• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 package com.google.protobuf;
32 
33 import static com.google.protobuf.Internal.EMPTY_BYTE_ARRAY;
34 import static com.google.protobuf.Internal.EMPTY_BYTE_BUFFER;
35 import static com.google.protobuf.Internal.UTF_8;
36 import static com.google.protobuf.Internal.checkNotNull;
37 import static com.google.protobuf.WireFormat.FIXED32_SIZE;
38 import static com.google.protobuf.WireFormat.FIXED64_SIZE;
39 import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE;
40 
41 import java.io.ByteArrayOutputStream;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.nio.Buffer;
45 import java.nio.ByteBuffer;
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.Iterator;
49 import java.util.List;
50 
51 /**
52  * Reads and decodes protocol message fields.
53  *
54  * <p>This class contains two kinds of methods: methods that read specific protocol message
55  * constructs and field types (e.g. {@link #readTag()} and {@link #readInt32()}) and methods that
56  * read low-level values (e.g. {@link #readRawVarint32()} and {@link #readRawBytes}). If you are
57  * reading encoded protocol messages, you should use the former methods, but if you are reading some
58  * other format of your own design, use the latter.
59  *
60  * @author kenton@google.com Kenton Varda
61  */
62 public abstract class CodedInputStream {
63   private static final int DEFAULT_BUFFER_SIZE = 4096;
64   private static final int DEFAULT_RECURSION_LIMIT = 100;
65   // Integer.MAX_VALUE == 0x7FFFFFF == INT_MAX from limits.h
66   private static final int DEFAULT_SIZE_LIMIT = Integer.MAX_VALUE;
67 
68   /** Visible for subclasses. See setRecursionLimit() */
69   int recursionDepth;
70 
71   int recursionLimit = DEFAULT_RECURSION_LIMIT;
72 
73   /** Visible for subclasses. See setSizeLimit() */
74   int sizeLimit = DEFAULT_SIZE_LIMIT;
75 
76   /** Used to adapt to the experimental {@link Reader} interface. */
77   CodedInputStreamReader wrapper;
78 
79   /** Create a new CodedInputStream wrapping the given InputStream. */
newInstance(final InputStream input)80   public static CodedInputStream newInstance(final InputStream input) {
81     return newInstance(input, DEFAULT_BUFFER_SIZE);
82   }
83 
84   /** Create a new CodedInputStream wrapping the given InputStream, with a specified buffer size. */
newInstance(final InputStream input, int bufferSize)85   public static CodedInputStream newInstance(final InputStream input, int bufferSize) {
86     if (bufferSize <= 0) {
87       throw new IllegalArgumentException("bufferSize must be > 0");
88     }
89     if (input == null) {
90       // TODO(nathanmittler): Ideally we should throw here. This is done for backward compatibility.
91       return newInstance(EMPTY_BYTE_ARRAY);
92     }
93     return new StreamDecoder(input, bufferSize);
94   }
95 
96   /** Create a new CodedInputStream wrapping the given {@code Iterable <ByteBuffer>}. */
newInstance(final Iterable<ByteBuffer> input)97   public static CodedInputStream newInstance(final Iterable<ByteBuffer> input) {
98     if (!UnsafeDirectNioDecoder.isSupported()) {
99       return newInstance(new IterableByteBufferInputStream(input));
100     }
101     return newInstance(input, false);
102   }
103 
104   /** Create a new CodedInputStream wrapping the given {@code Iterable <ByteBuffer>}. */
newInstance( final Iterable<ByteBuffer> bufs, final boolean bufferIsImmutable)105   static CodedInputStream newInstance(
106       final Iterable<ByteBuffer> bufs, final boolean bufferIsImmutable) {
107     // flag is to check the type of input's ByteBuffers.
108     // flag equals 1: all ByteBuffers have array.
109     // flag equals 2: all ByteBuffers are direct ByteBuffers.
110     // flag equals 3: some ByteBuffers are direct and some have array.
111     // flag greater than 3: other cases.
112     int flag = 0;
113     // Total size of the input
114     int totalSize = 0;
115     for (ByteBuffer buf : bufs) {
116       totalSize += buf.remaining();
117       if (buf.hasArray()) {
118         flag |= 1;
119       } else if (buf.isDirect()) {
120         flag |= 2;
121       } else {
122         flag |= 4;
123       }
124     }
125     if (flag == 2) {
126       return new IterableDirectByteBufferDecoder(bufs, totalSize, bufferIsImmutable);
127     } else {
128       // TODO(yilunchong): add another decoders to deal case 1 and 3.
129       return newInstance(new IterableByteBufferInputStream(bufs));
130     }
131   }
132 
133   /** Create a new CodedInputStream wrapping the given byte array. */
newInstance(final byte[] buf)134   public static CodedInputStream newInstance(final byte[] buf) {
135     return newInstance(buf, 0, buf.length);
136   }
137 
138   /** Create a new CodedInputStream wrapping the given byte array slice. */
newInstance(final byte[] buf, final int off, final int len)139   public static CodedInputStream newInstance(final byte[] buf, final int off, final int len) {
140     return newInstance(buf, off, len, /* bufferIsImmutable= */ false);
141   }
142 
143   /** Create a new CodedInputStream wrapping the given byte array slice. */
newInstance( final byte[] buf, final int off, final int len, final boolean bufferIsImmutable)144   static CodedInputStream newInstance(
145       final byte[] buf, final int off, final int len, final boolean bufferIsImmutable) {
146     ArrayDecoder result = new ArrayDecoder(buf, off, len, bufferIsImmutable);
147     try {
148       // Some uses of CodedInputStream can be more efficient if they know
149       // exactly how many bytes are available.  By pushing the end point of the
150       // buffer as a limit, we allow them to get this information via
151       // getBytesUntilLimit().  Pushing a limit that we know is at the end of
152       // the stream can never hurt, since we can never past that point anyway.
153       result.pushLimit(len);
154     } catch (InvalidProtocolBufferException ex) {
155       // The only reason pushLimit() might throw an exception here is if len
156       // is negative. Normally pushLimit()'s parameter comes directly off the
157       // wire, so it's important to catch exceptions in case of corrupt or
158       // malicious data. However, in this case, we expect that len is not a
159       // user-supplied value, so we can assume that it being negative indicates
160       // a programming error. Therefore, throwing an unchecked exception is
161       // appropriate.
162       throw new IllegalArgumentException(ex);
163     }
164     return result;
165   }
166 
167   /**
168    * Create a new CodedInputStream wrapping the given ByteBuffer. The data starting from the
169    * ByteBuffer's current position to its limit will be read. The returned CodedInputStream may or
170    * may not share the underlying data in the ByteBuffer, therefore the ByteBuffer cannot be changed
171    * while the CodedInputStream is in use. Note that the ByteBuffer's position won't be changed by
172    * this function. Concurrent calls with the same ByteBuffer object are safe if no other thread is
173    * trying to alter the ByteBuffer's status.
174    */
newInstance(ByteBuffer buf)175   public static CodedInputStream newInstance(ByteBuffer buf) {
176     return newInstance(buf, /* bufferIsImmutable= */ false);
177   }
178 
179   /** Create a new CodedInputStream wrapping the given buffer. */
newInstance(ByteBuffer buf, boolean bufferIsImmutable)180   static CodedInputStream newInstance(ByteBuffer buf, boolean bufferIsImmutable) {
181     if (buf.hasArray()) {
182       return newInstance(
183           buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), bufferIsImmutable);
184     }
185 
186     if (buf.isDirect() && UnsafeDirectNioDecoder.isSupported()) {
187       return new UnsafeDirectNioDecoder(buf, bufferIsImmutable);
188     }
189 
190     // The buffer is non-direct and does not expose the underlying array. Using the ByteBuffer API
191     // to access individual bytes is very slow, so just copy the buffer to an array.
192     // TODO(nathanmittler): Re-evaluate with Java 9
193     byte[] buffer = new byte[buf.remaining()];
194     buf.duplicate().get(buffer);
195     return newInstance(buffer, 0, buffer.length, true);
196   }
197 
198   /** Disable construction/inheritance outside of this class. */
CodedInputStream()199   private CodedInputStream() {}
200 
201   // -----------------------------------------------------------------
202 
203   /**
204    * Attempt to read a field tag, returning zero if we have reached EOF. Protocol message parsers
205    * use this to read tags, since a protocol message may legally end wherever a tag occurs, and zero
206    * is not a valid tag number.
207    */
readTag()208   public abstract int readTag() throws IOException;
209 
210   /**
211    * Verifies that the last call to readTag() returned the given tag value. This is used to verify
212    * that a nested group ended with the correct end tag.
213    *
214    * @throws InvalidProtocolBufferException {@code value} does not match the last tag.
215    */
checkLastTagWas(final int value)216   public abstract void checkLastTagWas(final int value) throws InvalidProtocolBufferException;
217 
getLastTag()218   public abstract int getLastTag();
219 
220   /**
221    * Reads and discards a single field, given its tag value.
222    *
223    * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped.
224    *     Otherwise, returns {@code true}.
225    */
skipField(final int tag)226   public abstract boolean skipField(final int tag) throws IOException;
227 
228   /**
229    * Reads a single field and writes it to output in wire format, given its tag value.
230    *
231    * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped.
232    *     Otherwise, returns {@code true}.
233    * @deprecated use {@code UnknownFieldSet} or {@code UnknownFieldSetLite} to skip to an output
234    *     stream.
235    */
236   @Deprecated
skipField(final int tag, final CodedOutputStream output)237   public abstract boolean skipField(final int tag, final CodedOutputStream output)
238       throws IOException;
239 
240   /**
241    * Reads and discards an entire message. This will read either until EOF or until an endgroup tag,
242    * whichever comes first.
243    */
skipMessage()244   public abstract void skipMessage() throws IOException;
245 
246   /**
247    * Reads an entire message and writes it to output in wire format. This will read either until EOF
248    * or until an endgroup tag, whichever comes first.
249    */
skipMessage(CodedOutputStream output)250   public abstract void skipMessage(CodedOutputStream output) throws IOException;
251 
252 
253   // -----------------------------------------------------------------
254 
255   /** Read a {@code double} field value from the stream. */
readDouble()256   public abstract double readDouble() throws IOException;
257 
258   /** Read a {@code float} field value from the stream. */
readFloat()259   public abstract float readFloat() throws IOException;
260 
261   /** Read a {@code uint64} field value from the stream. */
readUInt64()262   public abstract long readUInt64() throws IOException;
263 
264   /** Read an {@code int64} field value from the stream. */
readInt64()265   public abstract long readInt64() throws IOException;
266 
267   /** Read an {@code int32} field value from the stream. */
readInt32()268   public abstract int readInt32() throws IOException;
269 
270   /** Read a {@code fixed64} field value from the stream. */
readFixed64()271   public abstract long readFixed64() throws IOException;
272 
273   /** Read a {@code fixed32} field value from the stream. */
readFixed32()274   public abstract int readFixed32() throws IOException;
275 
276   /** Read a {@code bool} field value from the stream. */
readBool()277   public abstract boolean readBool() throws IOException;
278 
279   /**
280    * Read a {@code string} field value from the stream. If the stream contains malformed UTF-8,
281    * replace the offending bytes with the standard UTF-8 replacement character.
282    */
readString()283   public abstract String readString() throws IOException;
284 
285   /**
286    * Read a {@code string} field value from the stream. If the stream contains malformed UTF-8,
287    * throw exception {@link InvalidProtocolBufferException}.
288    */
readStringRequireUtf8()289   public abstract String readStringRequireUtf8() throws IOException;
290 
291   /** Read a {@code group} field value from the stream. */
readGroup( final int fieldNumber, final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)292   public abstract void readGroup(
293       final int fieldNumber,
294       final MessageLite.Builder builder,
295       final ExtensionRegistryLite extensionRegistry)
296       throws IOException;
297 
298 
299   /** Read a {@code group} field value from the stream. */
readGroup( final int fieldNumber, final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)300   public abstract <T extends MessageLite> T readGroup(
301       final int fieldNumber, final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)
302       throws IOException;
303 
304   /**
305    * Reads a {@code group} field value from the stream and merges it into the given {@link
306    * UnknownFieldSet}.
307    *
308    * @deprecated UnknownFieldSet.Builder now implements MessageLite.Builder, so you can just call
309    *     {@link #readGroup}.
310    */
311   @Deprecated
readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)312   public abstract void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
313       throws IOException;
314 
315   /** Read an embedded message field value from the stream. */
readMessage( final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)316   public abstract void readMessage(
317       final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
318       throws IOException;
319 
320 
321   /** Read an embedded message field value from the stream. */
readMessage( final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)322   public abstract <T extends MessageLite> T readMessage(
323       final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException;
324 
325   /** Read a {@code bytes} field value from the stream. */
readBytes()326   public abstract ByteString readBytes() throws IOException;
327 
328   /** Read a {@code bytes} field value from the stream. */
readByteArray()329   public abstract byte[] readByteArray() throws IOException;
330 
331   /** Read a {@code bytes} field value from the stream. */
readByteBuffer()332   public abstract ByteBuffer readByteBuffer() throws IOException;
333 
334   /** Read a {@code uint32} field value from the stream. */
readUInt32()335   public abstract int readUInt32() throws IOException;
336 
337   /**
338    * Read an enum field value from the stream. Caller is responsible for converting the numeric
339    * value to an actual enum.
340    */
readEnum()341   public abstract int readEnum() throws IOException;
342 
343   /** Read an {@code sfixed32} field value from the stream. */
readSFixed32()344   public abstract int readSFixed32() throws IOException;
345 
346   /** Read an {@code sfixed64} field value from the stream. */
readSFixed64()347   public abstract long readSFixed64() throws IOException;
348 
349   /** Read an {@code sint32} field value from the stream. */
readSInt32()350   public abstract int readSInt32() throws IOException;
351 
352   /** Read an {@code sint64} field value from the stream. */
readSInt64()353   public abstract long readSInt64() throws IOException;
354 
355   // =================================================================
356 
357   /** Read a raw Varint from the stream. If larger than 32 bits, discard the upper bits. */
readRawVarint32()358   public abstract int readRawVarint32() throws IOException;
359 
360   /** Read a raw Varint from the stream. */
readRawVarint64()361   public abstract long readRawVarint64() throws IOException;
362 
363   /** Variant of readRawVarint64 for when uncomfortably close to the limit. */
364   /* Visible for testing */
readRawVarint64SlowPath()365   abstract long readRawVarint64SlowPath() throws IOException;
366 
367   /** Read a 32-bit little-endian integer from the stream. */
readRawLittleEndian32()368   public abstract int readRawLittleEndian32() throws IOException;
369 
370   /** Read a 64-bit little-endian integer from the stream. */
readRawLittleEndian64()371   public abstract long readRawLittleEndian64() throws IOException;
372 
373   // -----------------------------------------------------------------
374 
375   /**
376    * Enables {@link ByteString} aliasing of the underlying buffer, trading off on buffer pinning for
377    * data copies. Only valid for buffer-backed streams.
378    */
enableAliasing(boolean enabled)379   public abstract void enableAliasing(boolean enabled);
380 
381   /**
382    * Set the maximum message recursion depth. In order to prevent malicious messages from causing
383    * stack overflows, {@code CodedInputStream} limits how deeply messages may be nested. The default
384    * limit is 100.
385    *
386    * @return the old limit.
387    */
setRecursionLimit(final int limit)388   public final int setRecursionLimit(final int limit) {
389     if (limit < 0) {
390       throw new IllegalArgumentException("Recursion limit cannot be negative: " + limit);
391     }
392     final int oldLimit = recursionLimit;
393     recursionLimit = limit;
394     return oldLimit;
395   }
396 
397   /**
398    * Only valid for {@link InputStream}-backed streams.
399    *
400    * <p>Set the maximum message size. In order to prevent malicious messages from exhausting memory
401    * or causing integer overflows, {@code CodedInputStream} limits how large a message may be. The
402    * default limit is {@code Integer.MAX_INT}. You should set this limit as small as you can without
403    * harming your app's functionality. Note that size limits only apply when reading from an {@code
404    * InputStream}, not when constructed around a raw byte array.
405    *
406    * <p>If you want to read several messages from a single CodedInputStream, you could call {@link
407    * #resetSizeCounter()} after each one to avoid hitting the size limit.
408    *
409    * @return the old limit.
410    */
setSizeLimit(final int limit)411   public final int setSizeLimit(final int limit) {
412     if (limit < 0) {
413       throw new IllegalArgumentException("Size limit cannot be negative: " + limit);
414     }
415     final int oldLimit = sizeLimit;
416     sizeLimit = limit;
417     return oldLimit;
418   }
419 
420   private boolean shouldDiscardUnknownFields = false;
421 
422   /**
423    * Sets this {@code CodedInputStream} to discard unknown fields. Only applies to full runtime
424    * messages; lite messages will always preserve unknowns.
425    *
426    * <p>Note calling this function alone will have NO immediate effect on the underlying input data.
427    * The unknown fields will be discarded during parsing. This affects both Proto2 and Proto3 full
428    * runtime.
429    */
discardUnknownFields()430   final void discardUnknownFields() {
431     shouldDiscardUnknownFields = true;
432   }
433 
434   /**
435    * Reverts the unknown fields preservation behavior for Proto2 and Proto3 full runtime to their
436    * default.
437    */
unsetDiscardUnknownFields()438   final void unsetDiscardUnknownFields() {
439     shouldDiscardUnknownFields = false;
440   }
441 
442   /**
443    * Whether unknown fields in this input stream should be discarded during parsing into full
444    * runtime messages.
445    */
shouldDiscardUnknownFields()446   final boolean shouldDiscardUnknownFields() {
447     return shouldDiscardUnknownFields;
448   }
449 
450   /**
451    * Resets the current size counter to zero (see {@link #setSizeLimit(int)}). Only valid for {@link
452    * InputStream}-backed streams.
453    */
resetSizeCounter()454   public abstract void resetSizeCounter();
455 
456   /**
457    * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This is called when
458    * descending into a length-delimited embedded message.
459    *
460    * <p>Note that {@code pushLimit()} does NOT affect how many bytes the {@code CodedInputStream}
461    * reads from an underlying {@code InputStream} when refreshing its buffer. If you need to prevent
462    * reading past a certain point in the underlying {@code InputStream} (e.g. because you expect it
463    * to contain more data after the end of the message which you need to handle differently) then
464    * you must place a wrapper around your {@code InputStream} which limits the amount of data that
465    * can be read from it.
466    *
467    * @return the old limit.
468    */
pushLimit(int byteLimit)469   public abstract int pushLimit(int byteLimit) throws InvalidProtocolBufferException;
470 
471   /**
472    * Discards the current limit, returning to the previous limit.
473    *
474    * @param oldLimit The old limit, as returned by {@code pushLimit}.
475    */
popLimit(final int oldLimit)476   public abstract void popLimit(final int oldLimit);
477 
478   /**
479    * Returns the number of bytes to be read before the current limit. If no limit is set, returns
480    * -1.
481    */
getBytesUntilLimit()482   public abstract int getBytesUntilLimit();
483 
484   /**
485    * Returns true if the stream has reached the end of the input. This is the case if either the end
486    * of the underlying input source has been reached or if the stream has reached a limit created
487    * using {@link #pushLimit(int)}. This function may get blocked when using StreamDecoder as it
488    * invokes {@link StreamDecoder#tryRefillBuffer(int)} in this function which will try to read
489    * bytes from input.
490    */
isAtEnd()491   public abstract boolean isAtEnd() throws IOException;
492 
493   /**
494    * The total bytes read up to the current position. Calling {@link #resetSizeCounter()} resets
495    * this value to zero.
496    */
getTotalBytesRead()497   public abstract int getTotalBytesRead();
498 
499   /**
500    * Read one byte from the input.
501    *
502    * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
503    */
readRawByte()504   public abstract byte readRawByte() throws IOException;
505 
506   /**
507    * Read a fixed size of bytes from the input.
508    *
509    * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
510    */
readRawBytes(final int size)511   public abstract byte[] readRawBytes(final int size) throws IOException;
512 
513   /**
514    * Reads and discards {@code size} bytes.
515    *
516    * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
517    */
skipRawBytes(final int size)518   public abstract void skipRawBytes(final int size) throws IOException;
519 
520   /**
521    * Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers into values that can be
522    * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
523    * to be varint encoded, thus always taking 10 bytes on the wire.)
524    *
525    * @param n An unsigned 32-bit integer, stored in a signed int because Java has no explicit
526    *     unsigned support.
527    * @return A signed 32-bit integer.
528    */
decodeZigZag32(final int n)529   public static int decodeZigZag32(final int n) {
530     return (n >>> 1) ^ -(n & 1);
531   }
532 
533   /**
534    * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into values that can be
535    * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
536    * to be varint encoded, thus always taking 10 bytes on the wire.)
537    *
538    * @param n An unsigned 64-bit integer, stored in a signed int because Java has no explicit
539    *     unsigned support.
540    * @return A signed 64-bit integer.
541    */
decodeZigZag64(final long n)542   public static long decodeZigZag64(final long n) {
543     return (n >>> 1) ^ -(n & 1);
544   }
545 
546   /**
547    * Like {@link #readRawVarint32(InputStream)}, but expects that the caller has already read one
548    * byte. This allows the caller to determine if EOF has been reached before attempting to read.
549    */
readRawVarint32(final int firstByte, final InputStream input)550   public static int readRawVarint32(final int firstByte, final InputStream input)
551       throws IOException {
552     if ((firstByte & 0x80) == 0) {
553       return firstByte;
554     }
555 
556     int result = firstByte & 0x7f;
557     int offset = 7;
558     for (; offset < 32; offset += 7) {
559       final int b = input.read();
560       if (b == -1) {
561         throw InvalidProtocolBufferException.truncatedMessage();
562       }
563       result |= (b & 0x7f) << offset;
564       if ((b & 0x80) == 0) {
565         return result;
566       }
567     }
568     // Keep reading up to 64 bits.
569     for (; offset < 64; offset += 7) {
570       final int b = input.read();
571       if (b == -1) {
572         throw InvalidProtocolBufferException.truncatedMessage();
573       }
574       if ((b & 0x80) == 0) {
575         return result;
576       }
577     }
578     throw InvalidProtocolBufferException.malformedVarint();
579   }
580 
581   /**
582    * Reads a varint from the input one byte at a time, so that it does not read any bytes after the
583    * end of the varint. If you simply wrapped the stream in a CodedInputStream and used {@link
584    * #readRawVarint32(InputStream)} then you would probably end up reading past the end of the
585    * varint since CodedInputStream buffers its input.
586    */
readRawVarint32(final InputStream input)587   static int readRawVarint32(final InputStream input) throws IOException {
588     final int firstByte = input.read();
589     if (firstByte == -1) {
590       throw InvalidProtocolBufferException.truncatedMessage();
591     }
592     return readRawVarint32(firstByte, input);
593   }
594 
595   /** A {@link CodedInputStream} implementation that uses a backing array as the input. */
596   private static final class ArrayDecoder extends CodedInputStream {
597     private final byte[] buffer;
598     private final boolean immutable;
599     private int limit;
600     private int bufferSizeAfterLimit;
601     private int pos;
602     private int startPos;
603     private int lastTag;
604     private boolean enableAliasing;
605 
606     /** The absolute position of the end of the current message. */
607     private int currentLimit = Integer.MAX_VALUE;
608 
ArrayDecoder(final byte[] buffer, final int offset, final int len, boolean immutable)609     private ArrayDecoder(final byte[] buffer, final int offset, final int len, boolean immutable) {
610       this.buffer = buffer;
611       limit = offset + len;
612       pos = offset;
613       startPos = pos;
614       this.immutable = immutable;
615     }
616 
617     @Override
readTag()618     public int readTag() throws IOException {
619       if (isAtEnd()) {
620         lastTag = 0;
621         return 0;
622       }
623 
624       lastTag = readRawVarint32();
625       if (WireFormat.getTagFieldNumber(lastTag) == 0) {
626         // If we actually read zero (or any tag number corresponding to field
627         // number zero), that's not a valid tag.
628         throw InvalidProtocolBufferException.invalidTag();
629       }
630       return lastTag;
631     }
632 
633     @Override
checkLastTagWas(final int value)634     public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
635       if (lastTag != value) {
636         throw InvalidProtocolBufferException.invalidEndTag();
637       }
638     }
639 
640     @Override
getLastTag()641     public int getLastTag() {
642       return lastTag;
643     }
644 
645     @Override
skipField(final int tag)646     public boolean skipField(final int tag) throws IOException {
647       switch (WireFormat.getTagWireType(tag)) {
648         case WireFormat.WIRETYPE_VARINT:
649           skipRawVarint();
650           return true;
651         case WireFormat.WIRETYPE_FIXED64:
652           skipRawBytes(FIXED64_SIZE);
653           return true;
654         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
655           skipRawBytes(readRawVarint32());
656           return true;
657         case WireFormat.WIRETYPE_START_GROUP:
658           skipMessage();
659           checkLastTagWas(
660               WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
661           return true;
662         case WireFormat.WIRETYPE_END_GROUP:
663           return false;
664         case WireFormat.WIRETYPE_FIXED32:
665           skipRawBytes(FIXED32_SIZE);
666           return true;
667         default:
668           throw InvalidProtocolBufferException.invalidWireType();
669       }
670     }
671 
672     @Override
skipField(final int tag, final CodedOutputStream output)673     public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
674       switch (WireFormat.getTagWireType(tag)) {
675         case WireFormat.WIRETYPE_VARINT:
676           {
677             long value = readInt64();
678             output.writeRawVarint32(tag);
679             output.writeUInt64NoTag(value);
680             return true;
681           }
682         case WireFormat.WIRETYPE_FIXED64:
683           {
684             long value = readRawLittleEndian64();
685             output.writeRawVarint32(tag);
686             output.writeFixed64NoTag(value);
687             return true;
688           }
689         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
690           {
691             ByteString value = readBytes();
692             output.writeRawVarint32(tag);
693             output.writeBytesNoTag(value);
694             return true;
695           }
696         case WireFormat.WIRETYPE_START_GROUP:
697           {
698             output.writeRawVarint32(tag);
699             skipMessage(output);
700             int endtag =
701                 WireFormat.makeTag(
702                     WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
703             checkLastTagWas(endtag);
704             output.writeRawVarint32(endtag);
705             return true;
706           }
707         case WireFormat.WIRETYPE_END_GROUP:
708           {
709             return false;
710           }
711         case WireFormat.WIRETYPE_FIXED32:
712           {
713             int value = readRawLittleEndian32();
714             output.writeRawVarint32(tag);
715             output.writeFixed32NoTag(value);
716             return true;
717           }
718         default:
719           throw InvalidProtocolBufferException.invalidWireType();
720       }
721     }
722 
723     @Override
skipMessage()724     public void skipMessage() throws IOException {
725       while (true) {
726         final int tag = readTag();
727         if (tag == 0 || !skipField(tag)) {
728           return;
729         }
730       }
731     }
732 
733     @Override
skipMessage(CodedOutputStream output)734     public void skipMessage(CodedOutputStream output) throws IOException {
735       while (true) {
736         final int tag = readTag();
737         if (tag == 0 || !skipField(tag, output)) {
738           return;
739         }
740       }
741     }
742 
743 
744     // -----------------------------------------------------------------
745 
746     @Override
readDouble()747     public double readDouble() throws IOException {
748       return Double.longBitsToDouble(readRawLittleEndian64());
749     }
750 
751     @Override
readFloat()752     public float readFloat() throws IOException {
753       return Float.intBitsToFloat(readRawLittleEndian32());
754     }
755 
756     @Override
readUInt64()757     public long readUInt64() throws IOException {
758       return readRawVarint64();
759     }
760 
761     @Override
readInt64()762     public long readInt64() throws IOException {
763       return readRawVarint64();
764     }
765 
766     @Override
readInt32()767     public int readInt32() throws IOException {
768       return readRawVarint32();
769     }
770 
771     @Override
readFixed64()772     public long readFixed64() throws IOException {
773       return readRawLittleEndian64();
774     }
775 
776     @Override
readFixed32()777     public int readFixed32() throws IOException {
778       return readRawLittleEndian32();
779     }
780 
781     @Override
readBool()782     public boolean readBool() throws IOException {
783       return readRawVarint64() != 0;
784     }
785 
786     @Override
readString()787     public String readString() throws IOException {
788       final int size = readRawVarint32();
789       if (size > 0 && size <= (limit - pos)) {
790         // Fast path:  We already have the bytes in a contiguous buffer, so
791         //   just copy directly from it.
792         final String result = new String(buffer, pos, size, UTF_8);
793         pos += size;
794         return result;
795       }
796 
797       if (size == 0) {
798         return "";
799       }
800       if (size < 0) {
801         throw InvalidProtocolBufferException.negativeSize();
802       }
803       throw InvalidProtocolBufferException.truncatedMessage();
804     }
805 
806     @Override
readStringRequireUtf8()807     public String readStringRequireUtf8() throws IOException {
808       final int size = readRawVarint32();
809       if (size > 0 && size <= (limit - pos)) {
810         String result = Utf8.decodeUtf8(buffer, pos, size);
811         pos += size;
812         return result;
813       }
814 
815       if (size == 0) {
816         return "";
817       }
818       if (size <= 0) {
819         throw InvalidProtocolBufferException.negativeSize();
820       }
821       throw InvalidProtocolBufferException.truncatedMessage();
822     }
823 
824     @Override
readGroup( final int fieldNumber, final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)825     public void readGroup(
826         final int fieldNumber,
827         final MessageLite.Builder builder,
828         final ExtensionRegistryLite extensionRegistry)
829         throws IOException {
830       if (recursionDepth >= recursionLimit) {
831         throw InvalidProtocolBufferException.recursionLimitExceeded();
832       }
833       ++recursionDepth;
834       builder.mergeFrom(this, extensionRegistry);
835       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
836       --recursionDepth;
837     }
838 
839 
840     @Override
readGroup( final int fieldNumber, final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)841     public <T extends MessageLite> T readGroup(
842         final int fieldNumber,
843         final Parser<T> parser,
844         final ExtensionRegistryLite extensionRegistry)
845         throws IOException {
846       if (recursionDepth >= recursionLimit) {
847         throw InvalidProtocolBufferException.recursionLimitExceeded();
848       }
849       ++recursionDepth;
850       T result = parser.parsePartialFrom(this, extensionRegistry);
851       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
852       --recursionDepth;
853       return result;
854     }
855 
856     @Deprecated
857     @Override
readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)858     public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
859         throws IOException {
860       readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
861     }
862 
863     @Override
readMessage( final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)864     public void readMessage(
865         final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
866         throws IOException {
867       final int length = readRawVarint32();
868       if (recursionDepth >= recursionLimit) {
869         throw InvalidProtocolBufferException.recursionLimitExceeded();
870       }
871       final int oldLimit = pushLimit(length);
872       ++recursionDepth;
873       builder.mergeFrom(this, extensionRegistry);
874       checkLastTagWas(0);
875       --recursionDepth;
876       popLimit(oldLimit);
877     }
878 
879 
880     @Override
readMessage( final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)881     public <T extends MessageLite> T readMessage(
882         final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
883       int length = readRawVarint32();
884       if (recursionDepth >= recursionLimit) {
885         throw InvalidProtocolBufferException.recursionLimitExceeded();
886       }
887       final int oldLimit = pushLimit(length);
888       ++recursionDepth;
889       T result = parser.parsePartialFrom(this, extensionRegistry);
890       checkLastTagWas(0);
891       --recursionDepth;
892       popLimit(oldLimit);
893       return result;
894     }
895 
896     @Override
readBytes()897     public ByteString readBytes() throws IOException {
898       final int size = readRawVarint32();
899       if (size > 0 && size <= (limit - pos)) {
900         // Fast path:  We already have the bytes in a contiguous buffer, so
901         //   just copy directly from it.
902         final ByteString result =
903             immutable && enableAliasing
904                 ? ByteString.wrap(buffer, pos, size)
905                 : ByteString.copyFrom(buffer, pos, size);
906         pos += size;
907         return result;
908       }
909       if (size == 0) {
910         return ByteString.EMPTY;
911       }
912       // Slow path:  Build a byte array first then copy it.
913       return ByteString.wrap(readRawBytes(size));
914     }
915 
916     @Override
readByteArray()917     public byte[] readByteArray() throws IOException {
918       final int size = readRawVarint32();
919       return readRawBytes(size);
920     }
921 
922     @Override
readByteBuffer()923     public ByteBuffer readByteBuffer() throws IOException {
924       final int size = readRawVarint32();
925       if (size > 0 && size <= (limit - pos)) {
926         // Fast path: We already have the bytes in a contiguous buffer.
927         // When aliasing is enabled, we can return a ByteBuffer pointing directly
928         // into the underlying byte array without copy if the CodedInputStream is
929         // constructed from a byte array. If aliasing is disabled or the input is
930         // from an InputStream or ByteString, we have to make a copy of the bytes.
931         ByteBuffer result =
932             !immutable && enableAliasing
933                 ? ByteBuffer.wrap(buffer, pos, size).slice()
934                 : ByteBuffer.wrap(Arrays.copyOfRange(buffer, pos, pos + size));
935         pos += size;
936         // TODO(nathanmittler): Investigate making the ByteBuffer be made read-only
937         return result;
938       }
939 
940       if (size == 0) {
941         return EMPTY_BYTE_BUFFER;
942       }
943       if (size < 0) {
944         throw InvalidProtocolBufferException.negativeSize();
945       }
946       throw InvalidProtocolBufferException.truncatedMessage();
947     }
948 
949     @Override
readUInt32()950     public int readUInt32() throws IOException {
951       return readRawVarint32();
952     }
953 
954     @Override
readEnum()955     public int readEnum() throws IOException {
956       return readRawVarint32();
957     }
958 
959     @Override
readSFixed32()960     public int readSFixed32() throws IOException {
961       return readRawLittleEndian32();
962     }
963 
964     @Override
readSFixed64()965     public long readSFixed64() throws IOException {
966       return readRawLittleEndian64();
967     }
968 
969     @Override
readSInt32()970     public int readSInt32() throws IOException {
971       return decodeZigZag32(readRawVarint32());
972     }
973 
974     @Override
readSInt64()975     public long readSInt64() throws IOException {
976       return decodeZigZag64(readRawVarint64());
977     }
978 
979     // =================================================================
980 
981     @Override
readRawVarint32()982     public int readRawVarint32() throws IOException {
983       // See implementation notes for readRawVarint64
984       fastpath:
985       {
986         int tempPos = pos;
987 
988         if (limit == tempPos) {
989           break fastpath;
990         }
991 
992         final byte[] buffer = this.buffer;
993         int x;
994         if ((x = buffer[tempPos++]) >= 0) {
995           pos = tempPos;
996           return x;
997         } else if (limit - tempPos < 9) {
998           break fastpath;
999         } else if ((x ^= (buffer[tempPos++] << 7)) < 0) {
1000           x ^= (~0 << 7);
1001         } else if ((x ^= (buffer[tempPos++] << 14)) >= 0) {
1002           x ^= (~0 << 7) ^ (~0 << 14);
1003         } else if ((x ^= (buffer[tempPos++] << 21)) < 0) {
1004           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
1005         } else {
1006           int y = buffer[tempPos++];
1007           x ^= y << 28;
1008           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
1009           if (y < 0
1010               && buffer[tempPos++] < 0
1011               && buffer[tempPos++] < 0
1012               && buffer[tempPos++] < 0
1013               && buffer[tempPos++] < 0
1014               && buffer[tempPos++] < 0) {
1015             break fastpath; // Will throw malformedVarint()
1016           }
1017         }
1018         pos = tempPos;
1019         return x;
1020       }
1021       return (int) readRawVarint64SlowPath();
1022     }
1023 
skipRawVarint()1024     private void skipRawVarint() throws IOException {
1025       if (limit - pos >= MAX_VARINT_SIZE) {
1026         skipRawVarintFastPath();
1027       } else {
1028         skipRawVarintSlowPath();
1029       }
1030     }
1031 
skipRawVarintFastPath()1032     private void skipRawVarintFastPath() throws IOException {
1033       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
1034         if (buffer[pos++] >= 0) {
1035           return;
1036         }
1037       }
1038       throw InvalidProtocolBufferException.malformedVarint();
1039     }
1040 
skipRawVarintSlowPath()1041     private void skipRawVarintSlowPath() throws IOException {
1042       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
1043         if (readRawByte() >= 0) {
1044           return;
1045         }
1046       }
1047       throw InvalidProtocolBufferException.malformedVarint();
1048     }
1049 
1050     @Override
readRawVarint64()1051     public long readRawVarint64() throws IOException {
1052       // Implementation notes:
1053       //
1054       // Optimized for one-byte values, expected to be common.
1055       // The particular code below was selected from various candidates
1056       // empirically, by winning VarintBenchmark.
1057       //
1058       // Sign extension of (signed) Java bytes is usually a nuisance, but
1059       // we exploit it here to more easily obtain the sign of bytes read.
1060       // Instead of cleaning up the sign extension bits by masking eagerly,
1061       // we delay until we find the final (positive) byte, when we clear all
1062       // accumulated bits with one xor.  We depend on javac to constant fold.
1063       fastpath:
1064       {
1065         int tempPos = pos;
1066 
1067         if (limit == tempPos) {
1068           break fastpath;
1069         }
1070 
1071         final byte[] buffer = this.buffer;
1072         long x;
1073         int y;
1074         if ((y = buffer[tempPos++]) >= 0) {
1075           pos = tempPos;
1076           return y;
1077         } else if (limit - tempPos < 9) {
1078           break fastpath;
1079         } else if ((y ^= (buffer[tempPos++] << 7)) < 0) {
1080           x = y ^ (~0 << 7);
1081         } else if ((y ^= (buffer[tempPos++] << 14)) >= 0) {
1082           x = y ^ ((~0 << 7) ^ (~0 << 14));
1083         } else if ((y ^= (buffer[tempPos++] << 21)) < 0) {
1084           x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
1085         } else if ((x = y ^ ((long) buffer[tempPos++] << 28)) >= 0L) {
1086           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
1087         } else if ((x ^= ((long) buffer[tempPos++] << 35)) < 0L) {
1088           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
1089         } else if ((x ^= ((long) buffer[tempPos++] << 42)) >= 0L) {
1090           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
1091         } else if ((x ^= ((long) buffer[tempPos++] << 49)) < 0L) {
1092           x ^=
1093               (~0L << 7)
1094                   ^ (~0L << 14)
1095                   ^ (~0L << 21)
1096                   ^ (~0L << 28)
1097                   ^ (~0L << 35)
1098                   ^ (~0L << 42)
1099                   ^ (~0L << 49);
1100         } else {
1101           x ^= ((long) buffer[tempPos++] << 56);
1102           x ^=
1103               (~0L << 7)
1104                   ^ (~0L << 14)
1105                   ^ (~0L << 21)
1106                   ^ (~0L << 28)
1107                   ^ (~0L << 35)
1108                   ^ (~0L << 42)
1109                   ^ (~0L << 49)
1110                   ^ (~0L << 56);
1111           if (x < 0L) {
1112             if (buffer[tempPos++] < 0L) {
1113               break fastpath; // Will throw malformedVarint()
1114             }
1115           }
1116         }
1117         pos = tempPos;
1118         return x;
1119       }
1120       return readRawVarint64SlowPath();
1121     }
1122 
1123     @Override
readRawVarint64SlowPath()1124     long readRawVarint64SlowPath() throws IOException {
1125       long result = 0;
1126       for (int shift = 0; shift < 64; shift += 7) {
1127         final byte b = readRawByte();
1128         result |= (long) (b & 0x7F) << shift;
1129         if ((b & 0x80) == 0) {
1130           return result;
1131         }
1132       }
1133       throw InvalidProtocolBufferException.malformedVarint();
1134     }
1135 
1136     @Override
readRawLittleEndian32()1137     public int readRawLittleEndian32() throws IOException {
1138       int tempPos = pos;
1139 
1140       if (limit - tempPos < FIXED32_SIZE) {
1141         throw InvalidProtocolBufferException.truncatedMessage();
1142       }
1143 
1144       final byte[] buffer = this.buffer;
1145       pos = tempPos + FIXED32_SIZE;
1146       return (((buffer[tempPos] & 0xff))
1147           | ((buffer[tempPos + 1] & 0xff) << 8)
1148           | ((buffer[tempPos + 2] & 0xff) << 16)
1149           | ((buffer[tempPos + 3] & 0xff) << 24));
1150     }
1151 
1152     @Override
readRawLittleEndian64()1153     public long readRawLittleEndian64() throws IOException {
1154       int tempPos = pos;
1155 
1156       if (limit - tempPos < FIXED64_SIZE) {
1157         throw InvalidProtocolBufferException.truncatedMessage();
1158       }
1159 
1160       final byte[] buffer = this.buffer;
1161       pos = tempPos + FIXED64_SIZE;
1162       return (((buffer[tempPos] & 0xffL))
1163           | ((buffer[tempPos + 1] & 0xffL) << 8)
1164           | ((buffer[tempPos + 2] & 0xffL) << 16)
1165           | ((buffer[tempPos + 3] & 0xffL) << 24)
1166           | ((buffer[tempPos + 4] & 0xffL) << 32)
1167           | ((buffer[tempPos + 5] & 0xffL) << 40)
1168           | ((buffer[tempPos + 6] & 0xffL) << 48)
1169           | ((buffer[tempPos + 7] & 0xffL) << 56));
1170     }
1171 
1172     @Override
enableAliasing(boolean enabled)1173     public void enableAliasing(boolean enabled) {
1174       this.enableAliasing = enabled;
1175     }
1176 
1177     @Override
resetSizeCounter()1178     public void resetSizeCounter() {
1179       startPos = pos;
1180     }
1181 
1182     @Override
pushLimit(int byteLimit)1183     public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
1184       if (byteLimit < 0) {
1185         throw InvalidProtocolBufferException.negativeSize();
1186       }
1187       byteLimit += getTotalBytesRead();
1188       final int oldLimit = currentLimit;
1189       if (byteLimit > oldLimit) {
1190         throw InvalidProtocolBufferException.truncatedMessage();
1191       }
1192       currentLimit = byteLimit;
1193 
1194       recomputeBufferSizeAfterLimit();
1195 
1196       return oldLimit;
1197     }
1198 
recomputeBufferSizeAfterLimit()1199     private void recomputeBufferSizeAfterLimit() {
1200       limit += bufferSizeAfterLimit;
1201       final int bufferEnd = limit - startPos;
1202       if (bufferEnd > currentLimit) {
1203         // Limit is in current buffer.
1204         bufferSizeAfterLimit = bufferEnd - currentLimit;
1205         limit -= bufferSizeAfterLimit;
1206       } else {
1207         bufferSizeAfterLimit = 0;
1208       }
1209     }
1210 
1211     @Override
popLimit(final int oldLimit)1212     public void popLimit(final int oldLimit) {
1213       currentLimit = oldLimit;
1214       recomputeBufferSizeAfterLimit();
1215     }
1216 
1217     @Override
getBytesUntilLimit()1218     public int getBytesUntilLimit() {
1219       if (currentLimit == Integer.MAX_VALUE) {
1220         return -1;
1221       }
1222 
1223       return currentLimit - getTotalBytesRead();
1224     }
1225 
1226     @Override
isAtEnd()1227     public boolean isAtEnd() throws IOException {
1228       return pos == limit;
1229     }
1230 
1231     @Override
getTotalBytesRead()1232     public int getTotalBytesRead() {
1233       return pos - startPos;
1234     }
1235 
1236     @Override
readRawByte()1237     public byte readRawByte() throws IOException {
1238       if (pos == limit) {
1239         throw InvalidProtocolBufferException.truncatedMessage();
1240       }
1241       return buffer[pos++];
1242     }
1243 
1244     @Override
readRawBytes(final int length)1245     public byte[] readRawBytes(final int length) throws IOException {
1246       if (length > 0 && length <= (limit - pos)) {
1247         final int tempPos = pos;
1248         pos += length;
1249         return Arrays.copyOfRange(buffer, tempPos, pos);
1250       }
1251 
1252       if (length <= 0) {
1253         if (length == 0) {
1254           return Internal.EMPTY_BYTE_ARRAY;
1255         } else {
1256           throw InvalidProtocolBufferException.negativeSize();
1257         }
1258       }
1259       throw InvalidProtocolBufferException.truncatedMessage();
1260     }
1261 
1262     @Override
skipRawBytes(final int length)1263     public void skipRawBytes(final int length) throws IOException {
1264       if (length >= 0 && length <= (limit - pos)) {
1265         // We have all the bytes we need already.
1266         pos += length;
1267         return;
1268       }
1269 
1270       if (length < 0) {
1271         throw InvalidProtocolBufferException.negativeSize();
1272       }
1273       throw InvalidProtocolBufferException.truncatedMessage();
1274     }
1275   }
1276 
1277   /**
1278    * A {@link CodedInputStream} implementation that uses a backing direct ByteBuffer as the input.
1279    * Requires the use of {@code sun.misc.Unsafe} to perform fast reads on the buffer.
1280    */
1281   private static final class UnsafeDirectNioDecoder extends CodedInputStream {
1282     /** The direct buffer that is backing this stream. */
1283     private final ByteBuffer buffer;
1284 
1285     /**
1286      * If {@code true}, indicates that the buffer is backing a {@link ByteString} and is therefore
1287      * considered to be an immutable input source.
1288      */
1289     private final boolean immutable;
1290 
1291     /** The unsafe address of the content of {@link #buffer}. */
1292     private final long address;
1293 
1294     /** The unsafe address of the current read limit of the buffer. */
1295     private long limit;
1296 
1297     /** The unsafe address of the current read position of the buffer. */
1298     private long pos;
1299 
1300     /** The unsafe address of the starting read position. */
1301     private long startPos;
1302 
1303     /** The amount of available data in the buffer beyond {@link #limit}. */
1304     private int bufferSizeAfterLimit;
1305 
1306     /** The last tag that was read from this stream. */
1307     private int lastTag;
1308 
1309     /**
1310      * If {@code true}, indicates that calls to read {@link ByteString} or {@code byte[]}
1311      * <strong>may</strong> return slices of the underlying buffer, rather than copies.
1312      */
1313     private boolean enableAliasing;
1314 
1315     /** The absolute position of the end of the current message. */
1316     private int currentLimit = Integer.MAX_VALUE;
1317 
isSupported()1318     static boolean isSupported() {
1319       return UnsafeUtil.hasUnsafeByteBufferOperations();
1320     }
1321 
UnsafeDirectNioDecoder(ByteBuffer buffer, boolean immutable)1322     private UnsafeDirectNioDecoder(ByteBuffer buffer, boolean immutable) {
1323       this.buffer = buffer;
1324       address = UnsafeUtil.addressOffset(buffer);
1325       limit = address + buffer.limit();
1326       pos = address + buffer.position();
1327       startPos = pos;
1328       this.immutable = immutable;
1329     }
1330 
1331     @Override
readTag()1332     public int readTag() throws IOException {
1333       if (isAtEnd()) {
1334         lastTag = 0;
1335         return 0;
1336       }
1337 
1338       lastTag = readRawVarint32();
1339       if (WireFormat.getTagFieldNumber(lastTag) == 0) {
1340         // If we actually read zero (or any tag number corresponding to field
1341         // number zero), that's not a valid tag.
1342         throw InvalidProtocolBufferException.invalidTag();
1343       }
1344       return lastTag;
1345     }
1346 
1347     @Override
checkLastTagWas(final int value)1348     public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
1349       if (lastTag != value) {
1350         throw InvalidProtocolBufferException.invalidEndTag();
1351       }
1352     }
1353 
1354     @Override
getLastTag()1355     public int getLastTag() {
1356       return lastTag;
1357     }
1358 
1359     @Override
skipField(final int tag)1360     public boolean skipField(final int tag) throws IOException {
1361       switch (WireFormat.getTagWireType(tag)) {
1362         case WireFormat.WIRETYPE_VARINT:
1363           skipRawVarint();
1364           return true;
1365         case WireFormat.WIRETYPE_FIXED64:
1366           skipRawBytes(FIXED64_SIZE);
1367           return true;
1368         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
1369           skipRawBytes(readRawVarint32());
1370           return true;
1371         case WireFormat.WIRETYPE_START_GROUP:
1372           skipMessage();
1373           checkLastTagWas(
1374               WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
1375           return true;
1376         case WireFormat.WIRETYPE_END_GROUP:
1377           return false;
1378         case WireFormat.WIRETYPE_FIXED32:
1379           skipRawBytes(FIXED32_SIZE);
1380           return true;
1381         default:
1382           throw InvalidProtocolBufferException.invalidWireType();
1383       }
1384     }
1385 
1386     @Override
skipField(final int tag, final CodedOutputStream output)1387     public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
1388       switch (WireFormat.getTagWireType(tag)) {
1389         case WireFormat.WIRETYPE_VARINT:
1390           {
1391             long value = readInt64();
1392             output.writeRawVarint32(tag);
1393             output.writeUInt64NoTag(value);
1394             return true;
1395           }
1396         case WireFormat.WIRETYPE_FIXED64:
1397           {
1398             long value = readRawLittleEndian64();
1399             output.writeRawVarint32(tag);
1400             output.writeFixed64NoTag(value);
1401             return true;
1402           }
1403         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
1404           {
1405             ByteString value = readBytes();
1406             output.writeRawVarint32(tag);
1407             output.writeBytesNoTag(value);
1408             return true;
1409           }
1410         case WireFormat.WIRETYPE_START_GROUP:
1411           {
1412             output.writeRawVarint32(tag);
1413             skipMessage(output);
1414             int endtag =
1415                 WireFormat.makeTag(
1416                     WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
1417             checkLastTagWas(endtag);
1418             output.writeRawVarint32(endtag);
1419             return true;
1420           }
1421         case WireFormat.WIRETYPE_END_GROUP:
1422           {
1423             return false;
1424           }
1425         case WireFormat.WIRETYPE_FIXED32:
1426           {
1427             int value = readRawLittleEndian32();
1428             output.writeRawVarint32(tag);
1429             output.writeFixed32NoTag(value);
1430             return true;
1431           }
1432         default:
1433           throw InvalidProtocolBufferException.invalidWireType();
1434       }
1435     }
1436 
1437     @Override
skipMessage()1438     public void skipMessage() throws IOException {
1439       while (true) {
1440         final int tag = readTag();
1441         if (tag == 0 || !skipField(tag)) {
1442           return;
1443         }
1444       }
1445     }
1446 
1447     @Override
skipMessage(CodedOutputStream output)1448     public void skipMessage(CodedOutputStream output) throws IOException {
1449       while (true) {
1450         final int tag = readTag();
1451         if (tag == 0 || !skipField(tag, output)) {
1452           return;
1453         }
1454       }
1455     }
1456 
1457 
1458     // -----------------------------------------------------------------
1459 
1460     @Override
readDouble()1461     public double readDouble() throws IOException {
1462       return Double.longBitsToDouble(readRawLittleEndian64());
1463     }
1464 
1465     @Override
readFloat()1466     public float readFloat() throws IOException {
1467       return Float.intBitsToFloat(readRawLittleEndian32());
1468     }
1469 
1470     @Override
readUInt64()1471     public long readUInt64() throws IOException {
1472       return readRawVarint64();
1473     }
1474 
1475     @Override
readInt64()1476     public long readInt64() throws IOException {
1477       return readRawVarint64();
1478     }
1479 
1480     @Override
readInt32()1481     public int readInt32() throws IOException {
1482       return readRawVarint32();
1483     }
1484 
1485     @Override
readFixed64()1486     public long readFixed64() throws IOException {
1487       return readRawLittleEndian64();
1488     }
1489 
1490     @Override
readFixed32()1491     public int readFixed32() throws IOException {
1492       return readRawLittleEndian32();
1493     }
1494 
1495     @Override
readBool()1496     public boolean readBool() throws IOException {
1497       return readRawVarint64() != 0;
1498     }
1499 
1500     @Override
readString()1501     public String readString() throws IOException {
1502       final int size = readRawVarint32();
1503       if (size > 0 && size <= remaining()) {
1504         // TODO(nathanmittler): Is there a way to avoid this copy?
1505         // TODO(anuraaga): It might be possible to share the optimized loop with
1506         // readStringRequireUtf8 by implementing Java replacement logic there.
1507         // The same as readBytes' logic
1508         byte[] bytes = new byte[size];
1509         UnsafeUtil.copyMemory(pos, bytes, 0, size);
1510         String result = new String(bytes, UTF_8);
1511         pos += size;
1512         return result;
1513       }
1514 
1515       if (size == 0) {
1516         return "";
1517       }
1518       if (size < 0) {
1519         throw InvalidProtocolBufferException.negativeSize();
1520       }
1521       throw InvalidProtocolBufferException.truncatedMessage();
1522     }
1523 
1524     @Override
readStringRequireUtf8()1525     public String readStringRequireUtf8() throws IOException {
1526       final int size = readRawVarint32();
1527       if (size > 0 && size <= remaining()) {
1528         final int bufferPos = bufferPos(pos);
1529         String result = Utf8.decodeUtf8(buffer, bufferPos, size);
1530         pos += size;
1531         return result;
1532       }
1533 
1534       if (size == 0) {
1535         return "";
1536       }
1537       if (size <= 0) {
1538         throw InvalidProtocolBufferException.negativeSize();
1539       }
1540       throw InvalidProtocolBufferException.truncatedMessage();
1541     }
1542 
1543     @Override
readGroup( final int fieldNumber, final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)1544     public void readGroup(
1545         final int fieldNumber,
1546         final MessageLite.Builder builder,
1547         final ExtensionRegistryLite extensionRegistry)
1548         throws IOException {
1549       if (recursionDepth >= recursionLimit) {
1550         throw InvalidProtocolBufferException.recursionLimitExceeded();
1551       }
1552       ++recursionDepth;
1553       builder.mergeFrom(this, extensionRegistry);
1554       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
1555       --recursionDepth;
1556     }
1557 
1558 
1559     @Override
readGroup( final int fieldNumber, final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)1560     public <T extends MessageLite> T readGroup(
1561         final int fieldNumber,
1562         final Parser<T> parser,
1563         final ExtensionRegistryLite extensionRegistry)
1564         throws IOException {
1565       if (recursionDepth >= recursionLimit) {
1566         throw InvalidProtocolBufferException.recursionLimitExceeded();
1567       }
1568       ++recursionDepth;
1569       T result = parser.parsePartialFrom(this, extensionRegistry);
1570       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
1571       --recursionDepth;
1572       return result;
1573     }
1574 
1575     @Deprecated
1576     @Override
readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)1577     public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
1578         throws IOException {
1579       readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
1580     }
1581 
1582     @Override
readMessage( final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)1583     public void readMessage(
1584         final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
1585         throws IOException {
1586       final int length = readRawVarint32();
1587       if (recursionDepth >= recursionLimit) {
1588         throw InvalidProtocolBufferException.recursionLimitExceeded();
1589       }
1590       final int oldLimit = pushLimit(length);
1591       ++recursionDepth;
1592       builder.mergeFrom(this, extensionRegistry);
1593       checkLastTagWas(0);
1594       --recursionDepth;
1595       popLimit(oldLimit);
1596     }
1597 
1598 
1599     @Override
readMessage( final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)1600     public <T extends MessageLite> T readMessage(
1601         final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
1602       int length = readRawVarint32();
1603       if (recursionDepth >= recursionLimit) {
1604         throw InvalidProtocolBufferException.recursionLimitExceeded();
1605       }
1606       final int oldLimit = pushLimit(length);
1607       ++recursionDepth;
1608       T result = parser.parsePartialFrom(this, extensionRegistry);
1609       checkLastTagWas(0);
1610       --recursionDepth;
1611       popLimit(oldLimit);
1612       return result;
1613     }
1614 
1615     @Override
readBytes()1616     public ByteString readBytes() throws IOException {
1617       final int size = readRawVarint32();
1618       if (size > 0 && size <= remaining()) {
1619         if (immutable && enableAliasing) {
1620           final ByteBuffer result = slice(pos, pos + size);
1621           pos += size;
1622           return ByteString.wrap(result);
1623         } else {
1624           // Use UnsafeUtil to copy the memory to bytes instead of using ByteBuffer ways.
1625           byte[] bytes = new byte[size];
1626           UnsafeUtil.copyMemory(pos, bytes, 0, size);
1627           pos += size;
1628           return ByteString.wrap(bytes);
1629         }
1630       }
1631 
1632       if (size == 0) {
1633         return ByteString.EMPTY;
1634       }
1635       if (size < 0) {
1636         throw InvalidProtocolBufferException.negativeSize();
1637       }
1638       throw InvalidProtocolBufferException.truncatedMessage();
1639     }
1640 
1641     @Override
readByteArray()1642     public byte[] readByteArray() throws IOException {
1643       return readRawBytes(readRawVarint32());
1644     }
1645 
1646     @Override
readByteBuffer()1647     public ByteBuffer readByteBuffer() throws IOException {
1648       final int size = readRawVarint32();
1649       if (size > 0 && size <= remaining()) {
1650         // "Immutable" implies that buffer is backing a ByteString.
1651         // Disallow slicing in this case to prevent the caller from modifying the contents
1652         // of the ByteString.
1653         if (!immutable && enableAliasing) {
1654           final ByteBuffer result = slice(pos, pos + size);
1655           pos += size;
1656           return result;
1657         } else {
1658           // The same as readBytes' logic
1659           byte[] bytes = new byte[size];
1660           UnsafeUtil.copyMemory(pos, bytes, 0, size);
1661           pos += size;
1662           return ByteBuffer.wrap(bytes);
1663         }
1664         // TODO(nathanmittler): Investigate making the ByteBuffer be made read-only
1665       }
1666 
1667       if (size == 0) {
1668         return EMPTY_BYTE_BUFFER;
1669       }
1670       if (size < 0) {
1671         throw InvalidProtocolBufferException.negativeSize();
1672       }
1673       throw InvalidProtocolBufferException.truncatedMessage();
1674     }
1675 
1676     @Override
readUInt32()1677     public int readUInt32() throws IOException {
1678       return readRawVarint32();
1679     }
1680 
1681     @Override
readEnum()1682     public int readEnum() throws IOException {
1683       return readRawVarint32();
1684     }
1685 
1686     @Override
readSFixed32()1687     public int readSFixed32() throws IOException {
1688       return readRawLittleEndian32();
1689     }
1690 
1691     @Override
readSFixed64()1692     public long readSFixed64() throws IOException {
1693       return readRawLittleEndian64();
1694     }
1695 
1696     @Override
readSInt32()1697     public int readSInt32() throws IOException {
1698       return decodeZigZag32(readRawVarint32());
1699     }
1700 
1701     @Override
readSInt64()1702     public long readSInt64() throws IOException {
1703       return decodeZigZag64(readRawVarint64());
1704     }
1705 
1706     // =================================================================
1707 
1708     @Override
readRawVarint32()1709     public int readRawVarint32() throws IOException {
1710       // See implementation notes for readRawVarint64
1711       fastpath:
1712       {
1713         long tempPos = pos;
1714 
1715         if (limit == tempPos) {
1716           break fastpath;
1717         }
1718 
1719         int x;
1720         if ((x = UnsafeUtil.getByte(tempPos++)) >= 0) {
1721           pos = tempPos;
1722           return x;
1723         } else if (limit - tempPos < 9) {
1724           break fastpath;
1725         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
1726           x ^= (~0 << 7);
1727         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
1728           x ^= (~0 << 7) ^ (~0 << 14);
1729         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
1730           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
1731         } else {
1732           int y = UnsafeUtil.getByte(tempPos++);
1733           x ^= y << 28;
1734           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
1735           if (y < 0
1736               && UnsafeUtil.getByte(tempPos++) < 0
1737               && UnsafeUtil.getByte(tempPos++) < 0
1738               && UnsafeUtil.getByte(tempPos++) < 0
1739               && UnsafeUtil.getByte(tempPos++) < 0
1740               && UnsafeUtil.getByte(tempPos++) < 0) {
1741             break fastpath; // Will throw malformedVarint()
1742           }
1743         }
1744         pos = tempPos;
1745         return x;
1746       }
1747       return (int) readRawVarint64SlowPath();
1748     }
1749 
skipRawVarint()1750     private void skipRawVarint() throws IOException {
1751       if (remaining() >= MAX_VARINT_SIZE) {
1752         skipRawVarintFastPath();
1753       } else {
1754         skipRawVarintSlowPath();
1755       }
1756     }
1757 
skipRawVarintFastPath()1758     private void skipRawVarintFastPath() throws IOException {
1759       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
1760         if (UnsafeUtil.getByte(pos++) >= 0) {
1761           return;
1762         }
1763       }
1764       throw InvalidProtocolBufferException.malformedVarint();
1765     }
1766 
skipRawVarintSlowPath()1767     private void skipRawVarintSlowPath() throws IOException {
1768       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
1769         if (readRawByte() >= 0) {
1770           return;
1771         }
1772       }
1773       throw InvalidProtocolBufferException.malformedVarint();
1774     }
1775 
1776     @Override
readRawVarint64()1777     public long readRawVarint64() throws IOException {
1778       // Implementation notes:
1779       //
1780       // Optimized for one-byte values, expected to be common.
1781       // The particular code below was selected from various candidates
1782       // empirically, by winning VarintBenchmark.
1783       //
1784       // Sign extension of (signed) Java bytes is usually a nuisance, but
1785       // we exploit it here to more easily obtain the sign of bytes read.
1786       // Instead of cleaning up the sign extension bits by masking eagerly,
1787       // we delay until we find the final (positive) byte, when we clear all
1788       // accumulated bits with one xor.  We depend on javac to constant fold.
1789       fastpath:
1790       {
1791         long tempPos = pos;
1792 
1793         if (limit == tempPos) {
1794           break fastpath;
1795         }
1796 
1797         long x;
1798         int y;
1799         if ((y = UnsafeUtil.getByte(tempPos++)) >= 0) {
1800           pos = tempPos;
1801           return y;
1802         } else if (limit - tempPos < 9) {
1803           break fastpath;
1804         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
1805           x = y ^ (~0 << 7);
1806         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
1807           x = y ^ ((~0 << 7) ^ (~0 << 14));
1808         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
1809           x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
1810         } else if ((x = y ^ ((long) UnsafeUtil.getByte(tempPos++) << 28)) >= 0L) {
1811           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
1812         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 35)) < 0L) {
1813           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
1814         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 42)) >= 0L) {
1815           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
1816         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 49)) < 0L) {
1817           x ^=
1818               (~0L << 7)
1819                   ^ (~0L << 14)
1820                   ^ (~0L << 21)
1821                   ^ (~0L << 28)
1822                   ^ (~0L << 35)
1823                   ^ (~0L << 42)
1824                   ^ (~0L << 49);
1825         } else {
1826           x ^= ((long) UnsafeUtil.getByte(tempPos++) << 56);
1827           x ^=
1828               (~0L << 7)
1829                   ^ (~0L << 14)
1830                   ^ (~0L << 21)
1831                   ^ (~0L << 28)
1832                   ^ (~0L << 35)
1833                   ^ (~0L << 42)
1834                   ^ (~0L << 49)
1835                   ^ (~0L << 56);
1836           if (x < 0L) {
1837             if (UnsafeUtil.getByte(tempPos++) < 0L) {
1838               break fastpath; // Will throw malformedVarint()
1839             }
1840           }
1841         }
1842         pos = tempPos;
1843         return x;
1844       }
1845       return readRawVarint64SlowPath();
1846     }
1847 
1848     @Override
readRawVarint64SlowPath()1849     long readRawVarint64SlowPath() throws IOException {
1850       long result = 0;
1851       for (int shift = 0; shift < 64; shift += 7) {
1852         final byte b = readRawByte();
1853         result |= (long) (b & 0x7F) << shift;
1854         if ((b & 0x80) == 0) {
1855           return result;
1856         }
1857       }
1858       throw InvalidProtocolBufferException.malformedVarint();
1859     }
1860 
1861     @Override
readRawLittleEndian32()1862     public int readRawLittleEndian32() throws IOException {
1863       long tempPos = pos;
1864 
1865       if (limit - tempPos < FIXED32_SIZE) {
1866         throw InvalidProtocolBufferException.truncatedMessage();
1867       }
1868 
1869       pos = tempPos + FIXED32_SIZE;
1870       return (((UnsafeUtil.getByte(tempPos) & 0xff))
1871           | ((UnsafeUtil.getByte(tempPos + 1) & 0xff) << 8)
1872           | ((UnsafeUtil.getByte(tempPos + 2) & 0xff) << 16)
1873           | ((UnsafeUtil.getByte(tempPos + 3) & 0xff) << 24));
1874     }
1875 
1876     @Override
readRawLittleEndian64()1877     public long readRawLittleEndian64() throws IOException {
1878       long tempPos = pos;
1879 
1880       if (limit - tempPos < FIXED64_SIZE) {
1881         throw InvalidProtocolBufferException.truncatedMessage();
1882       }
1883 
1884       pos = tempPos + FIXED64_SIZE;
1885       return (((UnsafeUtil.getByte(tempPos) & 0xffL))
1886           | ((UnsafeUtil.getByte(tempPos + 1) & 0xffL) << 8)
1887           | ((UnsafeUtil.getByte(tempPos + 2) & 0xffL) << 16)
1888           | ((UnsafeUtil.getByte(tempPos + 3) & 0xffL) << 24)
1889           | ((UnsafeUtil.getByte(tempPos + 4) & 0xffL) << 32)
1890           | ((UnsafeUtil.getByte(tempPos + 5) & 0xffL) << 40)
1891           | ((UnsafeUtil.getByte(tempPos + 6) & 0xffL) << 48)
1892           | ((UnsafeUtil.getByte(tempPos + 7) & 0xffL) << 56));
1893     }
1894 
1895     @Override
enableAliasing(boolean enabled)1896     public void enableAliasing(boolean enabled) {
1897       this.enableAliasing = enabled;
1898     }
1899 
1900     @Override
resetSizeCounter()1901     public void resetSizeCounter() {
1902       startPos = pos;
1903     }
1904 
1905     @Override
pushLimit(int byteLimit)1906     public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
1907       if (byteLimit < 0) {
1908         throw InvalidProtocolBufferException.negativeSize();
1909       }
1910       byteLimit += getTotalBytesRead();
1911       final int oldLimit = currentLimit;
1912       if (byteLimit > oldLimit) {
1913         throw InvalidProtocolBufferException.truncatedMessage();
1914       }
1915       currentLimit = byteLimit;
1916 
1917       recomputeBufferSizeAfterLimit();
1918 
1919       return oldLimit;
1920     }
1921 
1922     @Override
popLimit(final int oldLimit)1923     public void popLimit(final int oldLimit) {
1924       currentLimit = oldLimit;
1925       recomputeBufferSizeAfterLimit();
1926     }
1927 
1928     @Override
getBytesUntilLimit()1929     public int getBytesUntilLimit() {
1930       if (currentLimit == Integer.MAX_VALUE) {
1931         return -1;
1932       }
1933 
1934       return currentLimit - getTotalBytesRead();
1935     }
1936 
1937     @Override
isAtEnd()1938     public boolean isAtEnd() throws IOException {
1939       return pos == limit;
1940     }
1941 
1942     @Override
getTotalBytesRead()1943     public int getTotalBytesRead() {
1944       return (int) (pos - startPos);
1945     }
1946 
1947     @Override
readRawByte()1948     public byte readRawByte() throws IOException {
1949       if (pos == limit) {
1950         throw InvalidProtocolBufferException.truncatedMessage();
1951       }
1952       return UnsafeUtil.getByte(pos++);
1953     }
1954 
1955     @Override
readRawBytes(final int length)1956     public byte[] readRawBytes(final int length) throws IOException {
1957       if (length >= 0 && length <= remaining()) {
1958         byte[] bytes = new byte[length];
1959         slice(pos, pos + length).get(bytes);
1960         pos += length;
1961         return bytes;
1962       }
1963 
1964       if (length <= 0) {
1965         if (length == 0) {
1966           return EMPTY_BYTE_ARRAY;
1967         } else {
1968           throw InvalidProtocolBufferException.negativeSize();
1969         }
1970       }
1971 
1972       throw InvalidProtocolBufferException.truncatedMessage();
1973     }
1974 
1975     @Override
skipRawBytes(final int length)1976     public void skipRawBytes(final int length) throws IOException {
1977       if (length >= 0 && length <= remaining()) {
1978         // We have all the bytes we need already.
1979         pos += length;
1980         return;
1981       }
1982 
1983       if (length < 0) {
1984         throw InvalidProtocolBufferException.negativeSize();
1985       }
1986       throw InvalidProtocolBufferException.truncatedMessage();
1987     }
1988 
recomputeBufferSizeAfterLimit()1989     private void recomputeBufferSizeAfterLimit() {
1990       limit += bufferSizeAfterLimit;
1991       final int bufferEnd = (int) (limit - startPos);
1992       if (bufferEnd > currentLimit) {
1993         // Limit is in current buffer.
1994         bufferSizeAfterLimit = bufferEnd - currentLimit;
1995         limit -= bufferSizeAfterLimit;
1996       } else {
1997         bufferSizeAfterLimit = 0;
1998       }
1999     }
2000 
remaining()2001     private int remaining() {
2002       return (int) (limit - pos);
2003     }
2004 
bufferPos(long pos)2005     private int bufferPos(long pos) {
2006       return (int) (pos - address);
2007     }
2008 
slice(long begin, long end)2009     private ByteBuffer slice(long begin, long end) throws IOException {
2010       int prevPos = buffer.position();
2011       int prevLimit = buffer.limit();
2012       try {
2013         ((Buffer) buffer).position(bufferPos(begin));
2014         ((Buffer) buffer).limit(bufferPos(end));
2015         return buffer.slice();
2016       } catch (IllegalArgumentException e) {
2017         throw InvalidProtocolBufferException.truncatedMessage();
2018       } finally {
2019         ((Buffer) buffer).position(prevPos);
2020         ((Buffer) buffer).limit(prevLimit);
2021       }
2022     }
2023   }
2024 
2025   /**
2026    * Implementation of {@link CodedInputStream} that uses an {@link InputStream} as the data source.
2027    */
2028   private static final class StreamDecoder extends CodedInputStream {
2029     private final InputStream input;
2030     private final byte[] buffer;
2031     /** bufferSize represents how many bytes are currently filled in the buffer */
2032     private int bufferSize;
2033 
2034     private int bufferSizeAfterLimit;
2035     private int pos;
2036     private int lastTag;
2037 
2038     /**
2039      * The total number of bytes read before the current buffer. The total bytes read up to the
2040      * current position can be computed as {@code totalBytesRetired + pos}. This value may be
2041      * negative if reading started in the middle of the current buffer (e.g. if the constructor that
2042      * takes a byte array and an offset was used).
2043      */
2044     private int totalBytesRetired;
2045 
2046     /** The absolute position of the end of the current message. */
2047     private int currentLimit = Integer.MAX_VALUE;
2048 
StreamDecoder(final InputStream input, int bufferSize)2049     private StreamDecoder(final InputStream input, int bufferSize) {
2050       checkNotNull(input, "input");
2051       this.input = input;
2052       this.buffer = new byte[bufferSize];
2053       this.bufferSize = 0;
2054       pos = 0;
2055       totalBytesRetired = 0;
2056     }
2057 
2058     @Override
readTag()2059     public int readTag() throws IOException {
2060       if (isAtEnd()) {
2061         lastTag = 0;
2062         return 0;
2063       }
2064 
2065       lastTag = readRawVarint32();
2066       if (WireFormat.getTagFieldNumber(lastTag) == 0) {
2067         // If we actually read zero (or any tag number corresponding to field
2068         // number zero), that's not a valid tag.
2069         throw InvalidProtocolBufferException.invalidTag();
2070       }
2071       return lastTag;
2072     }
2073 
2074     @Override
checkLastTagWas(final int value)2075     public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
2076       if (lastTag != value) {
2077         throw InvalidProtocolBufferException.invalidEndTag();
2078       }
2079     }
2080 
2081     @Override
getLastTag()2082     public int getLastTag() {
2083       return lastTag;
2084     }
2085 
2086     @Override
skipField(final int tag)2087     public boolean skipField(final int tag) throws IOException {
2088       switch (WireFormat.getTagWireType(tag)) {
2089         case WireFormat.WIRETYPE_VARINT:
2090           skipRawVarint();
2091           return true;
2092         case WireFormat.WIRETYPE_FIXED64:
2093           skipRawBytes(FIXED64_SIZE);
2094           return true;
2095         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
2096           skipRawBytes(readRawVarint32());
2097           return true;
2098         case WireFormat.WIRETYPE_START_GROUP:
2099           skipMessage();
2100           checkLastTagWas(
2101               WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
2102           return true;
2103         case WireFormat.WIRETYPE_END_GROUP:
2104           return false;
2105         case WireFormat.WIRETYPE_FIXED32:
2106           skipRawBytes(FIXED32_SIZE);
2107           return true;
2108         default:
2109           throw InvalidProtocolBufferException.invalidWireType();
2110       }
2111     }
2112 
2113     @Override
skipField(final int tag, final CodedOutputStream output)2114     public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
2115       switch (WireFormat.getTagWireType(tag)) {
2116         case WireFormat.WIRETYPE_VARINT:
2117           {
2118             long value = readInt64();
2119             output.writeRawVarint32(tag);
2120             output.writeUInt64NoTag(value);
2121             return true;
2122           }
2123         case WireFormat.WIRETYPE_FIXED64:
2124           {
2125             long value = readRawLittleEndian64();
2126             output.writeRawVarint32(tag);
2127             output.writeFixed64NoTag(value);
2128             return true;
2129           }
2130         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
2131           {
2132             ByteString value = readBytes();
2133             output.writeRawVarint32(tag);
2134             output.writeBytesNoTag(value);
2135             return true;
2136           }
2137         case WireFormat.WIRETYPE_START_GROUP:
2138           {
2139             output.writeRawVarint32(tag);
2140             skipMessage(output);
2141             int endtag =
2142                 WireFormat.makeTag(
2143                     WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
2144             checkLastTagWas(endtag);
2145             output.writeRawVarint32(endtag);
2146             return true;
2147           }
2148         case WireFormat.WIRETYPE_END_GROUP:
2149           {
2150             return false;
2151           }
2152         case WireFormat.WIRETYPE_FIXED32:
2153           {
2154             int value = readRawLittleEndian32();
2155             output.writeRawVarint32(tag);
2156             output.writeFixed32NoTag(value);
2157             return true;
2158           }
2159         default:
2160           throw InvalidProtocolBufferException.invalidWireType();
2161       }
2162     }
2163 
2164     @Override
skipMessage()2165     public void skipMessage() throws IOException {
2166       while (true) {
2167         final int tag = readTag();
2168         if (tag == 0 || !skipField(tag)) {
2169           return;
2170         }
2171       }
2172     }
2173 
2174     @Override
skipMessage(CodedOutputStream output)2175     public void skipMessage(CodedOutputStream output) throws IOException {
2176       while (true) {
2177         final int tag = readTag();
2178         if (tag == 0 || !skipField(tag, output)) {
2179           return;
2180         }
2181       }
2182     }
2183 
2184     /** Collects the bytes skipped and returns the data in a ByteBuffer. */
2185     private class SkippedDataSink implements RefillCallback {
2186       private int lastPos = pos;
2187       private ByteArrayOutputStream byteArrayStream;
2188 
2189       @Override
onRefill()2190       public void onRefill() {
2191         if (byteArrayStream == null) {
2192           byteArrayStream = new ByteArrayOutputStream();
2193         }
2194         byteArrayStream.write(buffer, lastPos, pos - lastPos);
2195         lastPos = 0;
2196       }
2197 
2198       /** Gets skipped data in a ByteBuffer. This method should only be called once. */
getSkippedData()2199       ByteBuffer getSkippedData() {
2200         if (byteArrayStream == null) {
2201           return ByteBuffer.wrap(buffer, lastPos, pos - lastPos);
2202         } else {
2203           byteArrayStream.write(buffer, lastPos, pos);
2204           return ByteBuffer.wrap(byteArrayStream.toByteArray());
2205         }
2206       }
2207     }
2208 
2209 
2210     // -----------------------------------------------------------------
2211 
2212     @Override
readDouble()2213     public double readDouble() throws IOException {
2214       return Double.longBitsToDouble(readRawLittleEndian64());
2215     }
2216 
2217     @Override
readFloat()2218     public float readFloat() throws IOException {
2219       return Float.intBitsToFloat(readRawLittleEndian32());
2220     }
2221 
2222     @Override
readUInt64()2223     public long readUInt64() throws IOException {
2224       return readRawVarint64();
2225     }
2226 
2227     @Override
readInt64()2228     public long readInt64() throws IOException {
2229       return readRawVarint64();
2230     }
2231 
2232     @Override
readInt32()2233     public int readInt32() throws IOException {
2234       return readRawVarint32();
2235     }
2236 
2237     @Override
readFixed64()2238     public long readFixed64() throws IOException {
2239       return readRawLittleEndian64();
2240     }
2241 
2242     @Override
readFixed32()2243     public int readFixed32() throws IOException {
2244       return readRawLittleEndian32();
2245     }
2246 
2247     @Override
readBool()2248     public boolean readBool() throws IOException {
2249       return readRawVarint64() != 0;
2250     }
2251 
2252     @Override
readString()2253     public String readString() throws IOException {
2254       final int size = readRawVarint32();
2255       if (size > 0 && size <= (bufferSize - pos)) {
2256         // Fast path:  We already have the bytes in a contiguous buffer, so
2257         //   just copy directly from it.
2258         final String result = new String(buffer, pos, size, UTF_8);
2259         pos += size;
2260         return result;
2261       }
2262       if (size == 0) {
2263         return "";
2264       }
2265       if (size <= bufferSize) {
2266         refillBuffer(size);
2267         String result = new String(buffer, pos, size, UTF_8);
2268         pos += size;
2269         return result;
2270       }
2271       // Slow path:  Build a byte array first then copy it.
2272       return new String(readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false), UTF_8);
2273     }
2274 
2275     @Override
readStringRequireUtf8()2276     public String readStringRequireUtf8() throws IOException {
2277       final int size = readRawVarint32();
2278       final byte[] bytes;
2279       final int oldPos = pos;
2280       final int tempPos;
2281       if (size <= (bufferSize - oldPos) && size > 0) {
2282         // Fast path:  We already have the bytes in a contiguous buffer, so
2283         //   just copy directly from it.
2284         bytes = buffer;
2285         pos = oldPos + size;
2286         tempPos = oldPos;
2287       } else if (size == 0) {
2288         return "";
2289       } else if (size <= bufferSize) {
2290         refillBuffer(size);
2291         bytes = buffer;
2292         tempPos = 0;
2293         pos = tempPos + size;
2294       } else {
2295         // Slow path:  Build a byte array first then copy it.
2296         bytes = readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
2297         tempPos = 0;
2298       }
2299       return Utf8.decodeUtf8(bytes, tempPos, size);
2300     }
2301 
2302     @Override
readGroup( final int fieldNumber, final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)2303     public void readGroup(
2304         final int fieldNumber,
2305         final MessageLite.Builder builder,
2306         final ExtensionRegistryLite extensionRegistry)
2307         throws IOException {
2308       if (recursionDepth >= recursionLimit) {
2309         throw InvalidProtocolBufferException.recursionLimitExceeded();
2310       }
2311       ++recursionDepth;
2312       builder.mergeFrom(this, extensionRegistry);
2313       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
2314       --recursionDepth;
2315     }
2316 
2317 
2318     @Override
readGroup( final int fieldNumber, final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)2319     public <T extends MessageLite> T readGroup(
2320         final int fieldNumber,
2321         final Parser<T> parser,
2322         final ExtensionRegistryLite extensionRegistry)
2323         throws IOException {
2324       if (recursionDepth >= recursionLimit) {
2325         throw InvalidProtocolBufferException.recursionLimitExceeded();
2326       }
2327       ++recursionDepth;
2328       T result = parser.parsePartialFrom(this, extensionRegistry);
2329       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
2330       --recursionDepth;
2331       return result;
2332     }
2333 
2334     @Deprecated
2335     @Override
readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)2336     public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
2337         throws IOException {
2338       readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
2339     }
2340 
2341     @Override
readMessage( final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)2342     public void readMessage(
2343         final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
2344         throws IOException {
2345       final int length = readRawVarint32();
2346       if (recursionDepth >= recursionLimit) {
2347         throw InvalidProtocolBufferException.recursionLimitExceeded();
2348       }
2349       final int oldLimit = pushLimit(length);
2350       ++recursionDepth;
2351       builder.mergeFrom(this, extensionRegistry);
2352       checkLastTagWas(0);
2353       --recursionDepth;
2354       popLimit(oldLimit);
2355     }
2356 
2357 
2358     @Override
readMessage( final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)2359     public <T extends MessageLite> T readMessage(
2360         final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
2361       int length = readRawVarint32();
2362       if (recursionDepth >= recursionLimit) {
2363         throw InvalidProtocolBufferException.recursionLimitExceeded();
2364       }
2365       final int oldLimit = pushLimit(length);
2366       ++recursionDepth;
2367       T result = parser.parsePartialFrom(this, extensionRegistry);
2368       checkLastTagWas(0);
2369       --recursionDepth;
2370       popLimit(oldLimit);
2371       return result;
2372     }
2373 
2374     @Override
readBytes()2375     public ByteString readBytes() throws IOException {
2376       final int size = readRawVarint32();
2377       if (size <= (bufferSize - pos) && size > 0) {
2378         // Fast path:  We already have the bytes in a contiguous buffer, so
2379         //   just copy directly from it.
2380         final ByteString result = ByteString.copyFrom(buffer, pos, size);
2381         pos += size;
2382         return result;
2383       }
2384       if (size == 0) {
2385         return ByteString.EMPTY;
2386       }
2387       return readBytesSlowPath(size);
2388     }
2389 
2390     @Override
readByteArray()2391     public byte[] readByteArray() throws IOException {
2392       final int size = readRawVarint32();
2393       if (size <= (bufferSize - pos) && size > 0) {
2394         // Fast path: We already have the bytes in a contiguous buffer, so
2395         // just copy directly from it.
2396         final byte[] result = Arrays.copyOfRange(buffer, pos, pos + size);
2397         pos += size;
2398         return result;
2399       } else {
2400         // Slow path: Build a byte array first then copy it.
2401         // TODO(dweis): Do we want to protect from malicious input streams here?
2402         return readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
2403       }
2404     }
2405 
2406     @Override
readByteBuffer()2407     public ByteBuffer readByteBuffer() throws IOException {
2408       final int size = readRawVarint32();
2409       if (size <= (bufferSize - pos) && size > 0) {
2410         // Fast path: We already have the bytes in a contiguous buffer.
2411         ByteBuffer result = ByteBuffer.wrap(Arrays.copyOfRange(buffer, pos, pos + size));
2412         pos += size;
2413         return result;
2414       }
2415       if (size == 0) {
2416         return Internal.EMPTY_BYTE_BUFFER;
2417       }
2418       // Slow path: Build a byte array first then copy it.
2419 
2420       // We must copy as the byte array was handed off to the InputStream and a malicious
2421       // implementation could retain a reference.
2422       return ByteBuffer.wrap(readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ true));
2423     }
2424 
2425     @Override
readUInt32()2426     public int readUInt32() throws IOException {
2427       return readRawVarint32();
2428     }
2429 
2430     @Override
readEnum()2431     public int readEnum() throws IOException {
2432       return readRawVarint32();
2433     }
2434 
2435     @Override
readSFixed32()2436     public int readSFixed32() throws IOException {
2437       return readRawLittleEndian32();
2438     }
2439 
2440     @Override
readSFixed64()2441     public long readSFixed64() throws IOException {
2442       return readRawLittleEndian64();
2443     }
2444 
2445     @Override
readSInt32()2446     public int readSInt32() throws IOException {
2447       return decodeZigZag32(readRawVarint32());
2448     }
2449 
2450     @Override
readSInt64()2451     public long readSInt64() throws IOException {
2452       return decodeZigZag64(readRawVarint64());
2453     }
2454 
2455     // =================================================================
2456 
2457     @Override
readRawVarint32()2458     public int readRawVarint32() throws IOException {
2459       // See implementation notes for readRawVarint64
2460       fastpath:
2461       {
2462         int tempPos = pos;
2463 
2464         if (bufferSize == tempPos) {
2465           break fastpath;
2466         }
2467 
2468         final byte[] buffer = this.buffer;
2469         int x;
2470         if ((x = buffer[tempPos++]) >= 0) {
2471           pos = tempPos;
2472           return x;
2473         } else if (bufferSize - tempPos < 9) {
2474           break fastpath;
2475         } else if ((x ^= (buffer[tempPos++] << 7)) < 0) {
2476           x ^= (~0 << 7);
2477         } else if ((x ^= (buffer[tempPos++] << 14)) >= 0) {
2478           x ^= (~0 << 7) ^ (~0 << 14);
2479         } else if ((x ^= (buffer[tempPos++] << 21)) < 0) {
2480           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
2481         } else {
2482           int y = buffer[tempPos++];
2483           x ^= y << 28;
2484           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
2485           if (y < 0
2486               && buffer[tempPos++] < 0
2487               && buffer[tempPos++] < 0
2488               && buffer[tempPos++] < 0
2489               && buffer[tempPos++] < 0
2490               && buffer[tempPos++] < 0) {
2491             break fastpath; // Will throw malformedVarint()
2492           }
2493         }
2494         pos = tempPos;
2495         return x;
2496       }
2497       return (int) readRawVarint64SlowPath();
2498     }
2499 
skipRawVarint()2500     private void skipRawVarint() throws IOException {
2501       if (bufferSize - pos >= MAX_VARINT_SIZE) {
2502         skipRawVarintFastPath();
2503       } else {
2504         skipRawVarintSlowPath();
2505       }
2506     }
2507 
skipRawVarintFastPath()2508     private void skipRawVarintFastPath() throws IOException {
2509       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
2510         if (buffer[pos++] >= 0) {
2511           return;
2512         }
2513       }
2514       throw InvalidProtocolBufferException.malformedVarint();
2515     }
2516 
skipRawVarintSlowPath()2517     private void skipRawVarintSlowPath() throws IOException {
2518       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
2519         if (readRawByte() >= 0) {
2520           return;
2521         }
2522       }
2523       throw InvalidProtocolBufferException.malformedVarint();
2524     }
2525 
2526     @Override
readRawVarint64()2527     public long readRawVarint64() throws IOException {
2528       // Implementation notes:
2529       //
2530       // Optimized for one-byte values, expected to be common.
2531       // The particular code below was selected from various candidates
2532       // empirically, by winning VarintBenchmark.
2533       //
2534       // Sign extension of (signed) Java bytes is usually a nuisance, but
2535       // we exploit it here to more easily obtain the sign of bytes read.
2536       // Instead of cleaning up the sign extension bits by masking eagerly,
2537       // we delay until we find the final (positive) byte, when we clear all
2538       // accumulated bits with one xor.  We depend on javac to constant fold.
2539       fastpath:
2540       {
2541         int tempPos = pos;
2542 
2543         if (bufferSize == tempPos) {
2544           break fastpath;
2545         }
2546 
2547         final byte[] buffer = this.buffer;
2548         long x;
2549         int y;
2550         if ((y = buffer[tempPos++]) >= 0) {
2551           pos = tempPos;
2552           return y;
2553         } else if (bufferSize - tempPos < 9) {
2554           break fastpath;
2555         } else if ((y ^= (buffer[tempPos++] << 7)) < 0) {
2556           x = y ^ (~0 << 7);
2557         } else if ((y ^= (buffer[tempPos++] << 14)) >= 0) {
2558           x = y ^ ((~0 << 7) ^ (~0 << 14));
2559         } else if ((y ^= (buffer[tempPos++] << 21)) < 0) {
2560           x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
2561         } else if ((x = y ^ ((long) buffer[tempPos++] << 28)) >= 0L) {
2562           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
2563         } else if ((x ^= ((long) buffer[tempPos++] << 35)) < 0L) {
2564           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
2565         } else if ((x ^= ((long) buffer[tempPos++] << 42)) >= 0L) {
2566           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
2567         } else if ((x ^= ((long) buffer[tempPos++] << 49)) < 0L) {
2568           x ^=
2569               (~0L << 7)
2570                   ^ (~0L << 14)
2571                   ^ (~0L << 21)
2572                   ^ (~0L << 28)
2573                   ^ (~0L << 35)
2574                   ^ (~0L << 42)
2575                   ^ (~0L << 49);
2576         } else {
2577           x ^= ((long) buffer[tempPos++] << 56);
2578           x ^=
2579               (~0L << 7)
2580                   ^ (~0L << 14)
2581                   ^ (~0L << 21)
2582                   ^ (~0L << 28)
2583                   ^ (~0L << 35)
2584                   ^ (~0L << 42)
2585                   ^ (~0L << 49)
2586                   ^ (~0L << 56);
2587           if (x < 0L) {
2588             if (buffer[tempPos++] < 0L) {
2589               break fastpath; // Will throw malformedVarint()
2590             }
2591           }
2592         }
2593         pos = tempPos;
2594         return x;
2595       }
2596       return readRawVarint64SlowPath();
2597     }
2598 
2599     @Override
readRawVarint64SlowPath()2600     long readRawVarint64SlowPath() throws IOException {
2601       long result = 0;
2602       for (int shift = 0; shift < 64; shift += 7) {
2603         final byte b = readRawByte();
2604         result |= (long) (b & 0x7F) << shift;
2605         if ((b & 0x80) == 0) {
2606           return result;
2607         }
2608       }
2609       throw InvalidProtocolBufferException.malformedVarint();
2610     }
2611 
2612     @Override
readRawLittleEndian32()2613     public int readRawLittleEndian32() throws IOException {
2614       int tempPos = pos;
2615 
2616       if (bufferSize - tempPos < FIXED32_SIZE) {
2617         refillBuffer(FIXED32_SIZE);
2618         tempPos = pos;
2619       }
2620 
2621       final byte[] buffer = this.buffer;
2622       pos = tempPos + FIXED32_SIZE;
2623       return (((buffer[tempPos] & 0xff))
2624           | ((buffer[tempPos + 1] & 0xff) << 8)
2625           | ((buffer[tempPos + 2] & 0xff) << 16)
2626           | ((buffer[tempPos + 3] & 0xff) << 24));
2627     }
2628 
2629     @Override
readRawLittleEndian64()2630     public long readRawLittleEndian64() throws IOException {
2631       int tempPos = pos;
2632 
2633       if (bufferSize - tempPos < FIXED64_SIZE) {
2634         refillBuffer(FIXED64_SIZE);
2635         tempPos = pos;
2636       }
2637 
2638       final byte[] buffer = this.buffer;
2639       pos = tempPos + FIXED64_SIZE;
2640       return (((buffer[tempPos] & 0xffL))
2641           | ((buffer[tempPos + 1] & 0xffL) << 8)
2642           | ((buffer[tempPos + 2] & 0xffL) << 16)
2643           | ((buffer[tempPos + 3] & 0xffL) << 24)
2644           | ((buffer[tempPos + 4] & 0xffL) << 32)
2645           | ((buffer[tempPos + 5] & 0xffL) << 40)
2646           | ((buffer[tempPos + 6] & 0xffL) << 48)
2647           | ((buffer[tempPos + 7] & 0xffL) << 56));
2648     }
2649 
2650     // -----------------------------------------------------------------
2651 
2652     @Override
enableAliasing(boolean enabled)2653     public void enableAliasing(boolean enabled) {
2654       // TODO(nathanmittler): Ideally we should throw here. Do nothing for backward compatibility.
2655     }
2656 
2657     @Override
resetSizeCounter()2658     public void resetSizeCounter() {
2659       totalBytesRetired = -pos;
2660     }
2661 
2662     @Override
pushLimit(int byteLimit)2663     public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
2664       if (byteLimit < 0) {
2665         throw InvalidProtocolBufferException.negativeSize();
2666       }
2667       byteLimit += totalBytesRetired + pos;
2668       final int oldLimit = currentLimit;
2669       if (byteLimit > oldLimit) {
2670         throw InvalidProtocolBufferException.truncatedMessage();
2671       }
2672       currentLimit = byteLimit;
2673 
2674       recomputeBufferSizeAfterLimit();
2675 
2676       return oldLimit;
2677     }
2678 
recomputeBufferSizeAfterLimit()2679     private void recomputeBufferSizeAfterLimit() {
2680       bufferSize += bufferSizeAfterLimit;
2681       final int bufferEnd = totalBytesRetired + bufferSize;
2682       if (bufferEnd > currentLimit) {
2683         // Limit is in current buffer.
2684         bufferSizeAfterLimit = bufferEnd - currentLimit;
2685         bufferSize -= bufferSizeAfterLimit;
2686       } else {
2687         bufferSizeAfterLimit = 0;
2688       }
2689     }
2690 
2691     @Override
popLimit(final int oldLimit)2692     public void popLimit(final int oldLimit) {
2693       currentLimit = oldLimit;
2694       recomputeBufferSizeAfterLimit();
2695     }
2696 
2697     @Override
getBytesUntilLimit()2698     public int getBytesUntilLimit() {
2699       if (currentLimit == Integer.MAX_VALUE) {
2700         return -1;
2701       }
2702 
2703       final int currentAbsolutePosition = totalBytesRetired + pos;
2704       return currentLimit - currentAbsolutePosition;
2705     }
2706 
2707     @Override
isAtEnd()2708     public boolean isAtEnd() throws IOException {
2709       return pos == bufferSize && !tryRefillBuffer(1);
2710     }
2711 
2712     @Override
getTotalBytesRead()2713     public int getTotalBytesRead() {
2714       return totalBytesRetired + pos;
2715     }
2716 
2717     private interface RefillCallback {
onRefill()2718       void onRefill();
2719     }
2720 
2721     private RefillCallback refillCallback = null;
2722 
2723     /**
2724      * Reads more bytes from the input, making at least {@code n} bytes available in the buffer.
2725      * Caller must ensure that the requested space is not yet available, and that the requested
2726      * space is less than BUFFER_SIZE.
2727      *
2728      * @throws InvalidProtocolBufferException The end of the stream or the current limit was
2729      *     reached.
2730      */
refillBuffer(int n)2731     private void refillBuffer(int n) throws IOException {
2732       if (!tryRefillBuffer(n)) {
2733         // We have to distinguish the exception between sizeLimitExceeded and truncatedMessage. So
2734         // we just throw an sizeLimitExceeded exception here if it exceeds the sizeLimit
2735         if (n > sizeLimit - totalBytesRetired - pos) {
2736           throw InvalidProtocolBufferException.sizeLimitExceeded();
2737         } else {
2738           throw InvalidProtocolBufferException.truncatedMessage();
2739         }
2740       }
2741     }
2742 
2743     /**
2744      * Tries to read more bytes from the input, making at least {@code n} bytes available in the
2745      * buffer. Caller must ensure that the requested space is not yet available, and that the
2746      * requested space is less than BUFFER_SIZE.
2747      *
2748      * @return {@code true} If the bytes could be made available; {@code false} 1. Current at the
2749      *     end of the stream 2. The current limit was reached 3. The total size limit was reached
2750      */
tryRefillBuffer(int n)2751     private boolean tryRefillBuffer(int n) throws IOException {
2752       if (pos + n <= bufferSize) {
2753         throw new IllegalStateException(
2754             "refillBuffer() called when " + n + " bytes were already available in buffer");
2755       }
2756 
2757       // Check whether the size of total message needs to read is bigger than the size limit.
2758       // We shouldn't throw an exception here as isAtEnd() function needs to get this function's
2759       // return as the result.
2760       if (n > sizeLimit - totalBytesRetired - pos) {
2761         return false;
2762       }
2763 
2764       // Shouldn't throw the exception here either.
2765       if (totalBytesRetired + pos + n > currentLimit) {
2766         // Oops, we hit a limit.
2767         return false;
2768       }
2769 
2770       if (refillCallback != null) {
2771         refillCallback.onRefill();
2772       }
2773 
2774       int tempPos = pos;
2775       if (tempPos > 0) {
2776         if (bufferSize > tempPos) {
2777           System.arraycopy(buffer, tempPos, buffer, 0, bufferSize - tempPos);
2778         }
2779         totalBytesRetired += tempPos;
2780         bufferSize -= tempPos;
2781         pos = 0;
2782       }
2783 
2784       // Here we should refill the buffer as many bytes as possible.
2785       int bytesRead =
2786           input.read(
2787               buffer,
2788               bufferSize,
2789               Math.min(
2790                   //  the size of allocated but unused bytes in the buffer
2791                   buffer.length - bufferSize,
2792                   //  do not exceed the total bytes limit
2793                   sizeLimit - totalBytesRetired - bufferSize));
2794       if (bytesRead == 0 || bytesRead < -1 || bytesRead > buffer.length) {
2795         throw new IllegalStateException(
2796             input.getClass()
2797                 + "#read(byte[]) returned invalid result: "
2798                 + bytesRead
2799                 + "\nThe InputStream implementation is buggy.");
2800       }
2801       if (bytesRead > 0) {
2802         bufferSize += bytesRead;
2803         recomputeBufferSizeAfterLimit();
2804         return (bufferSize >= n) ? true : tryRefillBuffer(n);
2805       }
2806 
2807       return false;
2808     }
2809 
2810     @Override
readRawByte()2811     public byte readRawByte() throws IOException {
2812       if (pos == bufferSize) {
2813         refillBuffer(1);
2814       }
2815       return buffer[pos++];
2816     }
2817 
2818     @Override
readRawBytes(final int size)2819     public byte[] readRawBytes(final int size) throws IOException {
2820       final int tempPos = pos;
2821       if (size <= (bufferSize - tempPos) && size > 0) {
2822         pos = tempPos + size;
2823         return Arrays.copyOfRange(buffer, tempPos, tempPos + size);
2824       } else {
2825         // TODO(dweis): Do we want to protect from malicious input streams here?
2826         return readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
2827       }
2828     }
2829 
2830     /**
2831      * Exactly like readRawBytes, but caller must have already checked the fast path: (size <=
2832      * (bufferSize - pos) && size > 0)
2833      *
2834      * If ensureNoLeakedReferences is true, the value is guaranteed to have not escaped to
2835      * untrusted code.
2836      */
readRawBytesSlowPath( final int size, boolean ensureNoLeakedReferences)2837     private byte[] readRawBytesSlowPath(
2838         final int size, boolean ensureNoLeakedReferences) throws IOException {
2839       // Attempt to read the data in one byte array when it's safe to do.
2840       byte[] result = readRawBytesSlowPathOneChunk(size);
2841       if (result != null) {
2842         return ensureNoLeakedReferences ? result.clone() : result;
2843       }
2844 
2845       final int originalBufferPos = pos;
2846       final int bufferedBytes = bufferSize - pos;
2847 
2848       // Mark the current buffer consumed.
2849       totalBytesRetired += bufferSize;
2850       pos = 0;
2851       bufferSize = 0;
2852 
2853       // Determine the number of bytes we need to read from the input stream.
2854       int sizeLeft = size - bufferedBytes;
2855 
2856       // The size is very large. For security reasons we read them in small
2857       // chunks.
2858       List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft);
2859 
2860       // OK, got everything.  Now concatenate it all into one buffer.
2861       final byte[] bytes = new byte[size];
2862 
2863       // Start by copying the leftover bytes from this.buffer.
2864       System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);
2865 
2866       // And now all the chunks.
2867       int tempPos = bufferedBytes;
2868       for (final byte[] chunk : chunks) {
2869         System.arraycopy(chunk, 0, bytes, tempPos, chunk.length);
2870         tempPos += chunk.length;
2871       }
2872 
2873       // Done.
2874       return bytes;
2875     }
2876 
2877     /**
2878      * Attempts to read the data in one byte array when it's safe to do. Returns null if the size to
2879      * read is too large and needs to be allocated in smaller chunks for security reasons.
2880      *
2881      * Returns a byte[] that may have escaped to user code via InputStream APIs.
2882      */
readRawBytesSlowPathOneChunk(final int size)2883     private byte[] readRawBytesSlowPathOneChunk(final int size) throws IOException {
2884       if (size == 0) {
2885         return Internal.EMPTY_BYTE_ARRAY;
2886       }
2887       if (size < 0) {
2888         throw InvalidProtocolBufferException.negativeSize();
2889       }
2890 
2891       // Integer-overflow-conscious check that the message size so far has not exceeded sizeLimit.
2892       int currentMessageSize = totalBytesRetired + pos + size;
2893       if (currentMessageSize - sizeLimit > 0) {
2894         throw InvalidProtocolBufferException.sizeLimitExceeded();
2895       }
2896 
2897       // Verify that the message size so far has not exceeded currentLimit.
2898       if (currentMessageSize > currentLimit) {
2899         // Read to the end of the stream anyway.
2900         skipRawBytes(currentLimit - totalBytesRetired - pos);
2901         throw InvalidProtocolBufferException.truncatedMessage();
2902       }
2903 
2904       final int bufferedBytes = bufferSize - pos;
2905       // Determine the number of bytes we need to read from the input stream.
2906       int sizeLeft = size - bufferedBytes;
2907       // TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
2908       if (sizeLeft < DEFAULT_BUFFER_SIZE || sizeLeft <= input.available()) {
2909         // Either the bytes we need are known to be available, or the required buffer is
2910         // within an allowed threshold - go ahead and allocate the buffer now.
2911         final byte[] bytes = new byte[size];
2912 
2913         // Copy all of the buffered bytes to the result buffer.
2914         System.arraycopy(buffer, pos, bytes, 0, bufferedBytes);
2915         totalBytesRetired += bufferSize;
2916         pos = 0;
2917         bufferSize = 0;
2918 
2919         // Fill the remaining bytes from the input stream.
2920         int tempPos = bufferedBytes;
2921         while (tempPos < bytes.length) {
2922           int n = input.read(bytes, tempPos, size - tempPos);
2923           if (n == -1) {
2924             throw InvalidProtocolBufferException.truncatedMessage();
2925           }
2926           totalBytesRetired += n;
2927           tempPos += n;
2928         }
2929 
2930         return bytes;
2931       }
2932 
2933       return null;
2934     }
2935 
2936     /**
2937      * Reads the remaining data in small chunks from the input stream.
2938      *
2939      * Returns a byte[] that may have escaped to user code via InputStream APIs.
2940      */
readRawBytesSlowPathRemainingChunks(int sizeLeft)2941     private List<byte[]> readRawBytesSlowPathRemainingChunks(int sizeLeft) throws IOException {
2942       // The size is very large.  For security reasons, we can't allocate the
2943       // entire byte array yet.  The size comes directly from the input, so a
2944       // maliciously-crafted message could provide a bogus very large size in
2945       // order to trick the app into allocating a lot of memory.  We avoid this
2946       // by allocating and reading only a small chunk at a time, so that the
2947       // malicious message must actually *be* extremely large to cause
2948       // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
2949       final List<byte[]> chunks = new ArrayList<byte[]>();
2950 
2951       while (sizeLeft > 0) {
2952         // TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
2953         final byte[] chunk = new byte[Math.min(sizeLeft, DEFAULT_BUFFER_SIZE)];
2954         int tempPos = 0;
2955         while (tempPos < chunk.length) {
2956           final int n = input.read(chunk, tempPos, chunk.length - tempPos);
2957           if (n == -1) {
2958             throw InvalidProtocolBufferException.truncatedMessage();
2959           }
2960           totalBytesRetired += n;
2961           tempPos += n;
2962         }
2963         sizeLeft -= chunk.length;
2964         chunks.add(chunk);
2965       }
2966 
2967       return chunks;
2968     }
2969 
2970     /**
2971      * Like readBytes, but caller must have already checked the fast path: (size <= (bufferSize -
2972      * pos) && size > 0 || size == 0)
2973      */
readBytesSlowPath(final int size)2974     private ByteString readBytesSlowPath(final int size) throws IOException {
2975       final byte[] result = readRawBytesSlowPathOneChunk(size);
2976       if (result != null) {
2977         // We must copy as the byte array was handed off to the InputStream and a malicious
2978         // implementation could retain a reference.
2979         return ByteString.copyFrom(result);
2980       }
2981 
2982       final int originalBufferPos = pos;
2983       final int bufferedBytes = bufferSize - pos;
2984 
2985       // Mark the current buffer consumed.
2986       totalBytesRetired += bufferSize;
2987       pos = 0;
2988       bufferSize = 0;
2989 
2990       // Determine the number of bytes we need to read from the input stream.
2991       int sizeLeft = size - bufferedBytes;
2992 
2993       // The size is very large. For security reasons we read them in small
2994       // chunks.
2995       List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft);
2996 
2997       // OK, got everything.  Now concatenate it all into one buffer.
2998       final byte[] bytes = new byte[size];
2999 
3000       // Start by copying the leftover bytes from this.buffer.
3001       System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);
3002 
3003       // And now all the chunks.
3004       int tempPos = bufferedBytes;
3005       for (final byte[] chunk : chunks) {
3006         System.arraycopy(chunk, 0, bytes, tempPos, chunk.length);
3007         tempPos += chunk.length;
3008       }
3009 
3010       return ByteString.wrap(bytes);
3011     }
3012 
3013     @Override
skipRawBytes(final int size)3014     public void skipRawBytes(final int size) throws IOException {
3015       if (size <= (bufferSize - pos) && size >= 0) {
3016         // We have all the bytes we need already.
3017         pos += size;
3018       } else {
3019         skipRawBytesSlowPath(size);
3020       }
3021     }
3022 
3023     /**
3024      * Exactly like skipRawBytes, but caller must have already checked the fast path: (size <=
3025      * (bufferSize - pos) && size >= 0)
3026      */
skipRawBytesSlowPath(final int size)3027     private void skipRawBytesSlowPath(final int size) throws IOException {
3028       if (size < 0) {
3029         throw InvalidProtocolBufferException.negativeSize();
3030       }
3031 
3032       if (totalBytesRetired + pos + size > currentLimit) {
3033         // Read to the end of the stream anyway.
3034         skipRawBytes(currentLimit - totalBytesRetired - pos);
3035         // Then fail.
3036         throw InvalidProtocolBufferException.truncatedMessage();
3037       }
3038 
3039       int totalSkipped = 0;
3040       if (refillCallback == null) {
3041         // Skipping more bytes than are in the buffer.  First skip what we have.
3042         totalBytesRetired += pos;
3043         totalSkipped = bufferSize - pos;
3044         bufferSize = 0;
3045         pos = 0;
3046 
3047         try {
3048           while (totalSkipped < size) {
3049             int toSkip = size - totalSkipped;
3050             long skipped = input.skip(toSkip);
3051             if (skipped < 0 || skipped > toSkip) {
3052               throw new IllegalStateException(
3053                   input.getClass()
3054                       + "#skip returned invalid result: "
3055                       + skipped
3056                       + "\nThe InputStream implementation is buggy.");
3057             } else if (skipped == 0) {
3058               // The API contract of skip() permits an inputstream to skip zero bytes for any reason
3059               // it wants. In particular, ByteArrayInputStream will just return zero over and over
3060               // when it's at the end of its input. In order to actually confirm that we've hit the
3061               // end of input, we need to issue a read call via the other path.
3062               break;
3063             }
3064             totalSkipped += (int) skipped;
3065           }
3066         } finally {
3067           totalBytesRetired += totalSkipped;
3068           recomputeBufferSizeAfterLimit();
3069         }
3070       }
3071       if (totalSkipped < size) {
3072         // Skipping more bytes than are in the buffer.  First skip what we have.
3073         int tempPos = bufferSize - pos;
3074         pos = bufferSize;
3075 
3076         // Keep refilling the buffer until we get to the point we wanted to skip to.
3077         // This has the side effect of ensuring the limits are updated correctly.
3078         refillBuffer(1);
3079         while (size - tempPos > bufferSize) {
3080           tempPos += bufferSize;
3081           pos = bufferSize;
3082           refillBuffer(1);
3083         }
3084 
3085         pos = size - tempPos;
3086       }
3087     }
3088   }
3089 
3090   /**
3091    * Implementation of {@link CodedInputStream} that uses an {@link Iterable <ByteBuffer>} as the
3092    * data source. Requires the use of {@code sun.misc.Unsafe} to perform fast reads on the buffer.
3093    */
3094   private static final class IterableDirectByteBufferDecoder extends CodedInputStream {
3095     /** The object that need to decode. */
3096     private Iterable<ByteBuffer> input;
3097     /** The {@link Iterator} with type {@link ByteBuffer} of {@code input} */
3098     private Iterator<ByteBuffer> iterator;
3099     /** The current ByteBuffer; */
3100     private ByteBuffer currentByteBuffer;
3101     /**
3102      * If {@code true}, indicates that all the buffer are backing a {@link ByteString} and are
3103      * therefore considered to be an immutable input source.
3104      */
3105     private boolean immutable;
3106     /**
3107      * If {@code true}, indicates that calls to read {@link ByteString} or {@code byte[]}
3108      * <strong>may</strong> return slices of the underlying buffer, rather than copies.
3109      */
3110     private boolean enableAliasing;
3111     /** The global total message length limit */
3112     private int totalBufferSize;
3113     /** The amount of available data in the input beyond {@link #currentLimit}. */
3114     private int bufferSizeAfterCurrentLimit;
3115     /** The absolute position of the end of the current message. */
3116     private int currentLimit = Integer.MAX_VALUE;
3117     /** The last tag that was read from this stream. */
3118     private int lastTag;
3119     /** Total Bytes have been Read from the {@link Iterable} {@link ByteBuffer} */
3120     private int totalBytesRead;
3121     /** The start position offset of the whole message, used as to reset the totalBytesRead */
3122     private int startOffset;
3123     /** The current position for current ByteBuffer */
3124     private long currentByteBufferPos;
3125 
3126     private long currentByteBufferStartPos;
3127     /**
3128      * If the current ByteBuffer is unsafe-direct based, currentAddress is the start address of this
3129      * ByteBuffer; otherwise should be zero.
3130      */
3131     private long currentAddress;
3132     /** The limit position for current ByteBuffer */
3133     private long currentByteBufferLimit;
3134 
3135     /**
3136      * The constructor of {@code Iterable<ByteBuffer>} decoder.
3137      *
3138      * @param inputBufs The input data.
3139      * @param size The total size of the input data.
3140      * @param immutableFlag whether the input data is immutable.
3141      */
IterableDirectByteBufferDecoder( Iterable<ByteBuffer> inputBufs, int size, boolean immutableFlag)3142     private IterableDirectByteBufferDecoder(
3143         Iterable<ByteBuffer> inputBufs, int size, boolean immutableFlag) {
3144       totalBufferSize = size;
3145       input = inputBufs;
3146       iterator = input.iterator();
3147       immutable = immutableFlag;
3148       startOffset = totalBytesRead = 0;
3149       if (size == 0) {
3150         currentByteBuffer = EMPTY_BYTE_BUFFER;
3151         currentByteBufferPos = 0;
3152         currentByteBufferStartPos = 0;
3153         currentByteBufferLimit = 0;
3154         currentAddress = 0;
3155       } else {
3156         tryGetNextByteBuffer();
3157       }
3158     }
3159 
3160     /** To get the next ByteBuffer from {@code input}, and then update the parameters */
getNextByteBuffer()3161     private void getNextByteBuffer() throws InvalidProtocolBufferException {
3162       if (!iterator.hasNext()) {
3163         throw InvalidProtocolBufferException.truncatedMessage();
3164       }
3165       tryGetNextByteBuffer();
3166     }
3167 
tryGetNextByteBuffer()3168     private void tryGetNextByteBuffer() {
3169       currentByteBuffer = iterator.next();
3170       totalBytesRead += (int) (currentByteBufferPos - currentByteBufferStartPos);
3171       currentByteBufferPos = currentByteBuffer.position();
3172       currentByteBufferStartPos = currentByteBufferPos;
3173       currentByteBufferLimit = currentByteBuffer.limit();
3174       currentAddress = UnsafeUtil.addressOffset(currentByteBuffer);
3175       currentByteBufferPos += currentAddress;
3176       currentByteBufferStartPos += currentAddress;
3177       currentByteBufferLimit += currentAddress;
3178     }
3179 
3180     @Override
readTag()3181     public int readTag() throws IOException {
3182       if (isAtEnd()) {
3183         lastTag = 0;
3184         return 0;
3185       }
3186 
3187       lastTag = readRawVarint32();
3188       if (WireFormat.getTagFieldNumber(lastTag) == 0) {
3189         // If we actually read zero (or any tag number corresponding to field
3190         // number zero), that's not a valid tag.
3191         throw InvalidProtocolBufferException.invalidTag();
3192       }
3193       return lastTag;
3194     }
3195 
3196     @Override
checkLastTagWas(final int value)3197     public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
3198       if (lastTag != value) {
3199         throw InvalidProtocolBufferException.invalidEndTag();
3200       }
3201     }
3202 
3203     @Override
getLastTag()3204     public int getLastTag() {
3205       return lastTag;
3206     }
3207 
3208     @Override
skipField(final int tag)3209     public boolean skipField(final int tag) throws IOException {
3210       switch (WireFormat.getTagWireType(tag)) {
3211         case WireFormat.WIRETYPE_VARINT:
3212           skipRawVarint();
3213           return true;
3214         case WireFormat.WIRETYPE_FIXED64:
3215           skipRawBytes(FIXED64_SIZE);
3216           return true;
3217         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
3218           skipRawBytes(readRawVarint32());
3219           return true;
3220         case WireFormat.WIRETYPE_START_GROUP:
3221           skipMessage();
3222           checkLastTagWas(
3223               WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
3224           return true;
3225         case WireFormat.WIRETYPE_END_GROUP:
3226           return false;
3227         case WireFormat.WIRETYPE_FIXED32:
3228           skipRawBytes(FIXED32_SIZE);
3229           return true;
3230         default:
3231           throw InvalidProtocolBufferException.invalidWireType();
3232       }
3233     }
3234 
3235     @Override
skipField(final int tag, final CodedOutputStream output)3236     public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
3237       switch (WireFormat.getTagWireType(tag)) {
3238         case WireFormat.WIRETYPE_VARINT:
3239           {
3240             long value = readInt64();
3241             output.writeRawVarint32(tag);
3242             output.writeUInt64NoTag(value);
3243             return true;
3244           }
3245         case WireFormat.WIRETYPE_FIXED64:
3246           {
3247             long value = readRawLittleEndian64();
3248             output.writeRawVarint32(tag);
3249             output.writeFixed64NoTag(value);
3250             return true;
3251           }
3252         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
3253           {
3254             ByteString value = readBytes();
3255             output.writeRawVarint32(tag);
3256             output.writeBytesNoTag(value);
3257             return true;
3258           }
3259         case WireFormat.WIRETYPE_START_GROUP:
3260           {
3261             output.writeRawVarint32(tag);
3262             skipMessage(output);
3263             int endtag =
3264                 WireFormat.makeTag(
3265                     WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
3266             checkLastTagWas(endtag);
3267             output.writeRawVarint32(endtag);
3268             return true;
3269           }
3270         case WireFormat.WIRETYPE_END_GROUP:
3271           {
3272             return false;
3273           }
3274         case WireFormat.WIRETYPE_FIXED32:
3275           {
3276             int value = readRawLittleEndian32();
3277             output.writeRawVarint32(tag);
3278             output.writeFixed32NoTag(value);
3279             return true;
3280           }
3281         default:
3282           throw InvalidProtocolBufferException.invalidWireType();
3283       }
3284     }
3285 
3286     @Override
skipMessage()3287     public void skipMessage() throws IOException {
3288       while (true) {
3289         final int tag = readTag();
3290         if (tag == 0 || !skipField(tag)) {
3291           return;
3292         }
3293       }
3294     }
3295 
3296     @Override
skipMessage(CodedOutputStream output)3297     public void skipMessage(CodedOutputStream output) throws IOException {
3298       while (true) {
3299         final int tag = readTag();
3300         if (tag == 0 || !skipField(tag, output)) {
3301           return;
3302         }
3303       }
3304     }
3305 
3306     // -----------------------------------------------------------------
3307 
3308     @Override
readDouble()3309     public double readDouble() throws IOException {
3310       return Double.longBitsToDouble(readRawLittleEndian64());
3311     }
3312 
3313     @Override
readFloat()3314     public float readFloat() throws IOException {
3315       return Float.intBitsToFloat(readRawLittleEndian32());
3316     }
3317 
3318     @Override
readUInt64()3319     public long readUInt64() throws IOException {
3320       return readRawVarint64();
3321     }
3322 
3323     @Override
readInt64()3324     public long readInt64() throws IOException {
3325       return readRawVarint64();
3326     }
3327 
3328     @Override
readInt32()3329     public int readInt32() throws IOException {
3330       return readRawVarint32();
3331     }
3332 
3333     @Override
readFixed64()3334     public long readFixed64() throws IOException {
3335       return readRawLittleEndian64();
3336     }
3337 
3338     @Override
readFixed32()3339     public int readFixed32() throws IOException {
3340       return readRawLittleEndian32();
3341     }
3342 
3343     @Override
readBool()3344     public boolean readBool() throws IOException {
3345       return readRawVarint64() != 0;
3346     }
3347 
3348     @Override
readString()3349     public String readString() throws IOException {
3350       final int size = readRawVarint32();
3351       if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
3352         byte[] bytes = new byte[size];
3353         UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
3354         String result = new String(bytes, UTF_8);
3355         currentByteBufferPos += size;
3356         return result;
3357       } else if (size > 0 && size <= remaining()) {
3358         // TODO(yilunchong): To use an underlying bytes[] instead of allocating a new bytes[]
3359         byte[] bytes = new byte[size];
3360         readRawBytesTo(bytes, 0, size);
3361         String result = new String(bytes, UTF_8);
3362         return result;
3363       }
3364 
3365       if (size == 0) {
3366         return "";
3367       }
3368       if (size < 0) {
3369         throw InvalidProtocolBufferException.negativeSize();
3370       }
3371       throw InvalidProtocolBufferException.truncatedMessage();
3372     }
3373 
3374     @Override
readStringRequireUtf8()3375     public String readStringRequireUtf8() throws IOException {
3376       final int size = readRawVarint32();
3377       if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
3378         final int bufferPos = (int) (currentByteBufferPos - currentByteBufferStartPos);
3379         String result = Utf8.decodeUtf8(currentByteBuffer, bufferPos, size);
3380         currentByteBufferPos += size;
3381         return result;
3382       }
3383       if (size >= 0 && size <= remaining()) {
3384         byte[] bytes = new byte[size];
3385         readRawBytesTo(bytes, 0, size);
3386         return Utf8.decodeUtf8(bytes, 0, size);
3387       }
3388 
3389       if (size == 0) {
3390         return "";
3391       }
3392       if (size <= 0) {
3393         throw InvalidProtocolBufferException.negativeSize();
3394       }
3395       throw InvalidProtocolBufferException.truncatedMessage();
3396     }
3397 
3398     @Override
readGroup( final int fieldNumber, final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)3399     public void readGroup(
3400         final int fieldNumber,
3401         final MessageLite.Builder builder,
3402         final ExtensionRegistryLite extensionRegistry)
3403         throws IOException {
3404       if (recursionDepth >= recursionLimit) {
3405         throw InvalidProtocolBufferException.recursionLimitExceeded();
3406       }
3407       ++recursionDepth;
3408       builder.mergeFrom(this, extensionRegistry);
3409       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
3410       --recursionDepth;
3411     }
3412 
3413 
3414     @Override
readGroup( final int fieldNumber, final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)3415     public <T extends MessageLite> T readGroup(
3416         final int fieldNumber,
3417         final Parser<T> parser,
3418         final ExtensionRegistryLite extensionRegistry)
3419         throws IOException {
3420       if (recursionDepth >= recursionLimit) {
3421         throw InvalidProtocolBufferException.recursionLimitExceeded();
3422       }
3423       ++recursionDepth;
3424       T result = parser.parsePartialFrom(this, extensionRegistry);
3425       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
3426       --recursionDepth;
3427       return result;
3428     }
3429 
3430     @Deprecated
3431     @Override
readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)3432     public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
3433         throws IOException {
3434       readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
3435     }
3436 
3437     @Override
readMessage( final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)3438     public void readMessage(
3439         final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
3440         throws IOException {
3441       final int length = readRawVarint32();
3442       if (recursionDepth >= recursionLimit) {
3443         throw InvalidProtocolBufferException.recursionLimitExceeded();
3444       }
3445       final int oldLimit = pushLimit(length);
3446       ++recursionDepth;
3447       builder.mergeFrom(this, extensionRegistry);
3448       checkLastTagWas(0);
3449       --recursionDepth;
3450       popLimit(oldLimit);
3451     }
3452 
3453 
3454     @Override
readMessage( final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)3455     public <T extends MessageLite> T readMessage(
3456         final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
3457       int length = readRawVarint32();
3458       if (recursionDepth >= recursionLimit) {
3459         throw InvalidProtocolBufferException.recursionLimitExceeded();
3460       }
3461       final int oldLimit = pushLimit(length);
3462       ++recursionDepth;
3463       T result = parser.parsePartialFrom(this, extensionRegistry);
3464       checkLastTagWas(0);
3465       --recursionDepth;
3466       popLimit(oldLimit);
3467       return result;
3468     }
3469 
3470     @Override
readBytes()3471     public ByteString readBytes() throws IOException {
3472       final int size = readRawVarint32();
3473       if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
3474         if (immutable && enableAliasing) {
3475           final int idx = (int) (currentByteBufferPos - currentAddress);
3476           final ByteString result = ByteString.wrap(slice(idx, idx + size));
3477           currentByteBufferPos += size;
3478           return result;
3479         } else {
3480           byte[] bytes;
3481           bytes = new byte[size];
3482           UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
3483           currentByteBufferPos += size;
3484           return ByteString.wrap(bytes);
3485         }
3486       } else if (size > 0 && size <= remaining()) {
3487         byte[] temp = new byte[size];
3488         readRawBytesTo(temp, 0, size);
3489         return ByteString.wrap(temp);
3490       }
3491 
3492       if (size == 0) {
3493         return ByteString.EMPTY;
3494       }
3495       if (size < 0) {
3496         throw InvalidProtocolBufferException.negativeSize();
3497       }
3498       throw InvalidProtocolBufferException.truncatedMessage();
3499     }
3500 
3501     @Override
readByteArray()3502     public byte[] readByteArray() throws IOException {
3503       return readRawBytes(readRawVarint32());
3504     }
3505 
3506     @Override
readByteBuffer()3507     public ByteBuffer readByteBuffer() throws IOException {
3508       final int size = readRawVarint32();
3509       if (size > 0 && size <= currentRemaining()) {
3510         if (!immutable && enableAliasing) {
3511           currentByteBufferPos += size;
3512           return slice(
3513               (int) (currentByteBufferPos - currentAddress - size),
3514               (int) (currentByteBufferPos - currentAddress));
3515         } else {
3516           byte[] bytes = new byte[size];
3517           UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
3518           currentByteBufferPos += size;
3519           return ByteBuffer.wrap(bytes);
3520         }
3521       } else if (size > 0 && size <= remaining()) {
3522         byte[] temp = new byte[size];
3523         readRawBytesTo(temp, 0, size);
3524         return ByteBuffer.wrap(temp);
3525       }
3526 
3527       if (size == 0) {
3528         return EMPTY_BYTE_BUFFER;
3529       }
3530       if (size < 0) {
3531         throw InvalidProtocolBufferException.negativeSize();
3532       }
3533       throw InvalidProtocolBufferException.truncatedMessage();
3534     }
3535 
3536     @Override
readUInt32()3537     public int readUInt32() throws IOException {
3538       return readRawVarint32();
3539     }
3540 
3541     @Override
readEnum()3542     public int readEnum() throws IOException {
3543       return readRawVarint32();
3544     }
3545 
3546     @Override
readSFixed32()3547     public int readSFixed32() throws IOException {
3548       return readRawLittleEndian32();
3549     }
3550 
3551     @Override
readSFixed64()3552     public long readSFixed64() throws IOException {
3553       return readRawLittleEndian64();
3554     }
3555 
3556     @Override
readSInt32()3557     public int readSInt32() throws IOException {
3558       return decodeZigZag32(readRawVarint32());
3559     }
3560 
3561     @Override
readSInt64()3562     public long readSInt64() throws IOException {
3563       return decodeZigZag64(readRawVarint64());
3564     }
3565 
3566     @Override
readRawVarint32()3567     public int readRawVarint32() throws IOException {
3568       fastpath:
3569       {
3570         long tempPos = currentByteBufferPos;
3571 
3572         if (currentByteBufferLimit == currentByteBufferPos) {
3573           break fastpath;
3574         }
3575 
3576         int x;
3577         if ((x = UnsafeUtil.getByte(tempPos++)) >= 0) {
3578           currentByteBufferPos++;
3579           return x;
3580         } else if (currentByteBufferLimit - currentByteBufferPos < 10) {
3581           break fastpath;
3582         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
3583           x ^= (~0 << 7);
3584         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
3585           x ^= (~0 << 7) ^ (~0 << 14);
3586         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
3587           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
3588         } else {
3589           int y = UnsafeUtil.getByte(tempPos++);
3590           x ^= y << 28;
3591           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
3592           if (y < 0
3593               && UnsafeUtil.getByte(tempPos++) < 0
3594               && UnsafeUtil.getByte(tempPos++) < 0
3595               && UnsafeUtil.getByte(tempPos++) < 0
3596               && UnsafeUtil.getByte(tempPos++) < 0
3597               && UnsafeUtil.getByte(tempPos++) < 0) {
3598             break fastpath; // Will throw malformedVarint()
3599           }
3600         }
3601         currentByteBufferPos = tempPos;
3602         return x;
3603       }
3604       return (int) readRawVarint64SlowPath();
3605     }
3606 
3607     @Override
readRawVarint64()3608     public long readRawVarint64() throws IOException {
3609       fastpath:
3610       {
3611         long tempPos = currentByteBufferPos;
3612 
3613         if (currentByteBufferLimit == currentByteBufferPos) {
3614           break fastpath;
3615         }
3616 
3617         long x;
3618         int y;
3619         if ((y = UnsafeUtil.getByte(tempPos++)) >= 0) {
3620           currentByteBufferPos++;
3621           return y;
3622         } else if (currentByteBufferLimit - currentByteBufferPos < 10) {
3623           break fastpath;
3624         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
3625           x = y ^ (~0 << 7);
3626         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
3627           x = y ^ ((~0 << 7) ^ (~0 << 14));
3628         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
3629           x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
3630         } else if ((x = y ^ ((long) UnsafeUtil.getByte(tempPos++) << 28)) >= 0L) {
3631           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
3632         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 35)) < 0L) {
3633           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
3634         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 42)) >= 0L) {
3635           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
3636         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 49)) < 0L) {
3637           x ^=
3638               (~0L << 7)
3639                   ^ (~0L << 14)
3640                   ^ (~0L << 21)
3641                   ^ (~0L << 28)
3642                   ^ (~0L << 35)
3643                   ^ (~0L << 42)
3644                   ^ (~0L << 49);
3645         } else {
3646           x ^= ((long) UnsafeUtil.getByte(tempPos++) << 56);
3647           x ^=
3648               (~0L << 7)
3649                   ^ (~0L << 14)
3650                   ^ (~0L << 21)
3651                   ^ (~0L << 28)
3652                   ^ (~0L << 35)
3653                   ^ (~0L << 42)
3654                   ^ (~0L << 49)
3655                   ^ (~0L << 56);
3656           if (x < 0L) {
3657             if (UnsafeUtil.getByte(tempPos++) < 0L) {
3658               break fastpath; // Will throw malformedVarint()
3659             }
3660           }
3661         }
3662         currentByteBufferPos = tempPos;
3663         return x;
3664       }
3665       return readRawVarint64SlowPath();
3666     }
3667 
3668     @Override
readRawVarint64SlowPath()3669     long readRawVarint64SlowPath() throws IOException {
3670       long result = 0;
3671       for (int shift = 0; shift < 64; shift += 7) {
3672         final byte b = readRawByte();
3673         result |= (long) (b & 0x7F) << shift;
3674         if ((b & 0x80) == 0) {
3675           return result;
3676         }
3677       }
3678       throw InvalidProtocolBufferException.malformedVarint();
3679     }
3680 
3681     @Override
readRawLittleEndian32()3682     public int readRawLittleEndian32() throws IOException {
3683       if (currentRemaining() >= FIXED32_SIZE) {
3684         long tempPos = currentByteBufferPos;
3685         currentByteBufferPos += FIXED32_SIZE;
3686         return (((UnsafeUtil.getByte(tempPos) & 0xff))
3687             | ((UnsafeUtil.getByte(tempPos + 1) & 0xff) << 8)
3688             | ((UnsafeUtil.getByte(tempPos + 2) & 0xff) << 16)
3689             | ((UnsafeUtil.getByte(tempPos + 3) & 0xff) << 24));
3690       }
3691       return ((readRawByte() & 0xff)
3692           | ((readRawByte() & 0xff) << 8)
3693           | ((readRawByte() & 0xff) << 16)
3694           | ((readRawByte() & 0xff) << 24));
3695     }
3696 
3697     @Override
readRawLittleEndian64()3698     public long readRawLittleEndian64() throws IOException {
3699       if (currentRemaining() >= FIXED64_SIZE) {
3700         long tempPos = currentByteBufferPos;
3701         currentByteBufferPos += FIXED64_SIZE;
3702         return (((UnsafeUtil.getByte(tempPos) & 0xffL))
3703             | ((UnsafeUtil.getByte(tempPos + 1) & 0xffL) << 8)
3704             | ((UnsafeUtil.getByte(tempPos + 2) & 0xffL) << 16)
3705             | ((UnsafeUtil.getByte(tempPos + 3) & 0xffL) << 24)
3706             | ((UnsafeUtil.getByte(tempPos + 4) & 0xffL) << 32)
3707             | ((UnsafeUtil.getByte(tempPos + 5) & 0xffL) << 40)
3708             | ((UnsafeUtil.getByte(tempPos + 6) & 0xffL) << 48)
3709             | ((UnsafeUtil.getByte(tempPos + 7) & 0xffL) << 56));
3710       }
3711       return ((readRawByte() & 0xffL)
3712           | ((readRawByte() & 0xffL) << 8)
3713           | ((readRawByte() & 0xffL) << 16)
3714           | ((readRawByte() & 0xffL) << 24)
3715           | ((readRawByte() & 0xffL) << 32)
3716           | ((readRawByte() & 0xffL) << 40)
3717           | ((readRawByte() & 0xffL) << 48)
3718           | ((readRawByte() & 0xffL) << 56));
3719     }
3720 
3721     @Override
enableAliasing(boolean enabled)3722     public void enableAliasing(boolean enabled) {
3723       this.enableAliasing = enabled;
3724     }
3725 
3726     @Override
resetSizeCounter()3727     public void resetSizeCounter() {
3728       startOffset = (int) (totalBytesRead + currentByteBufferPos - currentByteBufferStartPos);
3729     }
3730 
3731     @Override
pushLimit(int byteLimit)3732     public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
3733       if (byteLimit < 0) {
3734         throw InvalidProtocolBufferException.negativeSize();
3735       }
3736       byteLimit += getTotalBytesRead();
3737       final int oldLimit = currentLimit;
3738       if (byteLimit > oldLimit) {
3739         throw InvalidProtocolBufferException.truncatedMessage();
3740       }
3741       currentLimit = byteLimit;
3742 
3743       recomputeBufferSizeAfterLimit();
3744 
3745       return oldLimit;
3746     }
3747 
recomputeBufferSizeAfterLimit()3748     private void recomputeBufferSizeAfterLimit() {
3749       totalBufferSize += bufferSizeAfterCurrentLimit;
3750       final int bufferEnd = totalBufferSize - startOffset;
3751       if (bufferEnd > currentLimit) {
3752         // Limit is in current buffer.
3753         bufferSizeAfterCurrentLimit = bufferEnd - currentLimit;
3754         totalBufferSize -= bufferSizeAfterCurrentLimit;
3755       } else {
3756         bufferSizeAfterCurrentLimit = 0;
3757       }
3758     }
3759 
3760     @Override
popLimit(final int oldLimit)3761     public void popLimit(final int oldLimit) {
3762       currentLimit = oldLimit;
3763       recomputeBufferSizeAfterLimit();
3764     }
3765 
3766     @Override
getBytesUntilLimit()3767     public int getBytesUntilLimit() {
3768       if (currentLimit == Integer.MAX_VALUE) {
3769         return -1;
3770       }
3771 
3772       return currentLimit - getTotalBytesRead();
3773     }
3774 
3775     @Override
isAtEnd()3776     public boolean isAtEnd() throws IOException {
3777       return totalBytesRead + currentByteBufferPos - currentByteBufferStartPos == totalBufferSize;
3778     }
3779 
3780     @Override
getTotalBytesRead()3781     public int getTotalBytesRead() {
3782       return (int)
3783           (totalBytesRead - startOffset + currentByteBufferPos - currentByteBufferStartPos);
3784     }
3785 
3786     @Override
readRawByte()3787     public byte readRawByte() throws IOException {
3788       if (currentRemaining() == 0) {
3789         getNextByteBuffer();
3790       }
3791       return UnsafeUtil.getByte(currentByteBufferPos++);
3792     }
3793 
3794     @Override
readRawBytes(final int length)3795     public byte[] readRawBytes(final int length) throws IOException {
3796       if (length >= 0 && length <= currentRemaining()) {
3797         byte[] bytes = new byte[length];
3798         UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, length);
3799         currentByteBufferPos += length;
3800         return bytes;
3801       }
3802       if (length >= 0 && length <= remaining()) {
3803         byte[] bytes = new byte[length];
3804         readRawBytesTo(bytes, 0, length);
3805         return bytes;
3806       }
3807 
3808       if (length <= 0) {
3809         if (length == 0) {
3810           return EMPTY_BYTE_ARRAY;
3811         } else {
3812           throw InvalidProtocolBufferException.negativeSize();
3813         }
3814       }
3815 
3816       throw InvalidProtocolBufferException.truncatedMessage();
3817     }
3818 
3819     /**
3820      * Try to get raw bytes from {@code input} with the size of {@code length} and copy to {@code
3821      * bytes} array. If the size is bigger than the number of remaining bytes in the input, then
3822      * throw {@code truncatedMessage} exception.
3823      *
3824      * @param bytes
3825      * @param offset
3826      * @param length
3827      * @throws IOException
3828      */
readRawBytesTo(byte[] bytes, int offset, final int length)3829     private void readRawBytesTo(byte[] bytes, int offset, final int length) throws IOException {
3830       if (length >= 0 && length <= remaining()) {
3831         int l = length;
3832         while (l > 0) {
3833           if (currentRemaining() == 0) {
3834             getNextByteBuffer();
3835           }
3836           int bytesToCopy = Math.min(l, (int) currentRemaining());
3837           UnsafeUtil.copyMemory(currentByteBufferPos, bytes, length - l + offset, bytesToCopy);
3838           l -= bytesToCopy;
3839           currentByteBufferPos += bytesToCopy;
3840         }
3841         return;
3842       }
3843 
3844       if (length <= 0) {
3845         if (length == 0) {
3846           return;
3847         } else {
3848           throw InvalidProtocolBufferException.negativeSize();
3849         }
3850       }
3851       throw InvalidProtocolBufferException.truncatedMessage();
3852     }
3853 
3854     @Override
skipRawBytes(final int length)3855     public void skipRawBytes(final int length) throws IOException {
3856       if (length >= 0
3857           && length
3858               <= (totalBufferSize
3859                   - totalBytesRead
3860                   - currentByteBufferPos
3861                   + currentByteBufferStartPos)) {
3862         // We have all the bytes we need already.
3863         int l = length;
3864         while (l > 0) {
3865           if (currentRemaining() == 0) {
3866             getNextByteBuffer();
3867           }
3868           int rl = Math.min(l, (int) currentRemaining());
3869           l -= rl;
3870           currentByteBufferPos += rl;
3871         }
3872         return;
3873       }
3874 
3875       if (length < 0) {
3876         throw InvalidProtocolBufferException.negativeSize();
3877       }
3878       throw InvalidProtocolBufferException.truncatedMessage();
3879     }
3880 
3881     // TODO: optimize to fastpath
skipRawVarint()3882     private void skipRawVarint() throws IOException {
3883       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
3884         if (readRawByte() >= 0) {
3885           return;
3886         }
3887       }
3888       throw InvalidProtocolBufferException.malformedVarint();
3889     }
3890 
3891     /**
3892      * Try to get the number of remaining bytes in {@code input}.
3893      *
3894      * @return the number of remaining bytes in {@code input}.
3895      */
remaining()3896     private int remaining() {
3897       return (int)
3898           (totalBufferSize - totalBytesRead - currentByteBufferPos + currentByteBufferStartPos);
3899     }
3900 
3901     /**
3902      * Try to get the number of remaining bytes in {@code currentByteBuffer}.
3903      *
3904      * @return the number of remaining bytes in {@code currentByteBuffer}
3905      */
currentRemaining()3906     private long currentRemaining() {
3907       return (currentByteBufferLimit - currentByteBufferPos);
3908     }
3909 
slice(int begin, int end)3910     private ByteBuffer slice(int begin, int end) throws IOException {
3911       int prevPos = currentByteBuffer.position();
3912       int prevLimit = currentByteBuffer.limit();
3913       try {
3914         ((Buffer) currentByteBuffer).position(begin);
3915         ((Buffer) currentByteBuffer).limit(end);
3916         return currentByteBuffer.slice();
3917       } catch (IllegalArgumentException e) {
3918         throw InvalidProtocolBufferException.truncatedMessage();
3919       } finally {
3920         ((Buffer) currentByteBuffer).position(prevPos);
3921         ((Buffer) currentByteBuffer).limit(prevLimit);
3922       }
3923     }
3924   }
3925 }
3926