tizen 2.3.1 release
[external/protobuf.git] / java / src / main / java / com / google / protobuf / CodedInputStream.java
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 java.io.ByteArrayOutputStream;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.nio.ByteBuffer;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.List;
40
41 /**
42  * Reads and decodes protocol message fields.
43  *
44  * This class contains two kinds of methods:  methods that read specific
45  * protocol message constructs and field types (e.g. {@link #readTag()} and
46  * {@link #readInt32()}) and methods that read low-level values (e.g.
47  * {@link #readRawVarint32()} and {@link #readRawBytes}).  If you are reading
48  * encoded protocol messages, you should use the former methods, but if you are
49  * reading some other format of your own design, use the latter.
50  *
51  * @author kenton@google.com Kenton Varda
52  */
53 public final class CodedInputStream {
54   /**
55    * Create a new CodedInputStream wrapping the given InputStream.
56    */
57   public static CodedInputStream newInstance(final InputStream input) {
58     return new CodedInputStream(input);
59   }
60
61   /**
62    * Create a new CodedInputStream wrapping the given byte array.
63    */
64   public static CodedInputStream newInstance(final byte[] buf) {
65     return newInstance(buf, 0, buf.length);
66   }
67
68   /**
69    * Create a new CodedInputStream wrapping the given byte array slice.
70    */
71   public static CodedInputStream newInstance(final byte[] buf, final int off,
72                                              final int len) {
73     CodedInputStream result = new CodedInputStream(buf, off, len);
74     try {
75       // Some uses of CodedInputStream can be more efficient if they know
76       // exactly how many bytes are available.  By pushing the end point of the
77       // buffer as a limit, we allow them to get this information via
78       // getBytesUntilLimit().  Pushing a limit that we know is at the end of
79       // the stream can never hurt, since we can never past that point anyway.
80       result.pushLimit(len);
81     } catch (InvalidProtocolBufferException ex) {
82       // The only reason pushLimit() might throw an exception here is if len
83       // is negative. Normally pushLimit()'s parameter comes directly off the
84       // wire, so it's important to catch exceptions in case of corrupt or
85       // malicious data. However, in this case, we expect that len is not a
86       // user-supplied value, so we can assume that it being negative indicates
87       // a programming error. Therefore, throwing an unchecked exception is
88       // appropriate.
89       throw new IllegalArgumentException(ex);
90     }
91     return result;
92   }
93
94   /**
95    * Create a new CodedInputStream wrapping the given ByteBuffer. The data
96    * starting from the ByteBuffer's current position to its limit will be read.
97    * The returned CodedInputStream may or may not share the underlying data
98    * in the ByteBuffer, therefore the ByteBuffer cannot be changed while the
99    * CodedInputStream is in use.
100    * Note that the ByteBuffer's position won't be changed by this function.
101    * Concurrent calls with the same ByteBuffer object are safe if no other
102    * thread is trying to alter the ByteBuffer's status.
103    */
104   public static CodedInputStream newInstance(ByteBuffer buf) {
105     if (buf.hasArray()) {
106       return newInstance(buf.array(), buf.arrayOffset() + buf.position(),
107           buf.remaining());
108     } else {
109       ByteBuffer temp = buf.duplicate();
110       byte[] buffer = new byte[temp.remaining()];
111       temp.get(buffer);
112       return newInstance(buffer);
113     }
114   }
115
116   /**
117    * Create a new CodedInputStream wrapping a LiteralByteString.
118    */
119   static CodedInputStream newInstance(LiteralByteString byteString) {
120     CodedInputStream result = new CodedInputStream(byteString);
121     try {
122       // Some uses of CodedInputStream can be more efficient if they know
123       // exactly how many bytes are available.  By pushing the end point of the
124       // buffer as a limit, we allow them to get this information via
125       // getBytesUntilLimit().  Pushing a limit that we know is at the end of
126       // the stream can never hurt, since we can never past that point anyway.
127       result.pushLimit(byteString.size());
128     } catch (InvalidProtocolBufferException ex) {
129       // The only reason pushLimit() might throw an exception here is if len
130       // is negative. Normally pushLimit()'s parameter comes directly off the
131       // wire, so it's important to catch exceptions in case of corrupt or
132       // malicious data. However, in this case, we expect that len is not a
133       // user-supplied value, so we can assume that it being negative indicates
134       // a programming error. Therefore, throwing an unchecked exception is
135       // appropriate.
136       throw new IllegalArgumentException(ex);
137     }
138     return result;
139   }
140
141   // -----------------------------------------------------------------
142
143   /**
144    * Attempt to read a field tag, returning zero if we have reached EOF.
145    * Protocol message parsers use this to read tags, since a protocol message
146    * may legally end wherever a tag occurs, and zero is not a valid tag number.
147    */
148   public int readTag() throws IOException {
149     if (isAtEnd()) {
150       lastTag = 0;
151       return 0;
152     }
153
154     lastTag = readRawVarint32();
155     if (WireFormat.getTagFieldNumber(lastTag) == 0) {
156       // If we actually read zero (or any tag number corresponding to field
157       // number zero), that's not a valid tag.
158       throw InvalidProtocolBufferException.invalidTag();
159     }
160     return lastTag;
161   }
162
163   /**
164    * Verifies that the last call to readTag() returned the given tag value.
165    * This is used to verify that a nested group ended with the correct
166    * end tag.
167    *
168    * @throws InvalidProtocolBufferException {@code value} does not match the
169    *                                        last tag.
170    */
171   public void checkLastTagWas(final int value)
172                               throws InvalidProtocolBufferException {
173     if (lastTag != value) {
174       throw InvalidProtocolBufferException.invalidEndTag();
175     }
176   }
177
178   public int getLastTag() {
179     return lastTag;
180   }
181
182   /**
183    * Reads and discards a single field, given its tag value.
184    *
185    * @return {@code false} if the tag is an endgroup tag, in which case
186    *         nothing is skipped.  Otherwise, returns {@code true}.
187    */
188   public boolean skipField(final int tag) throws IOException {
189     switch (WireFormat.getTagWireType(tag)) {
190       case WireFormat.WIRETYPE_VARINT:
191         skipRawVarint();
192         return true;
193       case WireFormat.WIRETYPE_FIXED64:
194         skipRawBytes(8);
195         return true;
196       case WireFormat.WIRETYPE_LENGTH_DELIMITED:
197         skipRawBytes(readRawVarint32());
198         return true;
199       case WireFormat.WIRETYPE_START_GROUP:
200         skipMessage();
201         checkLastTagWas(
202           WireFormat.makeTag(WireFormat.getTagFieldNumber(tag),
203                              WireFormat.WIRETYPE_END_GROUP));
204         return true;
205       case WireFormat.WIRETYPE_END_GROUP:
206         return false;
207       case WireFormat.WIRETYPE_FIXED32:
208         skipRawBytes(4);
209         return true;
210       default:
211         throw InvalidProtocolBufferException.invalidWireType();
212     }
213   }
214
215   /**
216    * Reads a single field and writes it to output in wire format,
217    * given its tag value.
218    *
219    * @return {@code false} if the tag is an endgroup tag, in which case
220    *         nothing is skipped.  Otherwise, returns {@code true}.
221    */
222   public boolean skipField(final int tag, final CodedOutputStream output)
223       throws IOException {
224     switch (WireFormat.getTagWireType(tag)) {
225       case WireFormat.WIRETYPE_VARINT: {
226         long value = readInt64();
227         output.writeRawVarint32(tag);
228         output.writeUInt64NoTag(value);
229         return true;
230       }
231       case WireFormat.WIRETYPE_FIXED64: {
232         long value = readRawLittleEndian64();
233         output.writeRawVarint32(tag);
234         output.writeFixed64NoTag(value);
235         return true;
236       }
237       case WireFormat.WIRETYPE_LENGTH_DELIMITED: {
238         ByteString value = readBytes();
239         output.writeRawVarint32(tag);
240         output.writeBytesNoTag(value);
241         return true;
242       }
243       case WireFormat.WIRETYPE_START_GROUP: {
244         output.writeRawVarint32(tag);
245         skipMessage(output);
246         int endtag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag),
247                                         WireFormat.WIRETYPE_END_GROUP);
248         checkLastTagWas(endtag);
249         output.writeRawVarint32(endtag);
250         return true;
251       }
252       case WireFormat.WIRETYPE_END_GROUP: {
253         return false;
254       }
255       case WireFormat.WIRETYPE_FIXED32: {
256         int value = readRawLittleEndian32();
257         output.writeRawVarint32(tag);
258         output.writeFixed32NoTag(value);
259         return true;
260       }
261       default:
262         throw InvalidProtocolBufferException.invalidWireType();
263     }
264   }
265
266   /**
267    * Reads and discards an entire message.  This will read either until EOF
268    * or until an endgroup tag, whichever comes first.
269    */
270   public void skipMessage() throws IOException {
271     while (true) {
272       final int tag = readTag();
273       if (tag == 0 || !skipField(tag)) {
274         return;
275       }
276     }
277   }
278
279   /**
280    * Reads an entire message and writes it to output in wire format.
281    * This will read either until EOF or until an endgroup tag,
282    * whichever comes first.
283    */
284   public void skipMessage(CodedOutputStream output) throws IOException {
285     while (true) {
286       final int tag = readTag();
287       if (tag == 0 || !skipField(tag, output)) {
288         return;
289       }
290     }
291   }
292
293   /**
294    * Collects the bytes skipped and returns the data in a ByteBuffer.
295    */
296   private class SkippedDataSink implements RefillCallback {
297     private int lastPos = bufferPos;
298     private ByteArrayOutputStream byteArrayStream;
299
300     @Override
301     public void onRefill() {
302       if (byteArrayStream == null) {
303         byteArrayStream = new ByteArrayOutputStream();
304       }
305       byteArrayStream.write(buffer, lastPos, bufferPos - lastPos);
306       lastPos = 0;
307     }
308
309     /**
310      * Gets skipped data in a ByteBuffer. This method should only be
311      * called once.
312      */
313     ByteBuffer getSkippedData() {
314       if (byteArrayStream == null) {
315         return ByteBuffer.wrap(buffer, lastPos, bufferPos - lastPos);
316       } else {
317         byteArrayStream.write(buffer, lastPos, bufferPos);
318         return ByteBuffer.wrap(byteArrayStream.toByteArray());
319       }
320     }
321   }
322
323
324   // -----------------------------------------------------------------
325
326   /** Read a {@code double} field value from the stream. */
327   public double readDouble() throws IOException {
328     return Double.longBitsToDouble(readRawLittleEndian64());
329   }
330
331   /** Read a {@code float} field value from the stream. */
332   public float readFloat() throws IOException {
333     return Float.intBitsToFloat(readRawLittleEndian32());
334   }
335
336   /** Read a {@code uint64} field value from the stream. */
337   public long readUInt64() throws IOException {
338     return readRawVarint64();
339   }
340
341   /** Read an {@code int64} field value from the stream. */
342   public long readInt64() throws IOException {
343     return readRawVarint64();
344   }
345
346   /** Read an {@code int32} field value from the stream. */
347   public int readInt32() throws IOException {
348     return readRawVarint32();
349   }
350
351   /** Read a {@code fixed64} field value from the stream. */
352   public long readFixed64() throws IOException {
353     return readRawLittleEndian64();
354   }
355
356   /** Read a {@code fixed32} field value from the stream. */
357   public int readFixed32() throws IOException {
358     return readRawLittleEndian32();
359   }
360
361   /** Read a {@code bool} field value from the stream. */
362   public boolean readBool() throws IOException {
363     return readRawVarint64() != 0;
364   }
365
366   /**
367    * Read a {@code string} field value from the stream.
368    * If the stream contains malformed UTF-8,
369    * replace the offending bytes with the standard UTF-8 replacement character.
370    */
371   public String readString() throws IOException {
372     final int size = readRawVarint32();
373     if (size <= (bufferSize - bufferPos) && size > 0) {
374       // Fast path:  We already have the bytes in a contiguous buffer, so
375       //   just copy directly from it.
376       final String result = new String(buffer, bufferPos, size, "UTF-8");
377       bufferPos += size;
378       return result;
379     } else if (size == 0) {
380       return "";
381     } else {
382       // Slow path:  Build a byte array first then copy it.
383       return new String(readRawBytesSlowPath(size), "UTF-8");
384     }
385   }
386
387   /**
388    * Read a {@code string} field value from the stream.
389    * If the stream contains malformed UTF-8,
390    * throw exception {@link InvalidProtocolBufferException}.
391    */
392   public String readStringRequireUtf8() throws IOException {
393     final int size = readRawVarint32();
394     final byte[] bytes;
395     int pos = bufferPos;
396     if (size <= (bufferSize - pos) && size > 0) {
397       // Fast path:  We already have the bytes in a contiguous buffer, so
398       //   just copy directly from it.
399       bytes = buffer;
400       bufferPos = pos + size;
401     } else if (size == 0) {
402       return "";
403     } else {
404       // Slow path:  Build a byte array first then copy it.
405       bytes = readRawBytesSlowPath(size);
406       pos = 0;
407     }
408     // TODO(martinrb): We could save a pass by validating while decoding.
409     if (!Utf8.isValidUtf8(bytes, pos, pos + size)) {
410       throw InvalidProtocolBufferException.invalidUtf8();
411     }
412     return new String(bytes, pos, size, "UTF-8");
413   }
414
415   /** Read a {@code group} field value from the stream. */
416   public void readGroup(final int fieldNumber,
417                         final MessageLite.Builder builder,
418                         final ExtensionRegistryLite extensionRegistry)
419       throws IOException {
420     if (recursionDepth >= recursionLimit) {
421       throw InvalidProtocolBufferException.recursionLimitExceeded();
422     }
423     ++recursionDepth;
424     builder.mergeFrom(this, extensionRegistry);
425     checkLastTagWas(
426       WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
427     --recursionDepth;
428   }
429
430
431   /** Read a {@code group} field value from the stream. */
432   public <T extends MessageLite> T readGroup(
433       final int fieldNumber,
434       final Parser<T> parser,
435       final ExtensionRegistryLite extensionRegistry)
436       throws IOException {
437     if (recursionDepth >= recursionLimit) {
438       throw InvalidProtocolBufferException.recursionLimitExceeded();
439     }
440     ++recursionDepth;
441     T result = parser.parsePartialFrom(this, extensionRegistry);
442     checkLastTagWas(
443       WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
444     --recursionDepth;
445     return result;
446   }
447
448   /**
449    * Reads a {@code group} field value from the stream and merges it into the
450    * given {@link UnknownFieldSet}.
451    *
452    * @deprecated UnknownFieldSet.Builder now implements MessageLite.Builder, so
453    *             you can just call {@link #readGroup}.
454    */
455   @Deprecated
456   public void readUnknownGroup(final int fieldNumber,
457                                final MessageLite.Builder builder)
458       throws IOException {
459     // We know that UnknownFieldSet will ignore any ExtensionRegistry so it
460     // is safe to pass null here.  (We can't call
461     // ExtensionRegistry.getEmptyRegistry() because that would make this
462     // class depend on ExtensionRegistry, which is not part of the lite
463     // library.)
464     readGroup(fieldNumber, builder, null);
465   }
466
467   /** Read an embedded message field value from the stream. */
468   public void readMessage(final MessageLite.Builder builder,
469                           final ExtensionRegistryLite extensionRegistry)
470       throws IOException {
471     final int length = readRawVarint32();
472     if (recursionDepth >= recursionLimit) {
473       throw InvalidProtocolBufferException.recursionLimitExceeded();
474     }
475     final int oldLimit = pushLimit(length);
476     ++recursionDepth;
477     builder.mergeFrom(this, extensionRegistry);
478     checkLastTagWas(0);
479     --recursionDepth;
480     popLimit(oldLimit);
481   }
482
483
484   /** Read an embedded message field value from the stream. */
485   public <T extends MessageLite> T readMessage(
486       final Parser<T> parser,
487       final ExtensionRegistryLite extensionRegistry)
488       throws IOException {
489     int length = readRawVarint32();
490     if (recursionDepth >= recursionLimit) {
491       throw InvalidProtocolBufferException.recursionLimitExceeded();
492     }
493     final int oldLimit = pushLimit(length);
494     ++recursionDepth;
495     T result = parser.parsePartialFrom(this, extensionRegistry);
496     checkLastTagWas(0);
497     --recursionDepth;
498     popLimit(oldLimit);
499     return result;
500   }
501
502   /** Read a {@code bytes} field value from the stream. */
503   public ByteString readBytes() throws IOException {
504     final int size = readRawVarint32();
505     if (size <= (bufferSize - bufferPos) && size > 0) {
506       // Fast path:  We already have the bytes in a contiguous buffer, so
507       //   just copy directly from it.
508       final ByteString result = bufferIsImmutable && enableAliasing
509           ? new BoundedByteString(buffer, bufferPos, size)
510           : ByteString.copyFrom(buffer, bufferPos, size);
511       bufferPos += size;
512       return result;
513     } else if (size == 0) {
514       return ByteString.EMPTY;
515     } else {
516       // Slow path:  Build a byte array first then copy it.
517       return new LiteralByteString(readRawBytesSlowPath(size));
518     }
519   }
520
521   /** Read a {@code bytes} field value from the stream. */
522   public byte[] readByteArray() throws IOException {
523     final int size = readRawVarint32();
524     if (size <= (bufferSize - bufferPos) && size > 0) {
525       // Fast path: We already have the bytes in a contiguous buffer, so
526       // just copy directly from it.
527       final byte[] result =
528           Arrays.copyOfRange(buffer, bufferPos, bufferPos + size);
529       bufferPos += size;
530       return result;
531     } else {
532       // Slow path: Build a byte array first then copy it.
533       return readRawBytesSlowPath(size);
534     }
535   }
536
537   /** Read a {@code bytes} field value from the stream. */
538   public ByteBuffer readByteBuffer() throws IOException {
539     final int size = readRawVarint32();
540     if (size <= (bufferSize - bufferPos) && size > 0) {
541       // Fast path: We already have the bytes in a contiguous buffer.
542       // When aliasing is enabled, we can return a ByteBuffer pointing directly
543       // into the underlying byte array without copy if the CodedInputStream is
544       // constructed from a byte array. If aliasing is disabled or the input is
545       // from an InputStream or ByteString, we have to make a copy of the bytes.
546       ByteBuffer result = input == null && !bufferIsImmutable && enableAliasing
547           ? ByteBuffer.wrap(buffer, bufferPos, size).slice()
548           : ByteBuffer.wrap(Arrays.copyOfRange(
549               buffer, bufferPos, bufferPos + size));
550       bufferPos += size;
551       return result;
552     } else if (size == 0) {
553       return Internal.EMPTY_BYTE_BUFFER;
554     } else {
555       // Slow path: Build a byte array first then copy it.
556       return ByteBuffer.wrap(readRawBytesSlowPath(size));
557     }
558   }
559
560   /** Read a {@code uint32} field value from the stream. */
561   public int readUInt32() throws IOException {
562     return readRawVarint32();
563   }
564
565   /**
566    * Read an enum field value from the stream.  Caller is responsible
567    * for converting the numeric value to an actual enum.
568    */
569   public int readEnum() throws IOException {
570     return readRawVarint32();
571   }
572
573   /** Read an {@code sfixed32} field value from the stream. */
574   public int readSFixed32() throws IOException {
575     return readRawLittleEndian32();
576   }
577
578   /** Read an {@code sfixed64} field value from the stream. */
579   public long readSFixed64() throws IOException {
580     return readRawLittleEndian64();
581   }
582
583   /** Read an {@code sint32} field value from the stream. */
584   public int readSInt32() throws IOException {
585     return decodeZigZag32(readRawVarint32());
586   }
587
588   /** Read an {@code sint64} field value from the stream. */
589   public long readSInt64() throws IOException {
590     return decodeZigZag64(readRawVarint64());
591   }
592
593   // =================================================================
594
595   /**
596    * Read a raw Varint from the stream.  If larger than 32 bits, discard the
597    * upper bits.
598    */
599   public int readRawVarint32() throws IOException {
600     // See implementation notes for readRawVarint64
601  fastpath: {
602       int pos = bufferPos;
603
604       if (bufferSize == pos) {
605         break fastpath;
606       }
607
608       final byte[] buffer = this.buffer;
609       int x;
610       if ((x = buffer[pos++]) >= 0) {
611         bufferPos = pos;
612         return x;
613       } else if (bufferSize - pos < 9) {
614         break fastpath;
615       } else if ((x ^= (buffer[pos++] << 7)) < 0L) {
616         x ^= (~0L << 7);
617       } else if ((x ^= (buffer[pos++] << 14)) >= 0L) {
618         x ^= (~0L << 7) ^ (~0L << 14);
619       } else if ((x ^= (buffer[pos++] << 21)) < 0L) {
620         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21);
621       } else {
622         int y = buffer[pos++];
623         x ^= y << 28;
624         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
625         if (y < 0 &&
626             buffer[pos++] < 0 &&
627             buffer[pos++] < 0 &&
628             buffer[pos++] < 0 &&
629             buffer[pos++] < 0 &&
630             buffer[pos++] < 0) {
631           break fastpath;  // Will throw malformedVarint()
632         }
633       }
634       bufferPos = pos;
635       return x;
636     }
637     return (int) readRawVarint64SlowPath();
638   }
639
640   private void skipRawVarint() throws IOException {
641     if (bufferSize - bufferPos >= 10) {
642       final byte[] buffer = this.buffer;
643       int pos = bufferPos;
644       for (int i = 0; i < 10; i++) {
645         if (buffer[pos++] >= 0) {
646           bufferPos = pos;
647           return;
648         }
649       }
650     }
651     skipRawVarintSlowPath();
652   }
653
654   private void skipRawVarintSlowPath() throws IOException {
655     for (int i = 0; i < 10; i++) {
656       if (readRawByte() >= 0) {
657         return;
658       }
659     }
660     throw InvalidProtocolBufferException.malformedVarint();
661   }
662
663   /**
664    * Reads a varint from the input one byte at a time, so that it does not
665    * read any bytes after the end of the varint.  If you simply wrapped the
666    * stream in a CodedInputStream and used {@link #readRawVarint32(InputStream)}
667    * then you would probably end up reading past the end of the varint since
668    * CodedInputStream buffers its input.
669    */
670   static int readRawVarint32(final InputStream input) throws IOException {
671     final int firstByte = input.read();
672     if (firstByte == -1) {
673       throw InvalidProtocolBufferException.truncatedMessage();
674     }
675     return readRawVarint32(firstByte, input);
676   }
677
678   /**
679    * Like {@link #readRawVarint32(InputStream)}, but expects that the caller
680    * has already read one byte.  This allows the caller to determine if EOF
681    * has been reached before attempting to read.
682    */
683   public static int readRawVarint32(
684       final int firstByte, final InputStream input) throws IOException {
685     if ((firstByte & 0x80) == 0) {
686       return firstByte;
687     }
688
689     int result = firstByte & 0x7f;
690     int offset = 7;
691     for (; offset < 32; offset += 7) {
692       final int b = input.read();
693       if (b == -1) {
694         throw InvalidProtocolBufferException.truncatedMessage();
695       }
696       result |= (b & 0x7f) << offset;
697       if ((b & 0x80) == 0) {
698         return result;
699       }
700     }
701     // Keep reading up to 64 bits.
702     for (; offset < 64; offset += 7) {
703       final int b = input.read();
704       if (b == -1) {
705         throw InvalidProtocolBufferException.truncatedMessage();
706       }
707       if ((b & 0x80) == 0) {
708         return result;
709       }
710     }
711     throw InvalidProtocolBufferException.malformedVarint();
712   }
713
714   /** Read a raw Varint from the stream. */
715   public long readRawVarint64() throws IOException {
716     // Implementation notes:
717     //
718     // Optimized for one-byte values, expected to be common.
719     // The particular code below was selected from various candidates
720     // empirically, by winning VarintBenchmark.
721     //
722     // Sign extension of (signed) Java bytes is usually a nuisance, but
723     // we exploit it here to more easily obtain the sign of bytes read.
724     // Instead of cleaning up the sign extension bits by masking eagerly,
725     // we delay until we find the final (positive) byte, when we clear all
726     // accumulated bits with one xor.  We depend on javac to constant fold.
727  fastpath: {
728       int pos = bufferPos;
729
730       if (bufferSize == pos) {
731         break fastpath;
732       }
733
734       final byte[] buffer = this.buffer;
735       long x;
736       int y;
737       if ((y = buffer[pos++]) >= 0) {
738         bufferPos = pos;
739         return y;
740       } else if (bufferSize - pos < 9) {
741         break fastpath;
742       } else if ((x = y ^ (buffer[pos++] << 7)) < 0L) {
743         x ^= (~0L << 7);
744       } else if ((x ^= (buffer[pos++] << 14)) >= 0L) {
745         x ^= (~0L << 7) ^ (~0L << 14);
746       } else if ((x ^= (buffer[pos++] << 21)) < 0L) {
747         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21);
748       } else if ((x ^= ((long) buffer[pos++] << 28)) >= 0L) {
749         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
750       } else if ((x ^= ((long) buffer[pos++] << 35)) < 0L) {
751         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
752       } else if ((x ^= ((long) buffer[pos++] << 42)) >= 0L) {
753         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
754       } else if ((x ^= ((long) buffer[pos++] << 49)) < 0L) {
755         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42)
756             ^ (~0L << 49);
757       } else {
758         x ^= ((long) buffer[pos++] << 56);
759         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42)
760             ^ (~0L << 49) ^ (~0L << 56);
761         if (x < 0L) {
762           if (buffer[pos++] < 0L) {
763             break fastpath;  // Will throw malformedVarint()
764           }
765         }
766       }
767       bufferPos = pos;
768       return x;
769     }
770     return readRawVarint64SlowPath();
771   }
772
773   /** Variant of readRawVarint64 for when uncomfortably close to the limit. */
774   /* Visible for testing */
775   long readRawVarint64SlowPath() throws IOException {
776     long result = 0;
777     for (int shift = 0; shift < 64; shift += 7) {
778       final byte b = readRawByte();
779       result |= (long) (b & 0x7F) << shift;
780       if ((b & 0x80) == 0) {
781         return result;
782       }
783     }
784     throw InvalidProtocolBufferException.malformedVarint();
785   }
786
787   /** Read a 32-bit little-endian integer from the stream. */
788   public int readRawLittleEndian32() throws IOException {
789     int pos = bufferPos;
790
791     // hand-inlined ensureAvailable(4);
792     if (bufferSize - pos < 4) {
793       refillBuffer(4);
794       pos = bufferPos;
795     }
796
797     final byte[] buffer = this.buffer;
798     bufferPos = pos + 4;
799     return (((buffer[pos]     & 0xff))       |
800             ((buffer[pos + 1] & 0xff) <<  8) |
801             ((buffer[pos + 2] & 0xff) << 16) |
802             ((buffer[pos + 3] & 0xff) << 24));
803   }
804
805   /** Read a 64-bit little-endian integer from the stream. */
806   public long readRawLittleEndian64() throws IOException {
807     int pos = bufferPos;
808
809     // hand-inlined ensureAvailable(8);
810     if (bufferSize - pos < 8) {
811       refillBuffer(8);
812       pos = bufferPos;
813     }
814
815     final byte[] buffer = this.buffer;
816     bufferPos = pos + 8;
817     return ((((long) buffer[pos]     & 0xffL))       |
818             (((long) buffer[pos + 1] & 0xffL) <<  8) |
819             (((long) buffer[pos + 2] & 0xffL) << 16) |
820             (((long) buffer[pos + 3] & 0xffL) << 24) |
821             (((long) buffer[pos + 4] & 0xffL) << 32) |
822             (((long) buffer[pos + 5] & 0xffL) << 40) |
823             (((long) buffer[pos + 6] & 0xffL) << 48) |
824             (((long) buffer[pos + 7] & 0xffL) << 56));
825   }
826
827   /**
828    * Decode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
829    * into values that can be efficiently encoded with varint.  (Otherwise,
830    * negative values must be sign-extended to 64 bits to be varint encoded,
831    * thus always taking 10 bytes on the wire.)
832    *
833    * @param n An unsigned 32-bit integer, stored in a signed int because
834    *          Java has no explicit unsigned support.
835    * @return A signed 32-bit integer.
836    */
837   public static int decodeZigZag32(final int n) {
838     return (n >>> 1) ^ -(n & 1);
839   }
840
841   /**
842    * Decode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
843    * into values that can be efficiently encoded with varint.  (Otherwise,
844    * negative values must be sign-extended to 64 bits to be varint encoded,
845    * thus always taking 10 bytes on the wire.)
846    *
847    * @param n An unsigned 64-bit integer, stored in a signed int because
848    *          Java has no explicit unsigned support.
849    * @return A signed 64-bit integer.
850    */
851   public static long decodeZigZag64(final long n) {
852     return (n >>> 1) ^ -(n & 1);
853   }
854
855   // -----------------------------------------------------------------
856
857   private final byte[] buffer;
858   private final boolean bufferIsImmutable;
859   private int bufferSize;
860   private int bufferSizeAfterLimit;
861   private int bufferPos;
862   private final InputStream input;
863   private int lastTag;
864   private boolean enableAliasing = false;
865
866   /**
867    * The total number of bytes read before the current buffer.  The total
868    * bytes read up to the current position can be computed as
869    * {@code totalBytesRetired + bufferPos}.  This value may be negative if
870    * reading started in the middle of the current buffer (e.g. if the
871    * constructor that takes a byte array and an offset was used).
872    */
873   private int totalBytesRetired;
874
875   /** The absolute position of the end of the current message. */
876   private int currentLimit = Integer.MAX_VALUE;
877
878   /** See setRecursionLimit() */
879   private int recursionDepth;
880   private int recursionLimit = DEFAULT_RECURSION_LIMIT;
881
882   /** See setSizeLimit() */
883   private int sizeLimit = DEFAULT_SIZE_LIMIT;
884
885   private static final int DEFAULT_RECURSION_LIMIT = 64;
886   private static final int DEFAULT_SIZE_LIMIT = 64 << 20;  // 64MB
887   private static final int BUFFER_SIZE = 4096;
888
889   private CodedInputStream(final byte[] buffer, final int off, final int len) {
890     this.buffer = buffer;
891     bufferSize = off + len;
892     bufferPos = off;
893     totalBytesRetired = -off;
894     input = null;
895     bufferIsImmutable = false;
896   }
897
898   private CodedInputStream(final InputStream input) {
899     buffer = new byte[BUFFER_SIZE];
900     bufferSize = 0;
901     bufferPos = 0;
902     totalBytesRetired = 0;
903     this.input = input;
904     bufferIsImmutable = false;
905   }
906
907   private CodedInputStream(final LiteralByteString byteString) {
908     buffer = byteString.bytes;
909     bufferPos = byteString.getOffsetIntoBytes();
910     bufferSize = bufferPos + byteString.size();
911     totalBytesRetired = -bufferPos;
912     input = null;
913     bufferIsImmutable = true;
914   }
915
916   public void enableAliasing(boolean enabled) {
917     this.enableAliasing = enabled;
918   }
919
920   /**
921    * Set the maximum message recursion depth.  In order to prevent malicious
922    * messages from causing stack overflows, {@code CodedInputStream} limits
923    * how deeply messages may be nested.  The default limit is 64.
924    *
925    * @return the old limit.
926    */
927   public int setRecursionLimit(final int limit) {
928     if (limit < 0) {
929       throw new IllegalArgumentException(
930         "Recursion limit cannot be negative: " + limit);
931     }
932     final int oldLimit = recursionLimit;
933     recursionLimit = limit;
934     return oldLimit;
935   }
936
937   /**
938    * Set the maximum message size.  In order to prevent malicious
939    * messages from exhausting memory or causing integer overflows,
940    * {@code CodedInputStream} limits how large a message may be.
941    * The default limit is 64MB.  You should set this limit as small
942    * as you can without harming your app's functionality.  Note that
943    * size limits only apply when reading from an {@code InputStream}, not
944    * when constructed around a raw byte array (nor with
945    * {@link ByteString#newCodedInput}).
946    * <p>
947    * If you want to read several messages from a single CodedInputStream, you
948    * could call {@link #resetSizeCounter()} after each one to avoid hitting the
949    * size limit.
950    *
951    * @return the old limit.
952    */
953   public int setSizeLimit(final int limit) {
954     if (limit < 0) {
955       throw new IllegalArgumentException(
956         "Size limit cannot be negative: " + limit);
957     }
958     final int oldLimit = sizeLimit;
959     sizeLimit = limit;
960     return oldLimit;
961   }
962
963   /**
964    * Resets the current size counter to zero (see {@link #setSizeLimit(int)}).
965    */
966   public void resetSizeCounter() {
967     totalBytesRetired = -bufferPos;
968   }
969
970   /**
971    * Sets {@code currentLimit} to (current position) + {@code byteLimit}.  This
972    * is called when descending into a length-delimited embedded message.
973    *
974    * <p>Note that {@code pushLimit()} does NOT affect how many bytes the
975    * {@code CodedInputStream} reads from an underlying {@code InputStream} when
976    * refreshing its buffer.  If you need to prevent reading past a certain
977    * point in the underlying {@code InputStream} (e.g. because you expect it to
978    * contain more data after the end of the message which you need to handle
979    * differently) then you must place a wrapper around your {@code InputStream}
980    * which limits the amount of data that can be read from it.
981    *
982    * @return the old limit.
983    */
984   public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
985     if (byteLimit < 0) {
986       throw InvalidProtocolBufferException.negativeSize();
987     }
988     byteLimit += totalBytesRetired + bufferPos;
989     final int oldLimit = currentLimit;
990     if (byteLimit > oldLimit) {
991       throw InvalidProtocolBufferException.truncatedMessage();
992     }
993     currentLimit = byteLimit;
994
995     recomputeBufferSizeAfterLimit();
996
997     return oldLimit;
998   }
999
1000   private void recomputeBufferSizeAfterLimit() {
1001     bufferSize += bufferSizeAfterLimit;
1002     final int bufferEnd = totalBytesRetired + bufferSize;
1003     if (bufferEnd > currentLimit) {
1004       // Limit is in current buffer.
1005       bufferSizeAfterLimit = bufferEnd - currentLimit;
1006       bufferSize -= bufferSizeAfterLimit;
1007     } else {
1008       bufferSizeAfterLimit = 0;
1009     }
1010   }
1011
1012   /**
1013    * Discards the current limit, returning to the previous limit.
1014    *
1015    * @param oldLimit The old limit, as returned by {@code pushLimit}.
1016    */
1017   public void popLimit(final int oldLimit) {
1018     currentLimit = oldLimit;
1019     recomputeBufferSizeAfterLimit();
1020   }
1021
1022   /**
1023    * Returns the number of bytes to be read before the current limit.
1024    * If no limit is set, returns -1.
1025    */
1026   public int getBytesUntilLimit() {
1027     if (currentLimit == Integer.MAX_VALUE) {
1028       return -1;
1029     }
1030
1031     final int currentAbsolutePosition = totalBytesRetired + bufferPos;
1032     return currentLimit - currentAbsolutePosition;
1033   }
1034
1035   /**
1036    * Returns true if the stream has reached the end of the input.  This is the
1037    * case if either the end of the underlying input source has been reached or
1038    * if the stream has reached a limit created using {@link #pushLimit(int)}.
1039    */
1040   public boolean isAtEnd() throws IOException {
1041     return bufferPos == bufferSize && !tryRefillBuffer(1);
1042   }
1043
1044   /**
1045    * The total bytes read up to the current position. Calling
1046    * {@link #resetSizeCounter()} resets this value to zero.
1047    */
1048   public int getTotalBytesRead() {
1049       return totalBytesRetired + bufferPos;
1050   }
1051
1052   private interface RefillCallback {
1053     void onRefill();
1054   }
1055
1056   private RefillCallback refillCallback = null;
1057
1058   /**
1059    * Ensures that at least {@code n} bytes are available in the buffer, reading
1060    * more bytes from the input if necessary to make it so.  Caller must ensure
1061    * that the requested space is less than BUFFER_SIZE.
1062    *
1063    * @throws InvalidProtocolBufferException The end of the stream or the current
1064    *                                        limit was reached.
1065    */
1066   private void ensureAvailable(int n) throws IOException {
1067     if (bufferSize - bufferPos < n) {
1068       refillBuffer(n);
1069     }
1070   }
1071
1072   /**
1073    * Reads more bytes from the input, making at least {@code n} bytes available
1074    * in the buffer.  Caller must ensure that the requested space is not yet
1075    * available, and that the requested space is less than BUFFER_SIZE.
1076    *
1077    * @throws InvalidProtocolBufferException The end of the stream or the current
1078    *                                        limit was reached.
1079    */
1080   private void refillBuffer(int n) throws IOException {
1081     if (!tryRefillBuffer(n)) {
1082       throw InvalidProtocolBufferException.truncatedMessage();
1083     }
1084   }
1085
1086   /**
1087    * Tries to read more bytes from the input, making at least {@code n} bytes
1088    * available in the buffer.  Caller must ensure that the requested space is
1089    * not yet available, and that the requested space is less than BUFFER_SIZE.
1090    *
1091    * @return {@code true} if the bytes could be made available; {@code false}
1092    *         if the end of the stream or the current limit was reached.
1093    */
1094   private boolean tryRefillBuffer(int n) throws IOException {
1095     if (bufferPos + n <= bufferSize) {
1096       throw new IllegalStateException(
1097           "refillBuffer() called when " + n +
1098           " bytes were already available in buffer");
1099     }
1100
1101     if (totalBytesRetired + bufferPos + n > currentLimit) {
1102       // Oops, we hit a limit.
1103       return false;
1104     }
1105
1106     if (refillCallback != null) {
1107       refillCallback.onRefill();
1108     }
1109
1110     if (input != null) {
1111       int pos = bufferPos;
1112       if (pos > 0) {
1113         if (bufferSize > pos) {
1114           System.arraycopy(buffer, pos, buffer, 0, bufferSize - pos);
1115         }
1116         totalBytesRetired += pos;
1117         bufferSize -= pos;
1118         bufferPos = 0;
1119       }
1120
1121       int bytesRead = input.read(buffer, bufferSize, buffer.length - bufferSize);
1122       if (bytesRead == 0 || bytesRead < -1 || bytesRead > buffer.length) {
1123         throw new IllegalStateException(
1124             "InputStream#read(byte[]) returned invalid result: " + bytesRead +
1125             "\nThe InputStream implementation is buggy.");
1126       }
1127       if (bytesRead > 0) {
1128         bufferSize += bytesRead;
1129         // Integer-overflow-conscious check against sizeLimit
1130         if (totalBytesRetired + n - sizeLimit > 0) {
1131           throw InvalidProtocolBufferException.sizeLimitExceeded();
1132         }
1133         recomputeBufferSizeAfterLimit();
1134         return (bufferSize >= n) ? true : tryRefillBuffer(n);
1135       }
1136     }
1137
1138     return false;
1139   }
1140
1141   /**
1142    * Read one byte from the input.
1143    *
1144    * @throws InvalidProtocolBufferException The end of the stream or the current
1145    *                                        limit was reached.
1146    */
1147   public byte readRawByte() throws IOException {
1148     if (bufferPos == bufferSize) {
1149       refillBuffer(1);
1150     }
1151     return buffer[bufferPos++];
1152   }
1153
1154   /**
1155    * Read a fixed size of bytes from the input.
1156    *
1157    * @throws InvalidProtocolBufferException The end of the stream or the current
1158    *                                        limit was reached.
1159    */
1160   public byte[] readRawBytes(final int size) throws IOException {
1161     final int pos = bufferPos;
1162     if (size <= (bufferSize - pos) && size > 0) {
1163       bufferPos = pos + size;
1164       return Arrays.copyOfRange(buffer, pos, pos + size);
1165     } else {
1166       return readRawBytesSlowPath(size);
1167     }
1168   }
1169
1170   /**
1171    * Exactly like readRawBytes, but caller must have already checked the fast
1172    * path: (size <= (bufferSize - pos) && size > 0)
1173    */
1174   private byte[] readRawBytesSlowPath(final int size) throws IOException {
1175     if (size <= 0) {
1176       if (size == 0) {
1177         return Internal.EMPTY_BYTE_ARRAY;
1178       } else {
1179         throw InvalidProtocolBufferException.negativeSize();
1180       }
1181     }
1182
1183     if (totalBytesRetired + bufferPos + size > currentLimit) {
1184       // Read to the end of the stream anyway.
1185       skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
1186       // Then fail.
1187       throw InvalidProtocolBufferException.truncatedMessage();
1188     }
1189
1190     if (size < BUFFER_SIZE) {
1191       // Reading more bytes than are in the buffer, but not an excessive number
1192       // of bytes.  We can safely allocate the resulting array ahead of time.
1193
1194       // First copy what we have.
1195       final byte[] bytes = new byte[size];
1196       int pos = bufferSize - bufferPos;
1197       System.arraycopy(buffer, bufferPos, bytes, 0, pos);
1198       bufferPos = bufferSize;
1199
1200       // We want to refill the buffer and then copy from the buffer into our
1201       // byte array rather than reading directly into our byte array because
1202       // the input may be unbuffered.
1203       ensureAvailable(size - pos);
1204       System.arraycopy(buffer, 0, bytes, pos, size - pos);
1205       bufferPos = size - pos;
1206
1207       return bytes;
1208     } else {
1209       // The size is very large.  For security reasons, we can't allocate the
1210       // entire byte array yet.  The size comes directly from the input, so a
1211       // maliciously-crafted message could provide a bogus very large size in
1212       // order to trick the app into allocating a lot of memory.  We avoid this
1213       // by allocating and reading only a small chunk at a time, so that the
1214       // malicious message must actually *be* extremely large to cause
1215       // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
1216
1217       // Remember the buffer markers since we'll have to copy the bytes out of
1218       // it later.
1219       final int originalBufferPos = bufferPos;
1220       final int originalBufferSize = bufferSize;
1221
1222       // Mark the current buffer consumed.
1223       totalBytesRetired += bufferSize;
1224       bufferPos = 0;
1225       bufferSize = 0;
1226
1227       // Read all the rest of the bytes we need.
1228       int sizeLeft = size - (originalBufferSize - originalBufferPos);
1229       final List<byte[]> chunks = new ArrayList<byte[]>();
1230
1231       while (sizeLeft > 0) {
1232         final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)];
1233         int pos = 0;
1234         while (pos < chunk.length) {
1235           final int n = (input == null) ? -1 :
1236             input.read(chunk, pos, chunk.length - pos);
1237           if (n == -1) {
1238             throw InvalidProtocolBufferException.truncatedMessage();
1239           }
1240           totalBytesRetired += n;
1241           pos += n;
1242         }
1243         sizeLeft -= chunk.length;
1244         chunks.add(chunk);
1245       }
1246
1247       // OK, got everything.  Now concatenate it all into one buffer.
1248       final byte[] bytes = new byte[size];
1249
1250       // Start by copying the leftover bytes from this.buffer.
1251       int pos = originalBufferSize - originalBufferPos;
1252       System.arraycopy(buffer, originalBufferPos, bytes, 0, pos);
1253
1254       // And now all the chunks.
1255       for (final byte[] chunk : chunks) {
1256         System.arraycopy(chunk, 0, bytes, pos, chunk.length);
1257         pos += chunk.length;
1258       }
1259
1260       // Done.
1261       return bytes;
1262     }
1263   }
1264
1265   /**
1266    * Reads and discards {@code size} bytes.
1267    *
1268    * @throws InvalidProtocolBufferException The end of the stream or the current
1269    *                                        limit was reached.
1270    */
1271   public void skipRawBytes(final int size) throws IOException {
1272     if (size <= (bufferSize - bufferPos) && size >= 0) {
1273       // We have all the bytes we need already.
1274       bufferPos += size;
1275     } else {
1276       skipRawBytesSlowPath(size);
1277     }
1278   }
1279
1280   /**
1281    * Exactly like skipRawBytes, but caller must have already checked the fast
1282    * path: (size <= (bufferSize - pos) && size >= 0)
1283    */
1284   private void skipRawBytesSlowPath(final int size) throws IOException {
1285     if (size < 0) {
1286       throw InvalidProtocolBufferException.negativeSize();
1287     }
1288
1289     if (totalBytesRetired + bufferPos + size > currentLimit) {
1290       // Read to the end of the stream anyway.
1291       skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
1292       // Then fail.
1293       throw InvalidProtocolBufferException.truncatedMessage();
1294     }
1295
1296     // Skipping more bytes than are in the buffer.  First skip what we have.
1297     int pos = bufferSize - bufferPos;
1298     bufferPos = bufferSize;
1299
1300     // Keep refilling the buffer until we get to the point we wanted to skip to.
1301     // This has the side effect of ensuring the limits are updated correctly.
1302     refillBuffer(1);
1303     while (size - pos > bufferSize) {
1304       pos += bufferSize;
1305       bufferPos = bufferSize;
1306       refillBuffer(1);
1307     }
1308
1309     bufferPos = size - pos;
1310   }
1311 }