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