1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillepackage com.google.protobuf;
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.io.IOException;
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.io.InputStream;
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.util.ArrayList;
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport java.util.List;
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/**
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * Reads and decodes protocol message fields.
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * This class contains two kinds of methods:  methods that read specific
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * protocol message constructs and field types (e.g. {@link #readTag()} and
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * {@link #readInt32()}) and methods that read low-level values (e.g.
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * {@link #readRawVarint32()} and {@link #readRawBytes}).  If you are reading
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * encoded protocol messages, you should use the former methods, but if you are
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * reading some other format of your own design, use the latter.
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville * @author kenton@google.com Kenton Varda
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville */
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillepublic final class CodedInputStream {
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Create a new CodedInputStream wrapping the given InputStream.
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static CodedInputStream newInstance(final InputStream input) {
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new CodedInputStream(input);
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Create a new CodedInputStream wrapping the given byte array.
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static CodedInputStream newInstance(final byte[] buf) {
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return newInstance(buf, 0, buf.length);
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Create a new CodedInputStream wrapping the given byte array slice.
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static CodedInputStream newInstance(final byte[] buf, final int off,
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                             final int len) {
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return new CodedInputStream(buf, off, len);
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // -----------------------------------------------------------------
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Attempt to read a field tag, returning zero if we have reached EOF.
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Protocol message parsers use this to read tags, since a protocol message
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * may legally end wherever a tag occurs, and zero is not a valid tag number.
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int readTag() throws IOException {
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (isAtEnd()) {
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      lastTag = 0;
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 0;
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    lastTag = readRawVarint32();
87d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    if (WireFormat.getTagFieldNumber(lastTag) == 0) {
88d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      // If we actually read zero (or any tag number corresponding to field
89d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      // number zero), that's not a valid tag.
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw InvalidProtocolBufferException.invalidTag();
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return lastTag;
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Verifies that the last call to readTag() returned the given tag value.
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * This is used to verify that a nested group ended with the correct
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * end tag.
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @throws InvalidProtocolBufferException {@code value} does not match the
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *                                        last tag.
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void checkLastTagWas(final int value)
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                              throws InvalidProtocolBufferException {
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (lastTag != value) {
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw InvalidProtocolBufferException.invalidEndTag();
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Reads and discards a single field, given its tag value.
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @return {@code false} if the tag is an endgroup tag, in which case
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *         nothing is skipped.  Otherwise, returns {@code true}.
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public boolean skipField(final int tag) throws IOException {
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    switch (WireFormat.getTagWireType(tag)) {
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case WireFormat.WIRETYPE_VARINT:
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        readInt32();
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return true;
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case WireFormat.WIRETYPE_FIXED64:
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        readRawLittleEndian64();
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return true;
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case WireFormat.WIRETYPE_LENGTH_DELIMITED:
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        skipRawBytes(readRawVarint32());
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return true;
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case WireFormat.WIRETYPE_START_GROUP:
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        skipMessage();
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        checkLastTagWas(
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          WireFormat.makeTag(WireFormat.getTagFieldNumber(tag),
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                             WireFormat.WIRETYPE_END_GROUP));
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return true;
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case WireFormat.WIRETYPE_END_GROUP:
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return false;
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      case WireFormat.WIRETYPE_FIXED32:
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        readRawLittleEndian32();
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return true;
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      default:
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw InvalidProtocolBufferException.invalidWireType();
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Reads and discards an entire message.  This will read either until EOF
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * or until an endgroup tag, whichever comes first.
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void skipMessage() throws IOException {
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    while (true) {
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final int tag = readTag();
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (tag == 0 || !skipField(tag)) {
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return;
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // -----------------------------------------------------------------
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a {@code double} field value from the stream. */
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public double readDouble() throws IOException {
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return Double.longBitsToDouble(readRawLittleEndian64());
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a {@code float} field value from the stream. */
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public float readFloat() throws IOException {
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return Float.intBitsToFloat(readRawLittleEndian32());
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a {@code uint64} field value from the stream. */
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public long readUInt64() throws IOException {
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return readRawVarint64();
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read an {@code int64} field value from the stream. */
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public long readInt64() throws IOException {
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return readRawVarint64();
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read an {@code int32} field value from the stream. */
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int readInt32() throws IOException {
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return readRawVarint32();
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a {@code fixed64} field value from the stream. */
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public long readFixed64() throws IOException {
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return readRawLittleEndian64();
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a {@code fixed32} field value from the stream. */
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int readFixed32() throws IOException {
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return readRawLittleEndian32();
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a {@code bool} field value from the stream. */
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public boolean readBool() throws IOException {
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return readRawVarint32() != 0;
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a {@code string} field value from the stream. */
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public String readString() throws IOException {
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int size = readRawVarint32();
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (size <= (bufferSize - bufferPos) && size > 0) {
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Fast path:  We already have the bytes in a contiguous buffer, so
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      //   just copy directly from it.
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final String result = new String(buffer, bufferPos, size, "UTF-8");
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferPos += size;
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return result;
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Slow path:  Build a byte array first then copy it.
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return new String(readRawBytes(size), "UTF-8");
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a {@code group} field value from the stream. */
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void readGroup(final int fieldNumber,
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                        final MessageLite.Builder builder,
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                        final ExtensionRegistryLite extensionRegistry)
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throws IOException {
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (recursionDepth >= recursionLimit) {
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw InvalidProtocolBufferException.recursionLimitExceeded();
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    ++recursionDepth;
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    builder.mergeFrom(this, extensionRegistry);
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    checkLastTagWas(
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    --recursionDepth;
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Reads a {@code group} field value from the stream and merges it into the
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * given {@link UnknownFieldSet}.
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @deprecated UnknownFieldSet.Builder now implements MessageLite.Builder, so
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *             you can just call {@link #readGroup}.
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  @Deprecated
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void readUnknownGroup(final int fieldNumber,
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                               final MessageLite.Builder builder)
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throws IOException {
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We know that UnknownFieldSet will ignore any ExtensionRegistry so it
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // is safe to pass null here.  (We can't call
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // ExtensionRegistry.getEmptyRegistry() because that would make this
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // class depend on ExtensionRegistry, which is not part of the lite
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // library.)
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    readGroup(fieldNumber, builder, null);
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read an embedded message field value from the stream. */
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void readMessage(final MessageLite.Builder builder,
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                          final ExtensionRegistryLite extensionRegistry)
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throws IOException {
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int length = readRawVarint32();
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (recursionDepth >= recursionLimit) {
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw InvalidProtocolBufferException.recursionLimitExceeded();
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int oldLimit = pushLimit(length);
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    ++recursionDepth;
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    builder.mergeFrom(this, extensionRegistry);
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    checkLastTagWas(0);
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    --recursionDepth;
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    popLimit(oldLimit);
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a {@code bytes} field value from the stream. */
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public ByteString readBytes() throws IOException {
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int size = readRawVarint32();
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (size <= (bufferSize - bufferPos) && size > 0) {
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Fast path:  We already have the bytes in a contiguous buffer, so
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      //   just copy directly from it.
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final ByteString result = ByteString.copyFrom(buffer, bufferPos, size);
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferPos += size;
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return result;
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Slow path:  Build a byte array first then copy it.
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return ByteString.copyFrom(readRawBytes(size));
275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a {@code uint32} field value from the stream. */
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int readUInt32() throws IOException {
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return readRawVarint32();
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Read an enum field value from the stream.  Caller is responsible
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * for converting the numeric value to an actual enum.
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int readEnum() throws IOException {
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return readRawVarint32();
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read an {@code sfixed32} field value from the stream. */
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int readSFixed32() throws IOException {
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return readRawLittleEndian32();
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read an {@code sfixed64} field value from the stream. */
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public long readSFixed64() throws IOException {
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return readRawLittleEndian64();
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read an {@code sint32} field value from the stream. */
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int readSInt32() throws IOException {
303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return decodeZigZag32(readRawVarint32());
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read an {@code sint64} field value from the stream. */
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public long readSInt64() throws IOException {
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return decodeZigZag64(readRawVarint64());
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // =================================================================
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Read a raw Varint from the stream.  If larger than 32 bits, discard the
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * upper bits.
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int readRawVarint32() throws IOException {
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    byte tmp = readRawByte();
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (tmp >= 0) {
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return tmp;
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int result = tmp & 0x7f;
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if ((tmp = readRawByte()) >= 0) {
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result |= tmp << 7;
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result |= (tmp & 0x7f) << 7;
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if ((tmp = readRawByte()) >= 0) {
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        result |= tmp << 14;
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        result |= (tmp & 0x7f) << 14;
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if ((tmp = readRawByte()) >= 0) {
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          result |= tmp << 21;
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        } else {
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          result |= (tmp & 0x7f) << 21;
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          result |= (tmp = readRawByte()) << 28;
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          if (tmp < 0) {
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            // Discard upper 32 bits.
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            for (int i = 0; i < 5; i++) {
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville              if (readRawByte() >= 0) {
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                return result;
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville              }
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            }
343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            throw InvalidProtocolBufferException.malformedVarint();
344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          }
345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return result;
349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Reads a varint from the input one byte at a time, so that it does not
353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * read any bytes after the end of the varint.  If you simply wrapped the
354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * stream in a CodedInputStream and used {@link #readRawVarint32(InputStream)}
355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * then you would probably end up reading past the end of the varint since
356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * CodedInputStream buffers its input.
357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  static int readRawVarint32(final InputStream input) throws IOException {
359d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    final int firstByte = input.read();
360d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    if (firstByte == -1) {
361d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      throw InvalidProtocolBufferException.truncatedMessage();
362d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
363d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return readRawVarint32(firstByte, input);
364d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
365d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
366d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  /**
367d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * Like {@link #readRawVarint32(InputStream)}, but expects that the caller
368d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * has already read one byte.  This allows the caller to determine if EOF
369d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * has been reached before attempting to read.
370d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   */
371d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  static int readRawVarint32(final int firstByte,
372d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                             final InputStream input) throws IOException {
373d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    if ((firstByte & 0x80) == 0) {
374d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      return firstByte;
375d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
376d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
377d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    int result = firstByte & 0x7f;
378d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    int offset = 7;
379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (; offset < 32; offset += 7) {
380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final int b = input.read();
381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (b == -1) {
382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw InvalidProtocolBufferException.truncatedMessage();
383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result |= (b & 0x7f) << offset;
385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if ((b & 0x80) == 0) {
386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return result;
387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Keep reading up to 64 bits.
390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (; offset < 64; offset += 7) {
391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final int b = input.read();
392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (b == -1) {
393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw InvalidProtocolBufferException.truncatedMessage();
394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if ((b & 0x80) == 0) {
396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return result;
397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    throw InvalidProtocolBufferException.malformedVarint();
400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a raw Varint from the stream. */
403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public long readRawVarint64() throws IOException {
404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int shift = 0;
405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    long result = 0;
406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    while (shift < 64) {
407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final byte b = readRawByte();
408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result |= (long)(b & 0x7F) << shift;
409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if ((b & 0x80) == 0) {
410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return result;
411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      shift += 7;
413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    throw InvalidProtocolBufferException.malformedVarint();
415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a 32-bit little-endian integer from the stream. */
418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int readRawLittleEndian32() throws IOException {
419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b1 = readRawByte();
420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b2 = readRawByte();
421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b3 = readRawByte();
422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b4 = readRawByte();
423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return (((int)b1 & 0xff)      ) |
424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (((int)b2 & 0xff) <<  8) |
425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (((int)b3 & 0xff) << 16) |
426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (((int)b4 & 0xff) << 24);
427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** Read a 64-bit little-endian integer from the stream. */
430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public long readRawLittleEndian64() throws IOException {
431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b1 = readRawByte();
432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b2 = readRawByte();
433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b3 = readRawByte();
434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b4 = readRawByte();
435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b5 = readRawByte();
436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b6 = readRawByte();
437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b7 = readRawByte();
438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final byte b8 = readRawByte();
439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return (((long)b1 & 0xff)      ) |
440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (((long)b2 & 0xff) <<  8) |
441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (((long)b3 & 0xff) << 16) |
442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (((long)b4 & 0xff) << 24) |
443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (((long)b5 & 0xff) << 32) |
444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (((long)b6 & 0xff) << 40) |
445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (((long)b7 & 0xff) << 48) |
446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (((long)b8 & 0xff) << 56);
447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Decode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * into values that can be efficiently encoded with varint.  (Otherwise,
452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * negative values must be sign-extended to 64 bits to be varint encoded,
453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * thus always taking 10 bytes on the wire.)
454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @param n An unsigned 32-bit integer, stored in a signed int because
456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *          Java has no explicit unsigned support.
457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @return A signed 32-bit integer.
458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static int decodeZigZag32(final int n) {
460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return (n >>> 1) ^ -(n & 1);
461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Decode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * into values that can be efficiently encoded with varint.  (Otherwise,
466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * negative values must be sign-extended to 64 bits to be varint encoded,
467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * thus always taking 10 bytes on the wire.)
468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @param n An unsigned 64-bit integer, stored in a signed int because
470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *          Java has no explicit unsigned support.
471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @return A signed 64-bit integer.
472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public static long decodeZigZag64(final long n) {
474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return (n >>> 1) ^ -(n & 1);
475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // -----------------------------------------------------------------
478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private final byte[] buffer;
480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private int bufferSize;
481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private int bufferSizeAfterLimit;
482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private int bufferPos;
483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private final InputStream input;
484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private int lastTag;
485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * The total number of bytes read before the current buffer.  The total
488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * bytes read up to the current position can be computed as
489d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * {@code totalBytesRetired + bufferPos}.  This value may be negative if
490d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * reading started in the middle of the current buffer (e.g. if the
491d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * constructor that takes a byte array and an offset was used).
492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private int totalBytesRetired;
494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** The absolute position of the end of the current message. */
496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private int currentLimit = Integer.MAX_VALUE;
497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** See setRecursionLimit() */
499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private int recursionDepth;
500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private int recursionLimit = DEFAULT_RECURSION_LIMIT;
501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /** See setSizeLimit() */
503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private int sizeLimit = DEFAULT_SIZE_LIMIT;
504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private static final int DEFAULT_RECURSION_LIMIT = 64;
506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private static final int DEFAULT_SIZE_LIMIT = 64 << 20;  // 64MB
507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private static final int BUFFER_SIZE = 4096;
508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private CodedInputStream(final byte[] buffer, final int off, final int len) {
510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    this.buffer = buffer;
511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bufferSize = off + len;
512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bufferPos = off;
513d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    totalBytesRetired = -off;
514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input = null;
515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private CodedInputStream(final InputStream input) {
518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer = new byte[BUFFER_SIZE];
519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bufferSize = 0;
520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bufferPos = 0;
521d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    totalBytesRetired = 0;
522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    this.input = input;
523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Set the maximum message recursion depth.  In order to prevent malicious
527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * messages from causing stack overflows, {@code CodedInputStream} limits
528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * how deeply messages may be nested.  The default limit is 64.
529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @return the old limit.
531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int setRecursionLimit(final int limit) {
533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (limit < 0) {
534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw new IllegalArgumentException(
535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "Recursion limit cannot be negative: " + limit);
536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int oldLimit = recursionLimit;
538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    recursionLimit = limit;
539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return oldLimit;
540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Set the maximum message size.  In order to prevent malicious
544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * messages from exhausting memory or causing integer overflows,
545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * {@code CodedInputStream} limits how large a message may be.
546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * The default limit is 64MB.  You should set this limit as small
547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * as you can without harming your app's functionality.  Note that
548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * size limits only apply when reading from an {@code InputStream}, not
549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * when constructed around a raw byte array (nor with
550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * {@link ByteString#newCodedInput}).
551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * <p>
552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * If you want to read several messages from a single CodedInputStream, you
553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * could call {@link #resetSizeCounter()} after each one to avoid hitting the
554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * size limit.
555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @return the old limit.
557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int setSizeLimit(final int limit) {
559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (limit < 0) {
560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw new IllegalArgumentException(
561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "Size limit cannot be negative: " + limit);
562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int oldLimit = sizeLimit;
564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sizeLimit = limit;
565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return oldLimit;
566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Resets the current size counter to zero (see {@link #setSizeLimit(int)}).
570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void resetSizeCounter() {
572d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    totalBytesRetired = -bufferPos;
573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Sets {@code currentLimit} to (current position) + {@code byteLimit}.  This
577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * is called when descending into a length-delimited embedded message.
578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
579d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * <p>Note that {@code pushLimit()} does NOT affect how many bytes the
580d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * {@code CodedInputStream} reads from an underlying {@code InputStream} when
581d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * refreshing its buffer.  If you need to prevent reading past a certain
582d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * point in the underlying {@code InputStream} (e.g. because you expect it to
583d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * contain more data after the end of the message which you need to handle
584d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * differently) then you must place a wrapper around you {@code InputStream}
585d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * which limits the amount of data that can be read from it.
586d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   *
587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @return the old limit.
588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (byteLimit < 0) {
591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw InvalidProtocolBufferException.negativeSize();
592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    byteLimit += totalBytesRetired + bufferPos;
594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int oldLimit = currentLimit;
595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (byteLimit > oldLimit) {
596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw InvalidProtocolBufferException.truncatedMessage();
597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    currentLimit = byteLimit;
599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    recomputeBufferSizeAfterLimit();
601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return oldLimit;
603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private void recomputeBufferSizeAfterLimit() {
606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bufferSize += bufferSizeAfterLimit;
607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int bufferEnd = totalBytesRetired + bufferSize;
608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (bufferEnd > currentLimit) {
609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Limit is in current buffer.
610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferSizeAfterLimit = bufferEnd - currentLimit;
611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferSize -= bufferSizeAfterLimit;
612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferSizeAfterLimit = 0;
614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Discards the current limit, returning to the previous limit.
619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @param oldLimit The old limit, as returned by {@code pushLimit}.
621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void popLimit(final int oldLimit) {
623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    currentLimit = oldLimit;
624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    recomputeBufferSizeAfterLimit();
625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Returns the number of bytes to be read before the current limit.
629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * If no limit is set, returns -1.
630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public int getBytesUntilLimit() {
632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (currentLimit == Integer.MAX_VALUE) {
633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return -1;
634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    final int currentAbsolutePosition = totalBytesRetired + bufferPos;
637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return currentLimit - currentAbsolutePosition;
638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Returns true if the stream has reached the end of the input.  This is the
642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * case if either the end of the underlying input source has been reached or
643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * if the stream has reached a limit created using {@link #pushLimit(int)}.
644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public boolean isAtEnd() throws IOException {
646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return bufferPos == bufferSize && !refillBuffer(false);
647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
648d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
649d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  /**
650d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * The total bytes read up to the current position. Calling
651d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   * {@link #resetSizeCounter()} resets this value to zero.
652d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville   */
653d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  public int getTotalBytesRead() {
654d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      return totalBytesRetired + bufferPos;
655d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Called with {@code this.buffer} is empty to read more bytes from the
659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * input.  If {@code mustSucceed} is true, refillBuffer() gurantees that
660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * either there will be at least one byte in the buffer when it returns
661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * or it will throw an exception.  If {@code mustSucceed} is false,
662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * refillBuffer() returns false if no more bytes were available.
663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  private boolean refillBuffer(final boolean mustSucceed) throws IOException {
665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (bufferPos < bufferSize) {
666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw new IllegalStateException(
667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "refillBuffer() called when buffer wasn't empty.");
668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (totalBytesRetired + bufferSize == currentLimit) {
671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Oops, we hit a limit.
672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (mustSucceed) {
673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw InvalidProtocolBufferException.truncatedMessage();
674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return false;
676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    totalBytesRetired += bufferSize;
680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bufferPos = 0;
682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bufferSize = (input == null) ? -1 : input.read(buffer);
683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (bufferSize == 0 || bufferSize < -1) {
684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw new IllegalStateException(
685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "InputStream#read(byte[]) returned invalid result: " + bufferSize +
686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "\nThe InputStream implementation is buggy.");
687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (bufferSize == -1) {
689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferSize = 0;
690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (mustSucceed) {
691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw InvalidProtocolBufferException.truncatedMessage();
692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return false;
694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      recomputeBufferSizeAfterLimit();
697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final int totalBytesRead =
698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        totalBytesRetired + bufferSize + bufferSizeAfterLimit;
699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (totalBytesRead > sizeLimit || totalBytesRead < 0) {
700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        throw InvalidProtocolBufferException.sizeLimitExceeded();
701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return true;
703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Read one byte from the input.
708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @throws InvalidProtocolBufferException The end of the stream or the current
710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *                                        limit was reached.
711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public byte readRawByte() throws IOException {
713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (bufferPos == bufferSize) {
714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      refillBuffer(true);
715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return buffer[bufferPos++];
717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Read a fixed size of bytes from the input.
721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @throws InvalidProtocolBufferException The end of the stream or the current
723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *                                        limit was reached.
724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public byte[] readRawBytes(final int size) throws IOException {
726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (size < 0) {
727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw InvalidProtocolBufferException.negativeSize();
728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (totalBytesRetired + bufferPos + size > currentLimit) {
731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Read to the end of the stream anyway.
732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Then fail.
734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw InvalidProtocolBufferException.truncatedMessage();
735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (size <= bufferSize - bufferPos) {
738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // We have all the bytes we need already.
739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final byte[] bytes = new byte[size];
740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      System.arraycopy(buffer, bufferPos, bytes, 0, size);
741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferPos += size;
742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return bytes;
743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (size < BUFFER_SIZE) {
744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Reading more bytes than are in the buffer, but not an excessive number
745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // of bytes.  We can safely allocate the resulting array ahead of time.
746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // First copy what we have.
748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final byte[] bytes = new byte[size];
749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      int pos = bufferSize - bufferPos;
750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      System.arraycopy(buffer, bufferPos, bytes, 0, pos);
751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferPos = bufferSize;
752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // We want to use refillBuffer() and then copy from the buffer into our
754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // byte array rather than reading directly into our byte array because
755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // the input may be unbuffered.
756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      refillBuffer(true);
757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      while (size - pos > bufferSize) {
759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        System.arraycopy(buffer, 0, bytes, pos, bufferSize);
760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        pos += bufferSize;
761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        bufferPos = bufferSize;
762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        refillBuffer(true);
763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      System.arraycopy(buffer, 0, bytes, pos, size - pos);
766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferPos = size - pos;
767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return bytes;
769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // The size is very large.  For security reasons, we can't allocate the
771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // entire byte array yet.  The size comes directly from the input, so a
772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // maliciously-crafted message could provide a bogus very large size in
773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // order to trick the app into allocating a lot of memory.  We avoid this
774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // by allocating and reading only a small chunk at a time, so that the
775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // malicious message must actually *be* extremely large to cause
776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Remember the buffer markers since we'll have to copy the bytes out of
779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // it later.
780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final int originalBufferPos = bufferPos;
781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final int originalBufferSize = bufferSize;
782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Mark the current buffer consumed.
784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      totalBytesRetired += bufferSize;
785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferPos = 0;
786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferSize = 0;
787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Read all the rest of the bytes we need.
789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      int sizeLeft = size - (originalBufferSize - originalBufferPos);
790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final List<byte[]> chunks = new ArrayList<byte[]>();
791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      while (sizeLeft > 0) {
793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)];
794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        int pos = 0;
795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        while (pos < chunk.length) {
796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          final int n = (input == null) ? -1 :
797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            input.read(chunk, pos, chunk.length - pos);
798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          if (n == -1) {
799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            throw InvalidProtocolBufferException.truncatedMessage();
800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          }
801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          totalBytesRetired += n;
802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          pos += n;
803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        sizeLeft -= chunk.length;
805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        chunks.add(chunk);
806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // OK, got everything.  Now concatenate it all into one buffer.
809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      final byte[] bytes = new byte[size];
810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Start by copying the leftover bytes from this.buffer.
812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      int pos = originalBufferSize - originalBufferPos;
813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      System.arraycopy(buffer, originalBufferPos, bytes, 0, pos);
814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // And now all the chunks.
816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      for (final byte[] chunk : chunks) {
817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        System.arraycopy(chunk, 0, bytes, pos, chunk.length);
818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        pos += chunk.length;
819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Done.
822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return bytes;
823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  /**
827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * Reads and discards {@code size} bytes.
828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *
829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   * @throws InvalidProtocolBufferException The end of the stream or the current
830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   *                                        limit was reached.
831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   */
832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  public void skipRawBytes(final int size) throws IOException {
833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (size < 0) {
834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw InvalidProtocolBufferException.negativeSize();
835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (totalBytesRetired + bufferPos + size > currentLimit) {
838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Read to the end of the stream anyway.
839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Then fail.
841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      throw InvalidProtocolBufferException.truncatedMessage();
842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (size <= bufferSize - bufferPos) {
845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // We have all the bytes we need already.
846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferPos += size;
847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Skipping more bytes than are in the buffer.  First skip what we have.
849fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      int pos = bufferSize - bufferPos;
8508a2f7578bb6289415f1d0a01c9cc96d283730480Wink Saville      totalBytesRetired += bufferSize;
851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferPos = 0;
852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bufferSize = 0;
853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Then skip directly from the InputStream for the rest.
855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      while (pos < size) {
856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        final int n = (input == null) ? -1 : (int) input.skip(size - pos);
857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (n <= 0) {
858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          throw InvalidProtocolBufferException.truncatedMessage();
859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        pos += n;
861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        totalBytesRetired += n;
862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
866