diff options
Diffstat (limited to 'java/src/main/java/com/google/protobuf/CodedInputStream.java')
-rw-r--r-- | java/src/main/java/com/google/protobuf/CodedInputStream.java | 224 |
1 files changed, 95 insertions, 129 deletions
diff --git a/java/src/main/java/com/google/protobuf/CodedInputStream.java b/java/src/main/java/com/google/protobuf/CodedInputStream.java index b6be2e87..9125957d 100644 --- a/java/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/src/main/java/com/google/protobuf/CodedInputStream.java @@ -51,21 +51,22 @@ public final class CodedInputStream { /** * Create a new CodedInputStream wrapping the given InputStream. */ - public static CodedInputStream newInstance(InputStream input) { + public static CodedInputStream newInstance(final InputStream input) { return new CodedInputStream(input); } /** * Create a new CodedInputStream wrapping the given byte array. */ - public static CodedInputStream newInstance(byte[] buf) { + public static CodedInputStream newInstance(final byte[] buf) { return newInstance(buf, 0, buf.length); } /** * Create a new CodedInputStream wrapping the given byte array slice. */ - public static CodedInputStream newInstance(byte[] buf, int off, int len) { + public static CodedInputStream newInstance(final byte[] buf, final int off, + final int len) { return new CodedInputStream(buf, off, len); } @@ -98,7 +99,8 @@ public final class CodedInputStream { * @throws InvalidProtocolBufferException {@code value} does not match the * last tag. */ - public void checkLastTagWas(int value) throws InvalidProtocolBufferException { + public void checkLastTagWas(final int value) + throws InvalidProtocolBufferException { if (lastTag != value) { throw InvalidProtocolBufferException.invalidEndTag(); } @@ -110,7 +112,7 @@ public final class CodedInputStream { * @return {@code false} if the tag is an endgroup tag, in which case * nothing is skipped. Otherwise, returns {@code true}. */ - public boolean skipField(int tag) throws IOException { + public boolean skipField(final int tag) throws IOException { switch (WireFormat.getTagWireType(tag)) { case WireFormat.WIRETYPE_VARINT: readInt32(); @@ -143,8 +145,10 @@ public final class CodedInputStream { */ public void skipMessage() throws IOException { while (true) { - int tag = readTag(); - if (tag == 0 || !skipField(tag)) return; + final int tag = readTag(); + if (tag == 0 || !skipField(tag)) { + return; + } } } @@ -192,11 +196,11 @@ public final class CodedInputStream { /** Read a {@code string} field value from the stream. */ public String readString() throws IOException { - int size = readRawVarint32(); + final int size = readRawVarint32(); if (size <= (bufferSize - bufferPos) && size > 0) { // Fast path: We already have the bytes in a contiguous buffer, so // just copy directly from it. - String result = new String(buffer, bufferPos, size, "UTF-8"); + final String result = new String(buffer, bufferPos, size, "UTF-8"); bufferPos += size; return result; } else { @@ -206,8 +210,9 @@ public final class CodedInputStream { } /** Read a {@code group} field value from the stream. */ - public void readGroup(int fieldNumber, Message.Builder builder, - ExtensionRegistry extensionRegistry) + public void readGroup(final int fieldNumber, + final MessageLite.Builder builder, + final ExtensionRegistryLite extensionRegistry) throws IOException { if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.recursionLimitExceeded(); @@ -222,28 +227,31 @@ public final class CodedInputStream { /** * Reads a {@code group} field value from the stream and merges it into the * given {@link UnknownFieldSet}. + * + * @deprecated UnknownFieldSet.Builder now implements MessageLite.Builder, so + * you can just call {@link #readGroup}. */ - public void readUnknownGroup(int fieldNumber, UnknownFieldSet.Builder builder) + @Deprecated + public void readUnknownGroup(final int fieldNumber, + final MessageLite.Builder builder) throws IOException { - if (recursionDepth >= recursionLimit) { - throw InvalidProtocolBufferException.recursionLimitExceeded(); - } - ++recursionDepth; - builder.mergeFrom(this); - checkLastTagWas( - WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP)); - --recursionDepth; + // We know that UnknownFieldSet will ignore any ExtensionRegistry so it + // is safe to pass null here. (We can't call + // ExtensionRegistry.getEmptyRegistry() because that would make this + // class depend on ExtensionRegistry, which is not part of the lite + // library.) + readGroup(fieldNumber, builder, null); } /** Read an embedded message field value from the stream. */ - public void readMessage(Message.Builder builder, - ExtensionRegistry extensionRegistry) + public void readMessage(final MessageLite.Builder builder, + final ExtensionRegistryLite extensionRegistry) throws IOException { - int length = readRawVarint32(); + final int length = readRawVarint32(); if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.recursionLimitExceeded(); } - int oldLimit = pushLimit(length); + final int oldLimit = pushLimit(length); ++recursionDepth; builder.mergeFrom(this, extensionRegistry); checkLastTagWas(0); @@ -253,11 +261,11 @@ public final class CodedInputStream { /** Read a {@code bytes} field value from the stream. */ public ByteString readBytes() throws IOException { - int size = readRawVarint32(); - if (size < bufferSize - bufferPos && size > 0) { + final int size = readRawVarint32(); + if (size <= (bufferSize - bufferPos) && size > 0) { // Fast path: We already have the bytes in a contiguous buffer, so // just copy directly from it. - ByteString result = ByteString.copyFrom(buffer, bufferPos, size); + final ByteString result = ByteString.copyFrom(buffer, bufferPos, size); bufferPos += size; return result; } else { @@ -299,52 +307,6 @@ public final class CodedInputStream { return decodeZigZag64(readRawVarint64()); } - /** - * Read a field of any primitive type. Enums, groups, and embedded - * messages are not handled by this method. - * - * @param type Declared type of the field. - * @return An object representing the field's value, of the exact - * type which would be returned by - * {@link Message#getField(Descriptors.FieldDescriptor)} for - * this field. - */ - public Object readPrimitiveField( - Descriptors.FieldDescriptor.Type type) throws IOException { - switch (type) { - case DOUBLE : return readDouble (); - case FLOAT : return readFloat (); - case INT64 : return readInt64 (); - case UINT64 : return readUInt64 (); - case INT32 : return readInt32 (); - case FIXED64 : return readFixed64 (); - case FIXED32 : return readFixed32 (); - case BOOL : return readBool (); - case STRING : return readString (); - case BYTES : return readBytes (); - case UINT32 : return readUInt32 (); - case SFIXED32: return readSFixed32(); - case SFIXED64: return readSFixed64(); - case SINT32 : return readSInt32 (); - case SINT64 : return readSInt64 (); - - case GROUP: - throw new IllegalArgumentException( - "readPrimitiveField() cannot handle nested groups."); - case MESSAGE: - throw new IllegalArgumentException( - "readPrimitiveField() cannot handle embedded messages."); - case ENUM: - // We don't hanlde enums because we don't know what to do if the - // value is not recognized. - throw new IllegalArgumentException( - "readPrimitiveField() cannot handle enums."); - } - - throw new RuntimeException( - "There is no way to get here, but the compiler thinks otherwise."); - } - // ================================================================= /** @@ -373,7 +335,9 @@ public final class CodedInputStream { if (tmp < 0) { // Discard upper 32 bits. for (int i = 0; i < 5; i++) { - if (readRawByte() >= 0) return result; + if (readRawByte() >= 0) { + return result; + } } throw InvalidProtocolBufferException.malformedVarint(); } @@ -390,11 +354,11 @@ public final class CodedInputStream { * then you would probably end up reading past the end of the varint since * CodedInputStream buffers its input. */ - static int readRawVarint32(InputStream input) throws IOException { + static int readRawVarint32(final InputStream input) throws IOException { int result = 0; int offset = 0; for (; offset < 32; offset += 7) { - int b = input.read(); + final int b = input.read(); if (b == -1) { throw InvalidProtocolBufferException.truncatedMessage(); } @@ -405,7 +369,7 @@ public final class CodedInputStream { } // Keep reading up to 64 bits. for (; offset < 64; offset += 7) { - int b = input.read(); + final int b = input.read(); if (b == -1) { throw InvalidProtocolBufferException.truncatedMessage(); } @@ -421,9 +385,11 @@ public final class CodedInputStream { int shift = 0; long result = 0; while (shift < 64) { - byte b = readRawByte(); + final byte b = readRawByte(); result |= (long)(b & 0x7F) << shift; - if ((b & 0x80) == 0) return result; + if ((b & 0x80) == 0) { + return result; + } shift += 7; } throw InvalidProtocolBufferException.malformedVarint(); @@ -431,10 +397,10 @@ public final class CodedInputStream { /** Read a 32-bit little-endian integer from the stream. */ public int readRawLittleEndian32() throws IOException { - byte b1 = readRawByte(); - byte b2 = readRawByte(); - byte b3 = readRawByte(); - byte b4 = readRawByte(); + final byte b1 = readRawByte(); + final byte b2 = readRawByte(); + final byte b3 = readRawByte(); + final byte b4 = readRawByte(); return (((int)b1 & 0xff) ) | (((int)b2 & 0xff) << 8) | (((int)b3 & 0xff) << 16) | @@ -443,14 +409,14 @@ public final class CodedInputStream { /** Read a 64-bit little-endian integer from the stream. */ public long readRawLittleEndian64() throws IOException { - byte b1 = readRawByte(); - byte b2 = readRawByte(); - byte b3 = readRawByte(); - byte b4 = readRawByte(); - byte b5 = readRawByte(); - byte b6 = readRawByte(); - byte b7 = readRawByte(); - byte b8 = readRawByte(); + final byte b1 = readRawByte(); + final byte b2 = readRawByte(); + final byte b3 = readRawByte(); + final byte b4 = readRawByte(); + final byte b5 = readRawByte(); + final byte b6 = readRawByte(); + final byte b7 = readRawByte(); + final byte b8 = readRawByte(); return (((long)b1 & 0xff) ) | (((long)b2 & 0xff) << 8) | (((long)b3 & 0xff) << 16) | @@ -471,7 +437,7 @@ public final class CodedInputStream { * Java has no explicit unsigned support. * @return A signed 32-bit integer. */ - public static int decodeZigZag32(int n) { + public static int decodeZigZag32(final int n) { return (n >>> 1) ^ -(n & 1); } @@ -485,31 +451,31 @@ public final class CodedInputStream { * Java has no explicit unsigned support. * @return A signed 64-bit integer. */ - public static long decodeZigZag64(long n) { + public static long decodeZigZag64(final long n) { return (n >>> 1) ^ -(n & 1); } // ----------------------------------------------------------------- - private byte[] buffer; + private final byte[] buffer; private int bufferSize; - private int bufferSizeAfterLimit = 0; + private int bufferSizeAfterLimit; private int bufferPos; - private InputStream input; - private int lastTag = 0; + private final InputStream input; + private int lastTag; /** * The total number of bytes read before the current buffer. The total * bytes read up to the current position can be computed as * {@code totalBytesRetired + bufferPos}. */ - private int totalBytesRetired = 0; + private int totalBytesRetired; /** The absolute position of the end of the current message. */ private int currentLimit = Integer.MAX_VALUE; /** See setRecursionLimit() */ - private int recursionDepth = 0; + private int recursionDepth; private int recursionLimit = DEFAULT_RECURSION_LIMIT; /** See setSizeLimit() */ @@ -519,17 +485,17 @@ public final class CodedInputStream { private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB private static final int BUFFER_SIZE = 4096; - private CodedInputStream(byte[] buffer, int off, int len) { + private CodedInputStream(final byte[] buffer, final int off, final int len) { this.buffer = buffer; - this.bufferSize = off + len; - this.bufferPos = off; - this.input = null; + bufferSize = off + len; + bufferPos = off; + input = null; } - private CodedInputStream(InputStream input) { - this.buffer = new byte[BUFFER_SIZE]; - this.bufferSize = 0; - this.bufferPos = 0; + private CodedInputStream(final InputStream input) { + buffer = new byte[BUFFER_SIZE]; + bufferSize = 0; + bufferPos = 0; this.input = input; } @@ -540,12 +506,12 @@ public final class CodedInputStream { * * @return the old limit. */ - public int setRecursionLimit(int limit) { + public int setRecursionLimit(final int limit) { if (limit < 0) { throw new IllegalArgumentException( "Recursion limit cannot be negative: " + limit); } - int oldLimit = recursionLimit; + final int oldLimit = recursionLimit; recursionLimit = limit; return oldLimit; } @@ -566,12 +532,12 @@ public final class CodedInputStream { * * @return the old limit. */ - public int setSizeLimit(int limit) { + public int setSizeLimit(final int limit) { if (limit < 0) { throw new IllegalArgumentException( "Size limit cannot be negative: " + limit); } - int oldLimit = sizeLimit; + final int oldLimit = sizeLimit; sizeLimit = limit; return oldLimit; } @@ -594,7 +560,7 @@ public final class CodedInputStream { throw InvalidProtocolBufferException.negativeSize(); } byteLimit += totalBytesRetired + bufferPos; - int oldLimit = currentLimit; + final int oldLimit = currentLimit; if (byteLimit > oldLimit) { throw InvalidProtocolBufferException.truncatedMessage(); } @@ -607,7 +573,7 @@ public final class CodedInputStream { private void recomputeBufferSizeAfterLimit() { bufferSize += bufferSizeAfterLimit; - int bufferEnd = totalBytesRetired + bufferSize; + final int bufferEnd = totalBytesRetired + bufferSize; if (bufferEnd > currentLimit) { // Limit is in current buffer. bufferSizeAfterLimit = bufferEnd - currentLimit; @@ -622,7 +588,7 @@ public final class CodedInputStream { * * @param oldLimit The old limit, as returned by {@code pushLimit}. */ - public void popLimit(int oldLimit) { + public void popLimit(final int oldLimit) { currentLimit = oldLimit; recomputeBufferSizeAfterLimit(); } @@ -636,7 +602,7 @@ public final class CodedInputStream { return -1; } - int currentAbsolutePosition = totalBytesRetired + bufferPos; + final int currentAbsolutePosition = totalBytesRetired + bufferPos; return currentLimit - currentAbsolutePosition; } @@ -656,7 +622,7 @@ public final class CodedInputStream { * or it will throw an exception. If {@code mustSucceed} is false, * refillBuffer() returns false if no more bytes were available. */ - private boolean refillBuffer(boolean mustSucceed) throws IOException { + private boolean refillBuffer(final boolean mustSucceed) throws IOException { if (bufferPos < bufferSize) { throw new IllegalStateException( "refillBuffer() called when buffer wasn't empty."); @@ -689,7 +655,7 @@ public final class CodedInputStream { } } else { recomputeBufferSizeAfterLimit(); - int totalBytesRead = + final int totalBytesRead = totalBytesRetired + bufferSize + bufferSizeAfterLimit; if (totalBytesRead > sizeLimit || totalBytesRead < 0) { throw InvalidProtocolBufferException.sizeLimitExceeded(); @@ -717,7 +683,7 @@ public final class CodedInputStream { * @throws InvalidProtocolBufferException The end of the stream or the current * limit was reached. */ - public byte[] readRawBytes(int size) throws IOException { + public byte[] readRawBytes(final int size) throws IOException { if (size < 0) { throw InvalidProtocolBufferException.negativeSize(); } @@ -731,7 +697,7 @@ public final class CodedInputStream { if (size <= bufferSize - bufferPos) { // We have all the bytes we need already. - byte[] bytes = new byte[size]; + final byte[] bytes = new byte[size]; System.arraycopy(buffer, bufferPos, bytes, 0, size); bufferPos += size; return bytes; @@ -740,7 +706,7 @@ public final class CodedInputStream { // of bytes. We can safely allocate the resulting array ahead of time. // First copy what we have. - byte[] bytes = new byte[size]; + final byte[] bytes = new byte[size]; int pos = bufferSize - bufferPos; System.arraycopy(buffer, bufferPos, bytes, 0, pos); bufferPos = bufferSize; @@ -772,8 +738,8 @@ public final class CodedInputStream { // Remember the buffer markers since we'll have to copy the bytes out of // it later. - int originalBufferPos = bufferPos; - int originalBufferSize = bufferSize; + final int originalBufferPos = bufferPos; + final int originalBufferSize = bufferSize; // Mark the current buffer consumed. totalBytesRetired += bufferSize; @@ -782,13 +748,13 @@ public final class CodedInputStream { // Read all the rest of the bytes we need. int sizeLeft = size - (originalBufferSize - originalBufferPos); - List<byte[]> chunks = new ArrayList<byte[]>(); + final List<byte[]> chunks = new ArrayList<byte[]>(); while (sizeLeft > 0) { - byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)]; + final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)]; int pos = 0; while (pos < chunk.length) { - int n = (input == null) ? -1 : + final int n = (input == null) ? -1 : input.read(chunk, pos, chunk.length - pos); if (n == -1) { throw InvalidProtocolBufferException.truncatedMessage(); @@ -801,14 +767,14 @@ public final class CodedInputStream { } // OK, got everything. Now concatenate it all into one buffer. - byte[] bytes = new byte[size]; + final byte[] bytes = new byte[size]; // Start by copying the leftover bytes from this.buffer. int pos = originalBufferSize - originalBufferPos; System.arraycopy(buffer, originalBufferPos, bytes, 0, pos); // And now all the chunks. - for (byte[] chunk : chunks) { + for (final byte[] chunk : chunks) { System.arraycopy(chunk, 0, bytes, pos, chunk.length); pos += chunk.length; } @@ -824,7 +790,7 @@ public final class CodedInputStream { * @throws InvalidProtocolBufferException The end of the stream or the current * limit was reached. */ - public void skipRawBytes(int size) throws IOException { + public void skipRawBytes(final int size) throws IOException { if (size < 0) { throw InvalidProtocolBufferException.negativeSize(); } @@ -848,7 +814,7 @@ public final class CodedInputStream { // Then skip directly from the InputStream for the rest. while (pos < size) { - int n = (input == null) ? -1 : (int) input.skip(size - pos); + final int n = (input == null) ? -1 : (int) input.skip(size - pos); if (n <= 0) { throw InvalidProtocolBufferException.truncatedMessage(); } |