aboutsummaryrefslogtreecommitdiffhomepage
path: root/javanano/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java
diff options
context:
space:
mode:
Diffstat (limited to 'javanano/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java')
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java683
1 files changed, 0 insertions, 683 deletions
diff --git a/javanano/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java b/javanano/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java
deleted file mode 100644
index f3993155..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java
+++ /dev/null
@@ -1,683 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2013 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf.nano;
-
-import java.io.IOException;
-
-/**
- * Reads and decodes protocol message fields.
- *
- * This class contains two kinds of methods: methods that read specific
- * protocol message constructs and field types (e.g. {@link #readTag()} and
- * {@link #readInt32()}) and methods that read low-level values (e.g.
- * {@link #readRawVarint32()} and {@link #readRawBytes}). If you are reading
- * encoded protocol messages, you should use the former methods, but if you are
- * reading some other format of your own design, use the latter.
- *
- * @author kenton@google.com Kenton Varda
- */
-public final class CodedInputByteBufferNano {
- /**
- * Create a new CodedInputStream wrapping the given byte array.
- */
- public static CodedInputByteBufferNano newInstance(final byte[] buf) {
- return newInstance(buf, 0, buf.length);
- }
-
- /**
- * Create a new CodedInputStream wrapping the given byte array slice.
- */
- public static CodedInputByteBufferNano newInstance(final byte[] buf, final int off,
- final int len) {
- return new CodedInputByteBufferNano(buf, off, len);
- }
-
- // -----------------------------------------------------------------
-
- /**
- * Attempt to read a field tag, returning zero if we have reached EOF.
- * Protocol message parsers use this to read tags, since a protocol message
- * may legally end wherever a tag occurs, and zero is not a valid tag number.
- */
- public int readTag() throws IOException {
- if (isAtEnd()) {
- lastTag = 0;
- return 0;
- }
-
- lastTag = readRawVarint32();
- if (lastTag == 0) {
- // If we actually read zero, that's not a valid tag.
- throw InvalidProtocolBufferNanoException.invalidTag();
- }
- return lastTag;
- }
-
- /**
- * Verifies that the last call to readTag() returned the given tag value.
- * This is used to verify that a nested group ended with the correct
- * end tag.
- *
- * @throws InvalidProtocolBufferNanoException {@code value} does not match the
- * last tag.
- */
- public void checkLastTagWas(final int value)
- throws InvalidProtocolBufferNanoException {
- if (lastTag != value) {
- throw InvalidProtocolBufferNanoException.invalidEndTag();
- }
- }
-
- /**
- * Reads and discards a single field, given its tag value.
- *
- * @return {@code false} if the tag is an endgroup tag, in which case
- * nothing is skipped. Otherwise, returns {@code true}.
- */
- public boolean skipField(final int tag) throws IOException {
- switch (WireFormatNano.getTagWireType(tag)) {
- case WireFormatNano.WIRETYPE_VARINT:
- readInt32();
- return true;
- case WireFormatNano.WIRETYPE_FIXED64:
- readRawLittleEndian64();
- return true;
- case WireFormatNano.WIRETYPE_LENGTH_DELIMITED:
- skipRawBytes(readRawVarint32());
- return true;
- case WireFormatNano.WIRETYPE_START_GROUP:
- skipMessage();
- checkLastTagWas(
- WireFormatNano.makeTag(WireFormatNano.getTagFieldNumber(tag),
- WireFormatNano.WIRETYPE_END_GROUP));
- return true;
- case WireFormatNano.WIRETYPE_END_GROUP:
- return false;
- case WireFormatNano.WIRETYPE_FIXED32:
- readRawLittleEndian32();
- return true;
- default:
- throw InvalidProtocolBufferNanoException.invalidWireType();
- }
- }
-
- /**
- * Reads and discards an entire message. This will read either until EOF
- * or until an endgroup tag, whichever comes first.
- */
- public void skipMessage() throws IOException {
- while (true) {
- final int tag = readTag();
- if (tag == 0 || !skipField(tag)) {
- return;
- }
- }
- }
-
- // -----------------------------------------------------------------
-
- /** Read a {@code double} field value from the stream. */
- public double readDouble() throws IOException {
- return Double.longBitsToDouble(readRawLittleEndian64());
- }
-
- /** Read a {@code float} field value from the stream. */
- public float readFloat() throws IOException {
- return Float.intBitsToFloat(readRawLittleEndian32());
- }
-
- /** Read a {@code uint64} field value from the stream. */
- public long readUInt64() throws IOException {
- return readRawVarint64();
- }
-
- /** Read an {@code int64} field value from the stream. */
- public long readInt64() throws IOException {
- return readRawVarint64();
- }
-
- /** Read an {@code int32} field value from the stream. */
- public int readInt32() throws IOException {
- return readRawVarint32();
- }
-
- /** Read a {@code fixed64} field value from the stream. */
- public long readFixed64() throws IOException {
- return readRawLittleEndian64();
- }
-
- /** Read a {@code fixed32} field value from the stream. */
- public int readFixed32() throws IOException {
- return readRawLittleEndian32();
- }
-
- /** Read a {@code bool} field value from the stream. */
- public boolean readBool() throws IOException {
- return readRawVarint32() != 0;
- }
-
- /** Read a {@code string} field value from the stream. */
- public String readString() throws IOException {
- 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.
- final String result = new String(buffer, bufferPos, size, InternalNano.UTF_8);
- bufferPos += size;
- return result;
- } else {
- // Slow path: Build a byte array first then copy it.
- return new String(readRawBytes(size), InternalNano.UTF_8);
- }
- }
-
- /** Read a {@code group} field value from the stream. */
- public void readGroup(final MessageNano msg, final int fieldNumber)
- throws IOException {
- if (recursionDepth >= recursionLimit) {
- throw InvalidProtocolBufferNanoException.recursionLimitExceeded();
- }
- ++recursionDepth;
- msg.mergeFrom(this);
- checkLastTagWas(
- WireFormatNano.makeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP));
- --recursionDepth;
- }
-
- public void readMessage(final MessageNano msg)
- throws IOException {
- final int length = readRawVarint32();
- if (recursionDepth >= recursionLimit) {
- throw InvalidProtocolBufferNanoException.recursionLimitExceeded();
- }
- final int oldLimit = pushLimit(length);
- ++recursionDepth;
- msg.mergeFrom(this);
- checkLastTagWas(0);
- --recursionDepth;
- popLimit(oldLimit);
- }
-
- /** Read a {@code bytes} field value from the stream. */
- public byte[] readBytes() throws IOException {
- 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.
- final byte[] result = new byte[size];
- System.arraycopy(buffer, bufferPos, result, 0, size);
- bufferPos += size;
- return result;
- } else if (size == 0) {
- return WireFormatNano.EMPTY_BYTES;
- } else {
- // Slow path: Build a byte array first then copy it.
- return readRawBytes(size);
- }
- }
-
- /** Read a {@code uint32} field value from the stream. */
- public int readUInt32() throws IOException {
- return readRawVarint32();
- }
-
- /**
- * Read an enum field value from the stream. Caller is responsible
- * for converting the numeric value to an actual enum.
- */
- public int readEnum() throws IOException {
- return readRawVarint32();
- }
-
- /** Read an {@code sfixed32} field value from the stream. */
- public int readSFixed32() throws IOException {
- return readRawLittleEndian32();
- }
-
- /** Read an {@code sfixed64} field value from the stream. */
- public long readSFixed64() throws IOException {
- return readRawLittleEndian64();
- }
-
- /** Read an {@code sint32} field value from the stream. */
- public int readSInt32() throws IOException {
- return decodeZigZag32(readRawVarint32());
- }
-
- /** Read an {@code sint64} field value from the stream. */
- public long readSInt64() throws IOException {
- return decodeZigZag64(readRawVarint64());
- }
-
- // =================================================================
-
- /**
- * Read a raw Varint from the stream. If larger than 32 bits, discard the
- * upper bits.
- */
- public int readRawVarint32() throws IOException {
- byte tmp = readRawByte();
- if (tmp >= 0) {
- return tmp;
- }
- int result = tmp & 0x7f;
- if ((tmp = readRawByte()) >= 0) {
- result |= tmp << 7;
- } else {
- result |= (tmp & 0x7f) << 7;
- if ((tmp = readRawByte()) >= 0) {
- result |= tmp << 14;
- } else {
- result |= (tmp & 0x7f) << 14;
- if ((tmp = readRawByte()) >= 0) {
- result |= tmp << 21;
- } else {
- result |= (tmp & 0x7f) << 21;
- result |= (tmp = readRawByte()) << 28;
- if (tmp < 0) {
- // Discard upper 32 bits.
- for (int i = 0; i < 5; i++) {
- if (readRawByte() >= 0) {
- return result;
- }
- }
- throw InvalidProtocolBufferNanoException.malformedVarint();
- }
- }
- }
- }
- return result;
- }
-
- /** Read a raw Varint from the stream. */
- public long readRawVarint64() throws IOException {
- int shift = 0;
- long result = 0;
- while (shift < 64) {
- final byte b = readRawByte();
- result |= (long)(b & 0x7F) << shift;
- if ((b & 0x80) == 0) {
- return result;
- }
- shift += 7;
- }
- throw InvalidProtocolBufferNanoException.malformedVarint();
- }
-
- /** Read a 32-bit little-endian integer from the stream. */
- public int readRawLittleEndian32() throws IOException {
- final byte b1 = readRawByte();
- final byte b2 = readRawByte();
- final byte b3 = readRawByte();
- final byte b4 = readRawByte();
- return ((b1 & 0xff) ) |
- ((b2 & 0xff) << 8) |
- ((b3 & 0xff) << 16) |
- ((b4 & 0xff) << 24);
- }
-
- /** Read a 64-bit little-endian integer from the stream. */
- public long readRawLittleEndian64() throws IOException {
- 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) |
- (((long)b4 & 0xff) << 24) |
- (((long)b5 & 0xff) << 32) |
- (((long)b6 & 0xff) << 40) |
- (((long)b7 & 0xff) << 48) |
- (((long)b8 & 0xff) << 56);
- }
-
- /**
- * Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
- * into values that can be efficiently encoded with varint. (Otherwise,
- * negative values must be sign-extended to 64 bits to be varint encoded,
- * thus always taking 10 bytes on the wire.)
- *
- * @param n An unsigned 32-bit integer, stored in a signed int because
- * Java has no explicit unsigned support.
- * @return A signed 32-bit integer.
- */
- public static int decodeZigZag32(final int n) {
- return (n >>> 1) ^ -(n & 1);
- }
-
- /**
- * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
- * into values that can be efficiently encoded with varint. (Otherwise,
- * negative values must be sign-extended to 64 bits to be varint encoded,
- * thus always taking 10 bytes on the wire.)
- *
- * @param n An unsigned 64-bit integer, stored in a signed int because
- * Java has no explicit unsigned support.
- * @return A signed 64-bit integer.
- */
- public static long decodeZigZag64(final long n) {
- return (n >>> 1) ^ -(n & 1);
- }
-
- // -----------------------------------------------------------------
-
- private final byte[] buffer;
- private int bufferStart;
- private int bufferSize;
- private int bufferSizeAfterLimit;
- private int bufferPos;
- private int lastTag;
-
- /** The absolute position of the end of the current message. */
- private int currentLimit = Integer.MAX_VALUE;
-
- /** See setRecursionLimit() */
- private int recursionDepth;
- private int recursionLimit = DEFAULT_RECURSION_LIMIT;
-
- /** See setSizeLimit() */
- private int sizeLimit = DEFAULT_SIZE_LIMIT;
-
- private static final int DEFAULT_RECURSION_LIMIT = 64;
- private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB
-
- private CodedInputByteBufferNano(final byte[] buffer, final int off, final int len) {
- this.buffer = buffer;
- bufferStart = off;
- bufferSize = off + len;
- bufferPos = off;
- }
-
- /**
- * Set the maximum message recursion depth. In order to prevent malicious
- * messages from causing stack overflows, {@code CodedInputStream} limits
- * how deeply messages may be nested. The default limit is 64.
- *
- * @return the old limit.
- */
- public int setRecursionLimit(final int limit) {
- if (limit < 0) {
- throw new IllegalArgumentException(
- "Recursion limit cannot be negative: " + limit);
- }
- final int oldLimit = recursionLimit;
- recursionLimit = limit;
- return oldLimit;
- }
-
- /**
- * Set the maximum message size. In order to prevent malicious
- * messages from exhausting memory or causing integer overflows,
- * {@code CodedInputStream} limits how large a message may be.
- * The default limit is 64MB. You should set this limit as small
- * as you can without harming your app's functionality. Note that
- * size limits only apply when reading from an {@code InputStream}, not
- * when constructed around a raw byte array.
- * <p>
- * If you want to read several messages from a single CodedInputStream, you
- * could call {@link #resetSizeCounter()} after each one to avoid hitting the
- * size limit.
- *
- * @return the old limit.
- */
- public int setSizeLimit(final int limit) {
- if (limit < 0) {
- throw new IllegalArgumentException(
- "Size limit cannot be negative: " + limit);
- }
- final int oldLimit = sizeLimit;
- sizeLimit = limit;
- return oldLimit;
- }
-
- /**
- * Resets the current size counter to zero (see {@link #setSizeLimit(int)}).
- */
- public void resetSizeCounter() {
- }
-
- /**
- * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This
- * is called when descending into a length-delimited embedded message.
- *
- * @return the old limit.
- */
- public int pushLimit(int byteLimit) throws InvalidProtocolBufferNanoException {
- if (byteLimit < 0) {
- throw InvalidProtocolBufferNanoException.negativeSize();
- }
- byteLimit += bufferPos;
- final int oldLimit = currentLimit;
- if (byteLimit > oldLimit) {
- throw InvalidProtocolBufferNanoException.truncatedMessage();
- }
- currentLimit = byteLimit;
-
- recomputeBufferSizeAfterLimit();
-
- return oldLimit;
- }
-
- private void recomputeBufferSizeAfterLimit() {
- bufferSize += bufferSizeAfterLimit;
- final int bufferEnd = bufferSize;
- if (bufferEnd > currentLimit) {
- // Limit is in current buffer.
- bufferSizeAfterLimit = bufferEnd - currentLimit;
- bufferSize -= bufferSizeAfterLimit;
- } else {
- bufferSizeAfterLimit = 0;
- }
- }
-
- /**
- * Discards the current limit, returning to the previous limit.
- *
- * @param oldLimit The old limit, as returned by {@code pushLimit}.
- */
- public void popLimit(final int oldLimit) {
- currentLimit = oldLimit;
- recomputeBufferSizeAfterLimit();
- }
-
- /**
- * Returns the number of bytes to be read before the current limit.
- * If no limit is set, returns -1.
- */
- public int getBytesUntilLimit() {
- if (currentLimit == Integer.MAX_VALUE) {
- return -1;
- }
-
- final int currentAbsolutePosition = bufferPos;
- return currentLimit - currentAbsolutePosition;
- }
-
- /**
- * Returns true if the stream has reached the end of the input. This is the
- * case if either the end of the underlying input source has been reached or
- * if the stream has reached a limit created using {@link #pushLimit(int)}.
- */
- public boolean isAtEnd() {
- return bufferPos == bufferSize;
- }
-
- /**
- * Get current position in buffer relative to beginning offset.
- */
- public int getPosition() {
- return bufferPos - bufferStart;
- }
-
- /**
- * Retrieves a subset of data in the buffer. The returned array is not backed by the original
- * buffer array.
- *
- * @param offset the position (relative to the buffer start position) to start at.
- * @param length the number of bytes to retrieve.
- */
- public byte[] getData(int offset, int length) {
- if (length == 0) {
- return WireFormatNano.EMPTY_BYTES;
- }
- byte[] copy = new byte[length];
- int start = bufferStart + offset;
- System.arraycopy(buffer, start, copy, 0, length);
- return copy;
- }
-
- /**
- * Rewind to previous position. Cannot go forward.
- */
- public void rewindToPosition(int position) {
- if (position > bufferPos - bufferStart) {
- throw new IllegalArgumentException(
- "Position " + position + " is beyond current " + (bufferPos - bufferStart));
- }
- if (position < 0) {
- throw new IllegalArgumentException("Bad position " + position);
- }
- bufferPos = bufferStart + position;
- }
-
- /**
- * Read one byte from the input.
- *
- * @throws InvalidProtocolBufferNanoException The end of the stream or the current
- * limit was reached.
- */
- public byte readRawByte() throws IOException {
- if (bufferPos == bufferSize) {
- throw InvalidProtocolBufferNanoException.truncatedMessage();
- }
- return buffer[bufferPos++];
- }
-
- /**
- * Read a fixed size of bytes from the input.
- *
- * @throws InvalidProtocolBufferNanoException The end of the stream or the current
- * limit was reached.
- */
- public byte[] readRawBytes(final int size) throws IOException {
- if (size < 0) {
- throw InvalidProtocolBufferNanoException.negativeSize();
- }
-
- if (bufferPos + size > currentLimit) {
- // Read to the end of the stream anyway.
- skipRawBytes(currentLimit - bufferPos);
- // Then fail.
- throw InvalidProtocolBufferNanoException.truncatedMessage();
- }
-
- if (size <= bufferSize - bufferPos) {
- // We have all the bytes we need already.
- final byte[] bytes = new byte[size];
- System.arraycopy(buffer, bufferPos, bytes, 0, size);
- bufferPos += size;
- return bytes;
- } else {
- throw InvalidProtocolBufferNanoException.truncatedMessage();
- }
- }
-
- /**
- * Reads and discards {@code size} bytes.
- *
- * @throws InvalidProtocolBufferNanoException The end of the stream or the current
- * limit was reached.
- */
- public void skipRawBytes(final int size) throws IOException {
- if (size < 0) {
- throw InvalidProtocolBufferNanoException.negativeSize();
- }
-
- if (bufferPos + size > currentLimit) {
- // Read to the end of the stream anyway.
- skipRawBytes(currentLimit - bufferPos);
- // Then fail.
- throw InvalidProtocolBufferNanoException.truncatedMessage();
- }
-
- if (size <= bufferSize - bufferPos) {
- // We have all the bytes we need already.
- bufferPos += size;
- } else {
- throw InvalidProtocolBufferNanoException.truncatedMessage();
- }
- }
-
- // Read a primitive type.
- Object readPrimitiveField(int type) throws IOException {
- switch (type) {
- case InternalNano.TYPE_DOUBLE:
- return readDouble();
- case InternalNano.TYPE_FLOAT:
- return readFloat();
- case InternalNano.TYPE_INT64:
- return readInt64();
- case InternalNano.TYPE_UINT64:
- return readUInt64();
- case InternalNano.TYPE_INT32:
- return readInt32();
- case InternalNano.TYPE_FIXED64:
- return readFixed64();
- case InternalNano.TYPE_FIXED32:
- return readFixed32();
- case InternalNano.TYPE_BOOL:
- return readBool();
- case InternalNano.TYPE_STRING:
- return readString();
- case InternalNano.TYPE_BYTES:
- return readBytes();
- case InternalNano.TYPE_UINT32:
- return readUInt32();
- case InternalNano.TYPE_ENUM:
- return readEnum();
- case InternalNano.TYPE_SFIXED32:
- return readSFixed32();
- case InternalNano.TYPE_SFIXED64:
- return readSFixed64();
- case InternalNano.TYPE_SINT32:
- return readSInt32();
- case InternalNano.TYPE_SINT64:
- return readSInt64();
- default:
- throw new IllegalArgumentException("Unknown type " + type);
- }
- }
-}