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
31package com.google.protobuf;
32
33import java.io.ByteArrayOutputStream;
34import java.io.IOException;
35import java.io.InputStream;
36import java.nio.ByteBuffer;
37import java.util.ArrayList;
38import java.util.Arrays;
39import 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 */
53public 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}
1312