View Javadoc
1   /*
2    * Copyright 2021 TiKV Project Authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  
18  package org.tikv.common.codec;
19  
20  import com.google.protobuf.ByteString;
21  import java.io.*;
22  import javax.annotation.Nonnull;
23  
24  public class CodecDataInput implements DataInput {
25    protected final DataInputStream inputStream;
26    protected final UnSyncByteArrayInputStream backingStream;
27    protected final byte[] backingBuffer;
28  
29    public CodecDataInput(ByteString data) {
30      this(data.toByteArray());
31    }
32  
33    public CodecDataInput(byte[] buf) {
34      backingBuffer = buf;
35      // MyDecimal usually will consume more bytes. If this happened,
36      // we need have a mechanism to reset backingStream.
37      // User mark first and then reset it later can do the trick.
38      backingStream =
39          new UnSyncByteArrayInputStream(buf) {
40            @Override
41            public void mark(int givenPos) {
42              mark = givenPos;
43            }
44          };
45      inputStream = new DataInputStream(backingStream);
46    }
47  
48    @Override
49    public void readFully(@Nonnull byte[] b) {
50      try {
51        inputStream.readFully(b);
52      } catch (Exception e) {
53        throw new RuntimeException(e);
54      }
55    }
56  
57    @Override
58    public void readFully(@Nonnull byte[] b, int off, int len) {
59      try {
60        inputStream.readFully(b, off, len);
61      } catch (Exception e) {
62        throw new RuntimeException(e);
63      }
64    }
65  
66    @Override
67    public int skipBytes(int n) {
68      try {
69        return inputStream.skipBytes(n);
70      } catch (Exception e) {
71        throw new RuntimeException(e);
72      }
73    }
74  
75    @Override
76    public boolean readBoolean() {
77      try {
78        return inputStream.readBoolean();
79      } catch (Exception e) {
80        throw new RuntimeException(e);
81      }
82    }
83  
84    @Override
85    public byte readByte() {
86      try {
87        return inputStream.readByte();
88      } catch (Exception e) {
89        throw new RuntimeException(e);
90      }
91    }
92  
93    @Override
94    public int readUnsignedByte() {
95      try {
96        return inputStream.readUnsignedByte();
97      } catch (Exception e) {
98        throw new RuntimeException(e);
99      }
100   }
101 
102   @Override
103   public short readShort() {
104     try {
105       return inputStream.readShort();
106     } catch (Exception e) {
107       throw new RuntimeException(e);
108     }
109   }
110 
111   @Override
112   public int readUnsignedShort() {
113     try {
114       return inputStream.readUnsignedShort();
115     } catch (Exception e) {
116       throw new RuntimeException(e);
117     }
118   }
119 
120   public int readPartialUnsignedShort() {
121     try {
122       byte[] readBuffer = new byte[2];
123       inputStream.read(readBuffer, 0, 2);
124       return ((readBuffer[0] & 0xff) << 8) + ((readBuffer[1] & 0xff) << 0);
125     } catch (IOException e) {
126       throw new RuntimeException(e);
127     }
128   }
129 
130   @Override
131   public char readChar() {
132     try {
133       return inputStream.readChar();
134     } catch (Exception e) {
135       throw new RuntimeException(e);
136     }
137   }
138 
139   @Override
140   public int readInt() {
141     try {
142       return inputStream.readInt();
143     } catch (Exception e) {
144       throw new RuntimeException(e);
145     }
146   }
147 
148   @Override
149   public long readLong() {
150     try {
151       return inputStream.readLong();
152     } catch (Exception e) {
153       throw new RuntimeException(e);
154     }
155   }
156 
157   @Override
158   public float readFloat() {
159     try {
160       return inputStream.readFloat();
161     } catch (Exception e) {
162       throw new RuntimeException(e);
163     }
164   }
165 
166   @Override
167   public double readDouble() {
168     try {
169       return inputStream.readDouble();
170     } catch (Exception e) {
171       throw new RuntimeException(e);
172     }
173   }
174 
175   @Override
176   public String readLine() {
177     try {
178       return inputStream.readLine();
179     } catch (Exception e) {
180       throw new RuntimeException(e);
181     }
182   }
183 
184   @Override
185   @Nonnull
186   public String readUTF() {
187     try {
188       return inputStream.readUTF();
189     } catch (Exception e) {
190       throw new RuntimeException(e);
191     }
192   }
193 
194   public int peekByte() {
195     mark(currentPos());
196     int b = readByte() & 0xFF;
197     reset();
198     return b;
199   }
200 
201   public int currentPos() {
202     return size() - available();
203   }
204 
205   public void mark(int givenPos) {
206     this.backingStream.mark(givenPos);
207   }
208 
209   public void reset() {
210     this.backingStream.reset();
211   }
212 
213   public boolean eof() {
214     return backingStream.available() == 0;
215   }
216 
217   public int size() {
218     return backingBuffer.length;
219   }
220 
221   public int available() {
222     return backingStream.available();
223   }
224 
225   public byte[] toByteArray() {
226     return backingBuffer;
227   }
228 
229   /**
230    * An copy of ByteArrayInputStream without synchronization for faster decode.
231    *
232    * @see ByteArrayInputStream
233    */
234   private static class UnSyncByteArrayInputStream extends InputStream {
235     protected byte[] buf;
236     protected int pos;
237     protected int mark = 0;
238     protected int count;
239 
240     UnSyncByteArrayInputStream(byte[] buf) {
241       this.buf = buf;
242       this.pos = 0;
243       this.count = buf.length;
244     }
245 
246     @Override
247     public int read() {
248       return (pos < count) ? (buf[pos++] & 0xff) : -1;
249     }
250 
251     @Override
252     public int read(byte[] b, int off, int len) {
253       if (b == null) {
254         throw new NullPointerException();
255       } else if (off < 0 || len < 0 || len > b.length - off) {
256         throw new IndexOutOfBoundsException();
257       }
258 
259       if (pos >= count) {
260         return -1;
261       }
262 
263       int avail = count - pos;
264       if (len > avail) {
265         len = avail;
266       }
267       if (len <= 0) {
268         return 0;
269       }
270       System.arraycopy(buf, pos, b, off, len);
271       pos += len;
272       return len;
273     }
274 
275     @Override
276     public long skip(long n) {
277       long k = count - pos;
278       if (n < k) {
279         k = n < 0 ? 0 : n;
280       }
281 
282       pos += k;
283       return k;
284     }
285 
286     @Override
287     public int available() {
288       return count - pos;
289     }
290 
291     @Override
292     public boolean markSupported() {
293       return true;
294     }
295 
296     @Override
297     public void mark(int readAheadLimit) {
298       mark = pos;
299     }
300 
301     @Override
302     public void reset() {
303       pos = mark;
304     }
305 
306     @Override
307     public void close() throws IOException {}
308   }
309 }