aboutsummaryrefslogtreecommitdiffhomepage
path: root/javanano/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'javanano/src/main/java')
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java683
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java1214
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java169
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/Extension.java706
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/FieldArray.java291
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/FieldData.java240
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/InternalNano.java547
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java93
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/MapFactories.java67
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/MessageNano.java198
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java275
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/UnknownFieldData.java88
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/WireFormatNano.java124
13 files changed, 0 insertions, 4695 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);
- }
- }
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java b/javanano/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java
deleted file mode 100644
index 322ada8e..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java
+++ /dev/null
@@ -1,1214 +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;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.ReadOnlyBufferException;
-
-/**
- * Encodes and writes protocol message fields.
- *
- * <p>This class contains two kinds of methods: methods that write specific
- * protocol message constructs and field types (e.g. {@link #writeTag} and
- * {@link #writeInt32}) and methods that write low-level values (e.g.
- * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are
- * writing encoded protocol messages, you should use the former methods, but if
- * you are writing some other format of your own design, use the latter.
- *
- * <p>This class is totally unsynchronized.
- *
- * @author kneton@google.com Kenton Varda
- */
-public final class CodedOutputByteBufferNano {
- /* max bytes per java UTF-16 char in UTF-8 */
- private static final int MAX_UTF8_EXPANSION = 3;
- private final ByteBuffer buffer;
-
- private CodedOutputByteBufferNano(final byte[] buffer, final int offset,
- final int length) {
- this(ByteBuffer.wrap(buffer, offset, length));
- }
-
- private CodedOutputByteBufferNano(final ByteBuffer buffer) {
- this.buffer = buffer;
- this.buffer.order(ByteOrder.LITTLE_ENDIAN);
- }
-
- /**
- * Create a new {@code CodedOutputStream} that writes directly to the given
- * byte array. If more bytes are written than fit in the array,
- * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
- * array is faster than writing to an {@code OutputStream}.
- */
- public static CodedOutputByteBufferNano newInstance(final byte[] flatArray) {
- return newInstance(flatArray, 0, flatArray.length);
- }
-
- /**
- * Create a new {@code CodedOutputStream} that writes directly to the given
- * byte array slice. If more bytes are written than fit in the slice,
- * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
- * array is faster than writing to an {@code OutputStream}.
- */
- public static CodedOutputByteBufferNano newInstance(final byte[] flatArray,
- final int offset,
- final int length) {
- return new CodedOutputByteBufferNano(flatArray, offset, length);
- }
-
- // -----------------------------------------------------------------
-
- /** Write a {@code double} field, including tag, to the stream. */
- public void writeDouble(final int fieldNumber, final double value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
- writeDoubleNoTag(value);
- }
-
- /** Write a {@code float} field, including tag, to the stream. */
- public void writeFloat(final int fieldNumber, final float value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
- writeFloatNoTag(value);
- }
-
- /** Write a {@code uint64} field, including tag, to the stream. */
- public void writeUInt64(final int fieldNumber, final long value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
- writeUInt64NoTag(value);
- }
-
- /** Write an {@code int64} field, including tag, to the stream. */
- public void writeInt64(final int fieldNumber, final long value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
- writeInt64NoTag(value);
- }
-
- /** Write an {@code int32} field, including tag, to the stream. */
- public void writeInt32(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
- writeInt32NoTag(value);
- }
-
- /** Write a {@code fixed64} field, including tag, to the stream. */
- public void writeFixed64(final int fieldNumber, final long value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
- writeFixed64NoTag(value);
- }
-
- /** Write a {@code fixed32} field, including tag, to the stream. */
- public void writeFixed32(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
- writeFixed32NoTag(value);
- }
-
- /** Write a {@code bool} field, including tag, to the stream. */
- public void writeBool(final int fieldNumber, final boolean value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
- writeBoolNoTag(value);
- }
-
- /** Write a {@code string} field, including tag, to the stream. */
- public void writeString(final int fieldNumber, final String value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
- writeStringNoTag(value);
- }
-
- /** Write a {@code group} field, including tag, to the stream. */
- public void writeGroup(final int fieldNumber, final MessageNano value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_START_GROUP);
- writeGroupNoTag(value);
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP);
- }
-
- /** Write an embedded message field, including tag, to the stream. */
- public void writeMessage(final int fieldNumber, final MessageNano value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
- writeMessageNoTag(value);
- }
-
- /** Write a {@code bytes} field, including tag, to the stream. */
- public void writeBytes(final int fieldNumber, final byte[] value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
- writeBytesNoTag(value);
- }
-
- /** Write a {@code uint32} field, including tag, to the stream. */
- public void writeUInt32(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
- writeUInt32NoTag(value);
- }
-
- /**
- * Write an enum field, including tag, to the stream. Caller is responsible
- * for converting the enum value to its numeric value.
- */
- public void writeEnum(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
- writeEnumNoTag(value);
- }
-
- /** Write an {@code sfixed32} field, including tag, to the stream. */
- public void writeSFixed32(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
- writeSFixed32NoTag(value);
- }
-
- /** Write an {@code sfixed64} field, including tag, to the stream. */
- public void writeSFixed64(final int fieldNumber, final long value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
- writeSFixed64NoTag(value);
- }
-
- /** Write an {@code sint32} field, including tag, to the stream. */
- public void writeSInt32(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
- writeSInt32NoTag(value);
- }
-
- /** Write an {@code sint64} field, including tag, to the stream. */
- public void writeSInt64(final int fieldNumber, final long value)
- throws IOException {
- writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
- writeSInt64NoTag(value);
- }
-
- /**
- * Write a MessageSet extension field to the stream. For historical reasons,
- * the wire format differs from normal fields.
- */
-// public void writeMessageSetExtension(final int fieldNumber,
-// final MessageMicro value)
-// throws IOException {
-// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
-// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
-// writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
-// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
-// }
-
- /**
- * Write an unparsed MessageSet extension field to the stream. For
- * historical reasons, the wire format differs from normal fields.
- */
-// public void writeRawMessageSetExtension(final int fieldNumber,
-// final ByteStringMicro value)
-// throws IOException {
-// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
-// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
-// writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
-// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
-// }
-
- // -----------------------------------------------------------------
-
- /** Write a {@code double} field to the stream. */
- public void writeDoubleNoTag(final double value) throws IOException {
- writeRawLittleEndian64(Double.doubleToLongBits(value));
- }
-
- /** Write a {@code float} field to the stream. */
- public void writeFloatNoTag(final float value) throws IOException {
- writeRawLittleEndian32(Float.floatToIntBits(value));
- }
-
- /** Write a {@code uint64} field to the stream. */
- public void writeUInt64NoTag(final long value) throws IOException {
- writeRawVarint64(value);
- }
-
- /** Write an {@code int64} field to the stream. */
- public void writeInt64NoTag(final long value) throws IOException {
- writeRawVarint64(value);
- }
-
- /** Write an {@code int32} field to the stream. */
- public void writeInt32NoTag(final int value) throws IOException {
- if (value >= 0) {
- writeRawVarint32(value);
- } else {
- // Must sign-extend.
- writeRawVarint64(value);
- }
- }
-
- /** Write a {@code fixed64} field to the stream. */
- public void writeFixed64NoTag(final long value) throws IOException {
- writeRawLittleEndian64(value);
- }
-
- /** Write a {@code fixed32} field to the stream. */
- public void writeFixed32NoTag(final int value) throws IOException {
- writeRawLittleEndian32(value);
- }
-
- /** Write a {@code bool} field to the stream. */
- public void writeBoolNoTag(final boolean value) throws IOException {
- writeRawByte(value ? 1 : 0);
- }
-
- /** Write a {@code string} field to the stream. */
- public void writeStringNoTag(final String value) throws IOException {
- // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
- // and at most 3 times of it. Optimize for the case where we know this length results in a
- // constant varint length - saves measuring length of the string.
- try {
- final int minLengthVarIntSize = computeRawVarint32Size(value.length());
- final int maxLengthVarIntSize = computeRawVarint32Size(value.length() * MAX_UTF8_EXPANSION);
- if (minLengthVarIntSize == maxLengthVarIntSize) {
- int oldPosition = buffer.position();
- // Buffer.position, when passed a position that is past its limit, throws
- // IllegalArgumentException, and this class is documented to throw
- // OutOfSpaceException instead.
- if (buffer.remaining() < minLengthVarIntSize) {
- throw new OutOfSpaceException(oldPosition + minLengthVarIntSize, buffer.limit());
- }
- buffer.position(oldPosition + minLengthVarIntSize);
- encode(value, buffer);
- int newPosition = buffer.position();
- buffer.position(oldPosition);
- writeRawVarint32(newPosition - oldPosition - minLengthVarIntSize);
- buffer.position(newPosition);
- } else {
- writeRawVarint32(encodedLength(value));
- encode(value, buffer);
- }
- } catch (BufferOverflowException e) {
- final OutOfSpaceException outOfSpaceException = new OutOfSpaceException(buffer.position(),
- buffer.limit());
- outOfSpaceException.initCause(e);
- throw outOfSpaceException;
- }
- }
-
- // These UTF-8 handling methods are copied from Guava's Utf8 class.
- /**
- * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string,
- * this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in
- * both time and space.
- *
- * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
- * surrogates)
- */
- private static int encodedLength(CharSequence sequence) {
- // Warning to maintainers: this implementation is highly optimized.
- int utf16Length = sequence.length();
- int utf8Length = utf16Length;
- int i = 0;
-
- // This loop optimizes for pure ASCII.
- while (i < utf16Length && sequence.charAt(i) < 0x80) {
- i++;
- }
-
- // This loop optimizes for chars less than 0x800.
- for (; i < utf16Length; i++) {
- char c = sequence.charAt(i);
- if (c < 0x800) {
- utf8Length += ((0x7f - c) >>> 31); // branch free!
- } else {
- utf8Length += encodedLengthGeneral(sequence, i);
- break;
- }
- }
-
- if (utf8Length < utf16Length) {
- // Necessary and sufficient condition for overflow because of maximum 3x expansion
- throw new IllegalArgumentException("UTF-8 length does not fit in int: "
- + (utf8Length + (1L << 32)));
- }
- return utf8Length;
- }
-
- private static int encodedLengthGeneral(CharSequence sequence, int start) {
- int utf16Length = sequence.length();
- int utf8Length = 0;
- for (int i = start; i < utf16Length; i++) {
- char c = sequence.charAt(i);
- if (c < 0x800) {
- utf8Length += (0x7f - c) >>> 31; // branch free!
- } else {
- utf8Length += 2;
- // jdk7+: if (Character.isSurrogate(c)) {
- if (Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE) {
- // Check that we have a well-formed surrogate pair.
- int cp = Character.codePointAt(sequence, i);
- if (cp < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
- throw new IllegalArgumentException("Unpaired surrogate at index " + i);
- }
- i++;
- }
- }
- }
- return utf8Length;
- }
-
- /**
- * Encodes {@code sequence} into UTF-8, in {@code byteBuffer}. For a string, this method is
- * equivalent to {@code buffer.put(string.getBytes(UTF_8))}, but is more efficient in both time
- * and space. Bytes are written starting at the current position. This method requires paired
- * surrogates, and therefore does not support chunking.
- *
- * <p>To ensure sufficient space in the output buffer, either call {@link #encodedLength} to
- * compute the exact amount needed, or leave room for {@code 3 * sequence.length()}, which is the
- * largest possible number of bytes that any input can be encoded to.
- *
- * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
- * surrogates)
- * @throws BufferOverflowException if {@code sequence} encoded in UTF-8 does not fit in
- * {@code byteBuffer}'s remaining space.
- * @throws ReadOnlyBufferException if {@code byteBuffer} is a read-only buffer.
- */
- private static void encode(CharSequence sequence, ByteBuffer byteBuffer) {
- if (byteBuffer.isReadOnly()) {
- throw new ReadOnlyBufferException();
- } else if (byteBuffer.hasArray()) {
- try {
- int encoded = encode(sequence,
- byteBuffer.array(),
- byteBuffer.arrayOffset() + byteBuffer.position(),
- byteBuffer.remaining());
- byteBuffer.position(encoded - byteBuffer.arrayOffset());
- } catch (ArrayIndexOutOfBoundsException e) {
- BufferOverflowException boe = new BufferOverflowException();
- boe.initCause(e);
- throw boe;
- }
- } else {
- encodeDirect(sequence, byteBuffer);
- }
- }
-
- private static void encodeDirect(CharSequence sequence, ByteBuffer byteBuffer) {
- int utf16Length = sequence.length();
- for (int i = 0; i < utf16Length; i++) {
- final char c = sequence.charAt(i);
- if (c < 0x80) { // ASCII
- byteBuffer.put((byte) c);
- } else if (c < 0x800) { // 11 bits, two UTF-8 bytes
- byteBuffer.put((byte) ((0xF << 6) | (c >>> 6)));
- byteBuffer.put((byte) (0x80 | (0x3F & c)));
- } else if (c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) {
- // Maximium single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
- byteBuffer.put((byte) ((0xF << 5) | (c >>> 12)));
- byteBuffer.put((byte) (0x80 | (0x3F & (c >>> 6))));
- byteBuffer.put((byte) (0x80 | (0x3F & c)));
- } else {
- final char low;
- if (i + 1 == sequence.length()
- || !Character.isSurrogatePair(c, (low = sequence.charAt(++i)))) {
- throw new IllegalArgumentException("Unpaired surrogate at index " + (i - 1));
- }
- int codePoint = Character.toCodePoint(c, low);
- byteBuffer.put((byte) ((0xF << 4) | (codePoint >>> 18)));
- byteBuffer.put((byte) (0x80 | (0x3F & (codePoint >>> 12))));
- byteBuffer.put((byte) (0x80 | (0x3F & (codePoint >>> 6))));
- byteBuffer.put((byte) (0x80 | (0x3F & codePoint)));
- }
- }
- }
-
- private static int encode(CharSequence sequence, byte[] bytes, int offset, int length) {
- int utf16Length = sequence.length();
- int j = offset;
- int i = 0;
- int limit = offset + length;
- // Designed to take advantage of
- // https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
- for (char c; i < utf16Length && i + j < limit && (c = sequence.charAt(i)) < 0x80; i++) {
- bytes[j + i] = (byte) c;
- }
- if (i == utf16Length) {
- return j + utf16Length;
- }
- j += i;
- for (char c; i < utf16Length; i++) {
- c = sequence.charAt(i);
- if (c < 0x80 && j < limit) {
- bytes[j++] = (byte) c;
- } else if (c < 0x800 && j <= limit - 2) { // 11 bits, two UTF-8 bytes
- bytes[j++] = (byte) ((0xF << 6) | (c >>> 6));
- bytes[j++] = (byte) (0x80 | (0x3F & c));
- } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) && j <= limit - 3) {
- // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
- bytes[j++] = (byte) ((0xF << 5) | (c >>> 12));
- bytes[j++] = (byte) (0x80 | (0x3F & (c >>> 6)));
- bytes[j++] = (byte) (0x80 | (0x3F & c));
- } else if (j <= limit - 4) {
- // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8 bytes
- final char low;
- if (i + 1 == sequence.length()
- || !Character.isSurrogatePair(c, (low = sequence.charAt(++i)))) {
- throw new IllegalArgumentException("Unpaired surrogate at index " + (i - 1));
- }
- int codePoint = Character.toCodePoint(c, low);
- bytes[j++] = (byte) ((0xF << 4) | (codePoint >>> 18));
- bytes[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 12)));
- bytes[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 6)));
- bytes[j++] = (byte) (0x80 | (0x3F & codePoint));
- } else {
- throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j);
- }
- }
- return j;
- }
-
- // End guava UTF-8 methods
-
-
- /** Write a {@code group} field to the stream. */
- public void writeGroupNoTag(final MessageNano value) throws IOException {
- value.writeTo(this);
- }
-
- /** Write an embedded message field to the stream. */
- public void writeMessageNoTag(final MessageNano value) throws IOException {
- writeRawVarint32(value.getCachedSize());
- value.writeTo(this);
- }
-
- /** Write a {@code bytes} field to the stream. */
- public void writeBytesNoTag(final byte[] value) throws IOException {
- writeRawVarint32(value.length);
- writeRawBytes(value);
- }
-
- /** Write a {@code uint32} field to the stream. */
- public void writeUInt32NoTag(final int value) throws IOException {
- writeRawVarint32(value);
- }
-
- /**
- * Write an enum field to the stream. Caller is responsible
- * for converting the enum value to its numeric value.
- */
- public void writeEnumNoTag(final int value) throws IOException {
- writeRawVarint32(value);
- }
-
- /** Write an {@code sfixed32} field to the stream. */
- public void writeSFixed32NoTag(final int value) throws IOException {
- writeRawLittleEndian32(value);
- }
-
- /** Write an {@code sfixed64} field to the stream. */
- public void writeSFixed64NoTag(final long value) throws IOException {
- writeRawLittleEndian64(value);
- }
-
- /** Write an {@code sint32} field to the stream. */
- public void writeSInt32NoTag(final int value) throws IOException {
- writeRawVarint32(encodeZigZag32(value));
- }
-
- /** Write an {@code sint64} field to the stream. */
- public void writeSInt64NoTag(final long value) throws IOException {
- writeRawVarint64(encodeZigZag64(value));
- }
-
- // =================================================================
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code double} field, including tag.
- */
- public static int computeDoubleSize(final int fieldNumber,
- final double value) {
- return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code float} field, including tag.
- */
- public static int computeFloatSize(final int fieldNumber, final float value) {
- return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code uint64} field, including tag.
- */
- public static int computeUInt64Size(final int fieldNumber, final long value) {
- return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code int64} field, including tag.
- */
- public static int computeInt64Size(final int fieldNumber, final long value) {
- return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code int32} field, including tag.
- */
- public static int computeInt32Size(final int fieldNumber, final int value) {
- return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code fixed64} field, including tag.
- */
- public static int computeFixed64Size(final int fieldNumber,
- final long value) {
- return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code fixed32} field, including tag.
- */
- public static int computeFixed32Size(final int fieldNumber,
- final int value) {
- return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bool} field, including tag.
- */
- public static int computeBoolSize(final int fieldNumber,
- final boolean value) {
- return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code string} field, including tag.
- */
- public static int computeStringSize(final int fieldNumber,
- final String value) {
- return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code group} field, including tag.
- */
- public static int computeGroupSize(final int fieldNumber,
- final MessageNano value) {
- return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * embedded message field, including tag.
- */
- public static int computeMessageSize(final int fieldNumber,
- final MessageNano value) {
- return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bytes} field, including tag.
- */
- public static int computeBytesSize(final int fieldNumber,
- final byte[] value) {
- return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code uint32} field, including tag.
- */
- public static int computeUInt32Size(final int fieldNumber, final int value) {
- return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * enum field, including tag. Caller is responsible for converting the
- * enum value to its numeric value.
- */
- public static int computeEnumSize(final int fieldNumber, final int value) {
- return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sfixed32} field, including tag.
- */
- public static int computeSFixed32Size(final int fieldNumber,
- final int value) {
- return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sfixed64} field, including tag.
- */
- public static int computeSFixed64Size(final int fieldNumber,
- final long value) {
- return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sint32} field, including tag.
- */
- public static int computeSInt32Size(final int fieldNumber, final int value) {
- return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sint64} field, including tag.
- */
- public static int computeSInt64Size(final int fieldNumber, final long value) {
- return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * MessageSet extension to the stream. For historical reasons,
- * the wire format differs from normal fields.
- */
-// public static int computeMessageSetExtensionSize(
-// final int fieldNumber, final MessageMicro value) {
-// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
-// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
-// computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
-// }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * unparsed MessageSet extension field to the stream. For
- * historical reasons, the wire format differs from normal fields.
- */
-// public static int computeRawMessageSetExtensionSize(
-// final int fieldNumber, final ByteStringMicro value) {
-// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
-// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
-// computeBytesSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
-// }
-
- // -----------------------------------------------------------------
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code double} field, including tag.
- */
- public static int computeDoubleSizeNoTag(final double value) {
- return LITTLE_ENDIAN_64_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code float} field, including tag.
- */
- public static int computeFloatSizeNoTag(final float value) {
- return LITTLE_ENDIAN_32_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code uint64} field, including tag.
- */
- public static int computeUInt64SizeNoTag(final long value) {
- return computeRawVarint64Size(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code int64} field, including tag.
- */
- public static int computeInt64SizeNoTag(final long value) {
- return computeRawVarint64Size(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code int32} field, including tag.
- */
- public static int computeInt32SizeNoTag(final int value) {
- if (value >= 0) {
- return computeRawVarint32Size(value);
- } else {
- // Must sign-extend.
- return 10;
- }
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code fixed64} field.
- */
- public static int computeFixed64SizeNoTag(final long value) {
- return LITTLE_ENDIAN_64_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code fixed32} field.
- */
- public static int computeFixed32SizeNoTag(final int value) {
- return LITTLE_ENDIAN_32_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bool} field.
- */
- public static int computeBoolSizeNoTag(final boolean value) {
- return 1;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code string} field.
- */
- public static int computeStringSizeNoTag(final String value) {
- final int length = encodedLength(value);
- return computeRawVarint32Size(length) + length;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code group} field.
- */
- public static int computeGroupSizeNoTag(final MessageNano value) {
- return value.getSerializedSize();
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an embedded
- * message field.
- */
- public static int computeMessageSizeNoTag(final MessageNano value) {
- final int size = value.getSerializedSize();
- return computeRawVarint32Size(size) + size;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bytes} field.
- */
- public static int computeBytesSizeNoTag(final byte[] value) {
- return computeRawVarint32Size(value.length) + value.length;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code uint32} field.
- */
- public static int computeUInt32SizeNoTag(final int value) {
- return computeRawVarint32Size(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an enum field.
- * Caller is responsible for converting the enum value to its numeric value.
- */
- public static int computeEnumSizeNoTag(final int value) {
- return computeRawVarint32Size(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sfixed32} field.
- */
- public static int computeSFixed32SizeNoTag(final int value) {
- return LITTLE_ENDIAN_32_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sfixed64} field.
- */
- public static int computeSFixed64SizeNoTag(final long value) {
- return LITTLE_ENDIAN_64_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sint32} field.
- */
- public static int computeSInt32SizeNoTag(final int value) {
- return computeRawVarint32Size(encodeZigZag32(value));
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sint64} field.
- */
- public static int computeSInt64SizeNoTag(final long value) {
- return computeRawVarint64Size(encodeZigZag64(value));
- }
-
- // =================================================================
-
- /**
- * If writing to a flat array, return the space left in the array.
- * Otherwise, throws {@code UnsupportedOperationException}.
- */
- public int spaceLeft() {
- return buffer.remaining();
- }
-
- /**
- * Verifies that {@link #spaceLeft()} returns zero. It's common to create
- * a byte array that is exactly big enough to hold a message, then write to
- * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()}
- * after writing verifies that the message was actually as big as expected,
- * which can help catch bugs.
- */
- public void checkNoSpaceLeft() {
- if (spaceLeft() != 0) {
- throw new IllegalStateException(
- "Did not write as much data as expected.");
- }
- }
-
- /**
- * Returns the position within the internal buffer.
- */
- public int position() {
- return buffer.position();
- }
-
- /**
- * Resets the position within the internal buffer to zero.
- *
- * @see #position
- * @see #spaceLeft
- */
- public void reset() {
- buffer.clear();
- }
-
- /**
- * If you create a CodedOutputStream around a simple flat array, you must
- * not attempt to write more bytes than the array has space. Otherwise,
- * this exception will be thrown.
- */
- public static class OutOfSpaceException extends IOException {
- private static final long serialVersionUID = -6947486886997889499L;
-
- OutOfSpaceException(int position, int limit) {
- super("CodedOutputStream was writing to a flat byte array and ran " +
- "out of space (pos " + position + " limit " + limit + ").");
- }
- }
-
- /** Write a single byte. */
- public void writeRawByte(final byte value) throws IOException {
- if (!buffer.hasRemaining()) {
- // We're writing to a single buffer.
- throw new OutOfSpaceException(buffer.position(), buffer.limit());
- }
-
- buffer.put(value);
- }
-
- /** Write a single byte, represented by an integer value. */
- public void writeRawByte(final int value) throws IOException {
- writeRawByte((byte) value);
- }
-
- /** Write an array of bytes. */
- public void writeRawBytes(final byte[] value) throws IOException {
- writeRawBytes(value, 0, value.length);
- }
-
- /** Write part of an array of bytes. */
- public void writeRawBytes(final byte[] value, int offset, int length)
- throws IOException {
- if (buffer.remaining() >= length) {
- buffer.put(value, offset, length);
- } else {
- // We're writing to a single buffer.
- throw new OutOfSpaceException(buffer.position(), buffer.limit());
- }
- }
-
- /** Encode and write a tag. */
- public void writeTag(final int fieldNumber, final int wireType)
- throws IOException {
- writeRawVarint32(WireFormatNano.makeTag(fieldNumber, wireType));
- }
-
- /** Compute the number of bytes that would be needed to encode a tag. */
- public static int computeTagSize(final int fieldNumber) {
- return computeRawVarint32Size(WireFormatNano.makeTag(fieldNumber, 0));
- }
-
- /**
- * Encode and write a varint. {@code value} is treated as
- * unsigned, so it won't be sign-extended if negative.
- */
- public void writeRawVarint32(int value) throws IOException {
- while (true) {
- if ((value & ~0x7F) == 0) {
- writeRawByte(value);
- return;
- } else {
- writeRawByte((value & 0x7F) | 0x80);
- value >>>= 7;
- }
- }
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a varint.
- * {@code value} is treated as unsigned, so it won't be sign-extended if
- * negative.
- */
- public static int computeRawVarint32Size(final int value) {
- if ((value & (0xffffffff << 7)) == 0) return 1;
- if ((value & (0xffffffff << 14)) == 0) return 2;
- if ((value & (0xffffffff << 21)) == 0) return 3;
- if ((value & (0xffffffff << 28)) == 0) return 4;
- return 5;
- }
-
- /** Encode and write a varint. */
- public void writeRawVarint64(long value) throws IOException {
- while (true) {
- if ((value & ~0x7FL) == 0) {
- writeRawByte((int)value);
- return;
- } else {
- writeRawByte(((int)value & 0x7F) | 0x80);
- value >>>= 7;
- }
- }
- }
-
- /** Compute the number of bytes that would be needed to encode a varint. */
- public static int computeRawVarint64Size(final long value) {
- if ((value & (0xffffffffffffffffL << 7)) == 0) return 1;
- if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
- if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
- if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
- if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
- if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
- if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
- if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
- if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
- return 10;
- }
-
- /** Write a little-endian 32-bit integer. */
- public void writeRawLittleEndian32(final int value) throws IOException {
- if (buffer.remaining() < 4) {
- throw new OutOfSpaceException(buffer.position(), buffer.limit());
- }
- buffer.putInt(value);
- }
-
- public static final int LITTLE_ENDIAN_32_SIZE = 4;
-
- /** Write a little-endian 64-bit integer. */
- public void writeRawLittleEndian64(final long value) throws IOException {
- if (buffer.remaining() < 8) {
- throw new OutOfSpaceException(buffer.position(), buffer.limit());
- }
- buffer.putLong(value);
- }
-
- public static final int LITTLE_ENDIAN_64_SIZE = 8;
-
- /**
- * Encode 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 A signed 32-bit integer.
- * @return An unsigned 32-bit integer, stored in a signed int because
- * Java has no explicit unsigned support.
- */
- public static int encodeZigZag32(final int n) {
- // Note: the right-shift must be arithmetic
- return (n << 1) ^ (n >> 31);
- }
-
- /**
- * Encode 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 A signed 64-bit integer.
- * @return An unsigned 64-bit integer, stored in a signed int because
- * Java has no explicit unsigned support.
- */
- public static long encodeZigZag64(final long n) {
- // Note: the right-shift must be arithmetic
- return (n << 1) ^ (n >> 63);
- }
-
- static int computeFieldSize(int number, int type, Object object) {
- switch (type) {
- case InternalNano.TYPE_BOOL:
- return computeBoolSize(number, (Boolean) object);
- case InternalNano.TYPE_BYTES:
- return computeBytesSize(number, (byte[]) object);
- case InternalNano.TYPE_STRING:
- return computeStringSize(number, (String) object);
- case InternalNano.TYPE_FLOAT:
- return computeFloatSize(number, (Float) object);
- case InternalNano.TYPE_DOUBLE:
- return computeDoubleSize(number, (Double) object);
- case InternalNano.TYPE_ENUM:
- return computeEnumSize(number, (Integer) object);
- case InternalNano.TYPE_FIXED32:
- return computeFixed32Size(number, (Integer) object);
- case InternalNano.TYPE_INT32:
- return computeInt32Size(number, (Integer) object);
- case InternalNano.TYPE_UINT32:
- return computeUInt32Size(number, (Integer) object);
- case InternalNano.TYPE_SINT32:
- return computeSInt32Size(number, (Integer) object);
- case InternalNano.TYPE_SFIXED32:
- return computeSFixed32Size(number, (Integer) object);
- case InternalNano.TYPE_INT64:
- return computeInt64Size(number, (Long) object);
- case InternalNano.TYPE_UINT64:
- return computeUInt64Size(number, (Long) object);
- case InternalNano.TYPE_SINT64:
- return computeSInt64Size(number, (Long) object);
- case InternalNano.TYPE_FIXED64:
- return computeFixed64Size(number, (Long) object);
- case InternalNano.TYPE_SFIXED64:
- return computeSFixed64Size(number, (Long) object);
- case InternalNano.TYPE_MESSAGE:
- return computeMessageSize(number, (MessageNano) object);
- case InternalNano.TYPE_GROUP:
- return computeGroupSize(number, (MessageNano) object);
- default:
- throw new IllegalArgumentException("Unknown type: " + type);
- }
- }
-
- void writeField(int number, int type, Object value)
- throws IOException {
- switch (type) {
- case InternalNano.TYPE_DOUBLE:
- Double doubleValue = (Double) value;
- writeDouble(number, doubleValue);
- break;
- case InternalNano.TYPE_FLOAT:
- Float floatValue = (Float) value;
- writeFloat(number, floatValue);
- break;
- case InternalNano.TYPE_INT64:
- Long int64Value = (Long) value;
- writeInt64(number, int64Value);
- break;
- case InternalNano.TYPE_UINT64:
- Long uint64Value = (Long) value;
- writeUInt64(number, uint64Value);
- break;
- case InternalNano.TYPE_INT32:
- Integer int32Value = (Integer) value;
- writeInt32(number, int32Value);
- break;
- case InternalNano.TYPE_FIXED64:
- Long fixed64Value = (Long) value;
- writeFixed64(number, fixed64Value);
- break;
- case InternalNano.TYPE_FIXED32:
- Integer fixed32Value = (Integer) value;
- writeFixed32(number, fixed32Value);
- break;
- case InternalNano.TYPE_BOOL:
- Boolean boolValue = (Boolean) value;
- writeBool(number, boolValue);
- break;
- case InternalNano.TYPE_STRING:
- String stringValue = (String) value;
- writeString(number, stringValue);
- break;
- case InternalNano.TYPE_BYTES:
- byte[] bytesValue = (byte[]) value;
- writeBytes(number, bytesValue);
- break;
- case InternalNano.TYPE_UINT32:
- Integer uint32Value = (Integer) value;
- writeUInt32(number, uint32Value);
- break;
- case InternalNano.TYPE_ENUM:
- Integer enumValue = (Integer) value;
- writeEnum(number, enumValue);
- break;
- case InternalNano.TYPE_SFIXED32:
- Integer sfixed32Value = (Integer) value;
- writeSFixed32(number, sfixed32Value);
- break;
- case InternalNano.TYPE_SFIXED64:
- Long sfixed64Value = (Long) value;
- writeSFixed64(number, sfixed64Value);
- break;
- case InternalNano.TYPE_SINT32:
- Integer sint32Value = (Integer) value;
- writeSInt32(number, sint32Value);
- break;
- case InternalNano.TYPE_SINT64:
- Long sint64Value = (Long) value;
- writeSInt64(number, sint64Value);
- break;
- case InternalNano.TYPE_MESSAGE:
- MessageNano messageValue = (MessageNano) value;
- writeMessage(number, messageValue);
- break;
- case InternalNano.TYPE_GROUP:
- MessageNano groupValue = (MessageNano) value;
- writeGroup(number, groupValue);
- break;
- default:
- throw new IOException("Unknown type: " + type);
- }
- }
-
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java b/javanano/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java
deleted file mode 100644
index 87973d76..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java
+++ /dev/null
@@ -1,169 +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;
-
-/**
- * Base class of those Protocol Buffer messages that need to store unknown fields,
- * such as extensions.
- */
-public abstract class ExtendableMessageNano<M extends ExtendableMessageNano<M>>
- extends MessageNano {
- /**
- * A container for fields unknown to the message, including extensions. Extension fields can
- * can be accessed through the {@link #getExtension} and {@link #setExtension} methods.
- */
- protected FieldArray unknownFieldData;
-
- @Override
- protected int computeSerializedSize() {
- int size = 0;
- if (unknownFieldData != null) {
- for (int i = 0; i < unknownFieldData.size(); i++) {
- FieldData field = unknownFieldData.dataAt(i);
- size += field.computeSerializedSize();
- }
- }
- return size;
- }
-
- @Override
- public void writeTo(CodedOutputByteBufferNano output) throws IOException {
- if (unknownFieldData == null) {
- return;
- }
- for (int i = 0; i < unknownFieldData.size(); i++) {
- FieldData field = unknownFieldData.dataAt(i);
- field.writeTo(output);
- }
- }
-
- /**
- * Checks if there is a value stored for the specified extension in this
- * message.
- */
- public final boolean hasExtension(Extension<M, ?> extension) {
- if (unknownFieldData == null) {
- return false;
- }
- FieldData field = unknownFieldData.get(WireFormatNano.getTagFieldNumber(extension.tag));
- return field != null;
- }
-
- /**
- * Gets the value stored in the specified extension of this message.
- */
- public final <T> T getExtension(Extension<M, T> extension) {
- if (unknownFieldData == null) {
- return null;
- }
- FieldData field = unknownFieldData.get(WireFormatNano.getTagFieldNumber(extension.tag));
- return field == null ? null : field.getValue(extension);
- }
-
- /**
- * Sets the value of the specified extension of this message.
- */
- public final <T> M setExtension(Extension<M, T> extension, T value) {
- int fieldNumber = WireFormatNano.getTagFieldNumber(extension.tag);
- if (value == null) {
- if (unknownFieldData != null) {
- unknownFieldData.remove(fieldNumber);
- if (unknownFieldData.isEmpty()) {
- unknownFieldData = null;
- }
- }
- } else {
- FieldData field = null;
- if (unknownFieldData == null) {
- unknownFieldData = new FieldArray();
- } else {
- field = unknownFieldData.get(fieldNumber);
- }
- if (field == null) {
- unknownFieldData.put(fieldNumber, new FieldData(extension, value));
- } else {
- field.setValue(extension, value);
- }
- }
-
- @SuppressWarnings("unchecked") // Generated code should guarantee type safety
- M typedThis = (M) this;
- return typedThis;
- }
-
- /**
- * Stores the binary data of an unknown field.
- *
- * <p>Generated messages will call this for unknown fields if the store_unknown_fields
- * option is on.
- *
- * <p>Note that the tag might be a end-group tag (rather than the start of an unknown field) in
- * which case we do not want to add an unknown field entry.
- *
- * @param input the input buffer.
- * @param tag the tag of the field.
-
- * @return {@literal true} unless the tag is an end-group tag.
- */
- protected final boolean storeUnknownField(CodedInputByteBufferNano input, int tag)
- throws IOException {
- int startPos = input.getPosition();
- if (!input.skipField(tag)) {
- return false; // This wasn't an unknown field, it's an end-group tag.
- }
- int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
- int endPos = input.getPosition();
- byte[] bytes = input.getData(startPos, endPos - startPos);
- UnknownFieldData unknownField = new UnknownFieldData(tag, bytes);
-
- FieldData field = null;
- if (unknownFieldData == null) {
- unknownFieldData = new FieldArray();
- } else {
- field = unknownFieldData.get(fieldNumber);
- }
- if (field == null) {
- field = new FieldData();
- unknownFieldData.put(fieldNumber, field);
- }
- field.addUnknownField(unknownField);
- return true;
- }
-
- @Override
- public M clone() throws CloneNotSupportedException {
- M cloned = (M) super.clone();
- InternalNano.cloneUnknownFieldData(this, cloned);
- return cloned;
- }
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/Extension.java b/javanano/src/main/java/com/google/protobuf/nano/Extension.java
deleted file mode 100644
index c458f9b1..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/Extension.java
+++ /dev/null
@@ -1,706 +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;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Represents an extension.
- *
- * @author bduff@google.com (Brian Duff)
- * @author maxtroy@google.com (Max Cai)
- * @param <M> the type of the extendable message this extension is for.
- * @param <T> the Java type of the extension; see {@link #clazz}.
- */
-public class Extension<M extends ExtendableMessageNano<M>, T> {
-
- /*
- * Because we typically only define message-typed extensions, the Extension class hierarchy is
- * designed as follows, to allow a big amount of code in this file to be removed by ProGuard:
- *
- * Extension // ready to use for message/group typed extensions
- * Δ
- * |
- * PrimitiveExtension // for primitive/enum typed extensions
- */
-
- public static final int TYPE_DOUBLE = InternalNano.TYPE_DOUBLE;
- public static final int TYPE_FLOAT = InternalNano.TYPE_FLOAT;
- public static final int TYPE_INT64 = InternalNano.TYPE_INT64;
- public static final int TYPE_UINT64 = InternalNano.TYPE_UINT64;
- public static final int TYPE_INT32 = InternalNano.TYPE_INT32;
- public static final int TYPE_FIXED64 = InternalNano.TYPE_FIXED64;
- public static final int TYPE_FIXED32 = InternalNano.TYPE_FIXED32;
- public static final int TYPE_BOOL = InternalNano.TYPE_BOOL;
- public static final int TYPE_STRING = InternalNano.TYPE_STRING;
- public static final int TYPE_GROUP = InternalNano.TYPE_GROUP;
- public static final int TYPE_MESSAGE = InternalNano.TYPE_MESSAGE;
- public static final int TYPE_BYTES = InternalNano.TYPE_BYTES;
- public static final int TYPE_UINT32 = InternalNano.TYPE_UINT32;
- public static final int TYPE_ENUM = InternalNano.TYPE_ENUM;
- public static final int TYPE_SFIXED32 = InternalNano.TYPE_SFIXED32;
- public static final int TYPE_SFIXED64 = InternalNano.TYPE_SFIXED64;
- public static final int TYPE_SINT32 = InternalNano.TYPE_SINT32;
- public static final int TYPE_SINT64 = InternalNano.TYPE_SINT64;
-
- /**
- * Creates an {@code Extension} of the given message type and tag number.
- * Should be used by the generated code only.
- *
- * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
- * @deprecated use {@link #createMessageTyped(int, Class, long)} instead.
- */
- @Deprecated
- public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
- Extension<M, T> createMessageTyped(int type, Class<T> clazz, int tag) {
- return new Extension<M, T>(type, clazz, tag, false);
- }
-
- // Note: these create...() methods take a long for the tag parameter,
- // because tags are represented as unsigned ints, and these values exist
- // in generated code as long values. However, they can fit in 32-bits, so
- // it's safe to cast them to int without loss of precision.
-
- /**
- * Creates an {@code Extension} of the given message type and tag number.
- * Should be used by the generated code only.
- *
- * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
- */
- public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
- Extension<M, T> createMessageTyped(int type, Class<T> clazz, long tag) {
- return new Extension<M, T>(type, clazz, (int) tag, false);
- }
-
- /**
- * Creates a repeated {@code Extension} of the given message type and tag number.
- * Should be used by the generated code only.
- *
- * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
- */
- public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
- Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, long tag) {
- return new Extension<M, T[]>(type, clazz, (int) tag, true);
- }
-
- /**
- * Creates an {@code Extension} of the given primitive type and tag number.
- * Should be used by the generated code only.
- *
- * @param type one of {@code TYPE_*}, except {@link #TYPE_MESSAGE} and {@link #TYPE_GROUP}
- * @param clazz the boxed Java type of this extension
- */
- public static <M extends ExtendableMessageNano<M>, T>
- Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, long tag) {
- return new PrimitiveExtension<M, T>(type, clazz, (int) tag, false, 0, 0);
- }
-
- /**
- * Creates a repeated {@code Extension} of the given primitive type and tag number.
- * Should be used by the generated code only.
- *
- * @param type one of {@code TYPE_*}, except {@link #TYPE_MESSAGE} and {@link #TYPE_GROUP}
- * @param clazz the Java array type of this extension, with an unboxed component type
- */
- public static <M extends ExtendableMessageNano<M>, T>
- Extension<M, T> createRepeatedPrimitiveTyped(
- int type, Class<T> clazz, long tag, long nonPackedTag, long packedTag) {
- return new PrimitiveExtension<M, T>(type, clazz, (int) tag, true,
- (int) nonPackedTag, (int) packedTag);
- }
-
- /**
- * Protocol Buffer type of this extension; one of the {@code TYPE_} constants.
- */
- protected final int type;
-
- /**
- * Java type of this extension. For a singular extension, this is the boxed Java type for the
- * Protocol Buffer {@link #type}; for a repeated extension, this is an array type whose
- * component type is the unboxed Java type for {@link #type}. For example, for a singular
- * {@code int32}/{@link #TYPE_INT32} extension, this equals {@code Integer.class}; for a
- * repeated {@code int32} extension, this equals {@code int[].class}.
- */
- protected final Class<T> clazz;
-
- /**
- * Tag number of this extension. The data should be viewed as an unsigned 32-bit value.
- */
- public final int tag;
-
- /**
- * Whether this extension is repeated.
- */
- protected final boolean repeated;
-
- private Extension(int type, Class<T> clazz, int tag, boolean repeated) {
- this.type = type;
- this.clazz = clazz;
- this.tag = tag;
- this.repeated = repeated;
- }
-
- /**
- * Returns the value of this extension stored in the given list of unknown fields, or
- * {@code null} if no unknown fields matches this extension.
- *
- * @param unknownFields a list of {@link UnknownFieldData}. All of the elements must have a tag
- * that matches this Extension's tag.
- *
- */
- final T getValueFrom(List<UnknownFieldData> unknownFields) {
- if (unknownFields == null) {
- return null;
- }
- return repeated ? getRepeatedValueFrom(unknownFields) : getSingularValueFrom(unknownFields);
- }
-
- private T getRepeatedValueFrom(List<UnknownFieldData> unknownFields) {
- // For repeated extensions, read all matching unknown fields in their original order.
- List<Object> resultList = new ArrayList<Object>();
- for (int i = 0; i < unknownFields.size(); i++) {
- UnknownFieldData data = unknownFields.get(i);
- if (data.bytes.length != 0) {
- readDataInto(data, resultList);
- }
- }
-
- int resultSize = resultList.size();
- if (resultSize == 0) {
- return null;
- } else {
- T result = clazz.cast(Array.newInstance(clazz.getComponentType(), resultSize));
- for (int i = 0; i < resultSize; i++) {
- Array.set(result, i, resultList.get(i));
- }
- return result;
- }
- }
-
- private T getSingularValueFrom(List<UnknownFieldData> unknownFields) {
- // For singular extensions, get the last piece of data stored under this extension.
- if (unknownFields.isEmpty()) {
- return null;
- }
- UnknownFieldData lastData = unknownFields.get(unknownFields.size() - 1);
- return clazz.cast(readData(CodedInputByteBufferNano.newInstance(lastData.bytes)));
- }
-
- protected Object readData(CodedInputByteBufferNano input) {
- // This implementation is for message/group extensions.
- Class<?> messageType = repeated ? clazz.getComponentType() : clazz;
- try {
- switch (type) {
- case TYPE_GROUP:
- MessageNano group = (MessageNano) messageType.newInstance();
- input.readGroup(group, WireFormatNano.getTagFieldNumber(tag));
- return group;
- case TYPE_MESSAGE:
- MessageNano message = (MessageNano) messageType.newInstance();
- input.readMessage(message);
- return message;
- default:
- throw new IllegalArgumentException("Unknown type " + type);
- }
- } catch (InstantiationException e) {
- throw new IllegalArgumentException(
- "Error creating instance of class " + messageType, e);
- } catch (IllegalAccessException e) {
- throw new IllegalArgumentException(
- "Error creating instance of class " + messageType, e);
- } catch (IOException e) {
- throw new IllegalArgumentException("Error reading extension field", e);
- }
- }
-
- protected void readDataInto(UnknownFieldData data, List<Object> resultList) {
- // This implementation is for message/group extensions.
- resultList.add(readData(CodedInputByteBufferNano.newInstance(data.bytes)));
- }
-
- void writeTo(Object value, CodedOutputByteBufferNano output) throws IOException {
- if (repeated) {
- writeRepeatedData(value, output);
- } else {
- writeSingularData(value, output);
- }
- }
-
- protected void writeSingularData(Object value, CodedOutputByteBufferNano out) {
- // This implementation is for message/group extensions.
- try {
- out.writeRawVarint32(tag);
- switch (type) {
- case TYPE_GROUP:
- MessageNano groupValue = (MessageNano) value;
- int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
- out.writeGroupNoTag(groupValue);
- // The endgroup tag must be included in the data payload.
- out.writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP);
- break;
- case TYPE_MESSAGE:
- MessageNano messageValue = (MessageNano) value;
- out.writeMessageNoTag(messageValue);
- break;
- default:
- throw new IllegalArgumentException("Unknown type " + type);
- }
- } catch (IOException e) {
- // Should not happen
- throw new IllegalStateException(e);
- }
- }
-
- protected void writeRepeatedData(Object array, CodedOutputByteBufferNano output) {
- // This implementation is for non-packed extensions.
- int arrayLength = Array.getLength(array);
- for (int i = 0; i < arrayLength; i++) {
- Object element = Array.get(array, i);
- if (element != null) {
- writeSingularData(element, output);
- }
- }
- }
-
- int computeSerializedSize(Object value) {
- if (repeated) {
- return computeRepeatedSerializedSize(value);
- } else {
- return computeSingularSerializedSize(value);
- }
- }
-
- protected int computeRepeatedSerializedSize(Object array) {
- // This implementation is for non-packed extensions.
- int size = 0;
- int arrayLength = Array.getLength(array);
- for (int i = 0; i < arrayLength; i++) {
- Object element = Array.get(array, i);
- if (element != null) {
- size += computeSingularSerializedSize(Array.get(array, i));
- }
- }
- return size;
- }
-
- protected int computeSingularSerializedSize(Object value) {
- // This implementation is for message/group extensions.
- int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
- switch (type) {
- case TYPE_GROUP:
- MessageNano groupValue = (MessageNano) value;
- return CodedOutputByteBufferNano.computeGroupSize(fieldNumber, groupValue);
- case TYPE_MESSAGE:
- MessageNano messageValue = (MessageNano) value;
- return CodedOutputByteBufferNano.computeMessageSize(fieldNumber, messageValue);
- default:
- throw new IllegalArgumentException("Unknown type " + type);
- }
- }
-
- /**
- * Represents an extension of a primitive (including enum) type. If there is no primitive
- * extensions, this subclass will be removable by ProGuard.
- */
- private static class PrimitiveExtension<M extends ExtendableMessageNano<M>, T>
- extends Extension<M, T> {
-
- /**
- * Tag of a piece of non-packed data from the wire compatible with this extension.
- */
- private final int nonPackedTag;
-
- /**
- * Tag of a piece of packed data from the wire compatible with this extension.
- * 0 if the type of this extension is not packable.
- */
- private final int packedTag;
-
- public PrimitiveExtension(int type, Class<T> clazz, int tag, boolean repeated,
- int nonPackedTag, int packedTag) {
- super(type, clazz, tag, repeated);
- this.nonPackedTag = nonPackedTag;
- this.packedTag = packedTag;
- }
-
- @Override
- protected Object readData(CodedInputByteBufferNano input) {
- try {
- return input.readPrimitiveField(type);
- } catch (IOException e) {
- throw new IllegalArgumentException("Error reading extension field", e);
- }
- }
-
- @Override
- protected void readDataInto(UnknownFieldData data, List<Object> resultList) {
- // This implementation is for primitive typed extensions,
- // which can read both packed and non-packed data.
- if (data.tag == nonPackedTag) {
- resultList.add(readData(CodedInputByteBufferNano.newInstance(data.bytes)));
- } else {
- CodedInputByteBufferNano buffer =
- CodedInputByteBufferNano.newInstance(data.bytes);
- try {
- buffer.pushLimit(buffer.readRawVarint32()); // length limit
- } catch (IOException e) {
- throw new IllegalArgumentException("Error reading extension field", e);
- }
- while (!buffer.isAtEnd()) {
- resultList.add(readData(buffer));
- }
- }
- }
-
- @Override
- protected final void writeSingularData(Object value, CodedOutputByteBufferNano output) {
- try {
- output.writeRawVarint32(tag);
- switch (type) {
- case TYPE_DOUBLE:
- Double doubleValue = (Double) value;
- output.writeDoubleNoTag(doubleValue);
- break;
- case TYPE_FLOAT:
- Float floatValue = (Float) value;
- output.writeFloatNoTag(floatValue);
- break;
- case TYPE_INT64:
- Long int64Value = (Long) value;
- output.writeInt64NoTag(int64Value);
- break;
- case TYPE_UINT64:
- Long uint64Value = (Long) value;
- output.writeUInt64NoTag(uint64Value);
- break;
- case TYPE_INT32:
- Integer int32Value = (Integer) value;
- output.writeInt32NoTag(int32Value);
- break;
- case TYPE_FIXED64:
- Long fixed64Value = (Long) value;
- output.writeFixed64NoTag(fixed64Value);
- break;
- case TYPE_FIXED32:
- Integer fixed32Value = (Integer) value;
- output.writeFixed32NoTag(fixed32Value);
- break;
- case TYPE_BOOL:
- Boolean boolValue = (Boolean) value;
- output.writeBoolNoTag(boolValue);
- break;
- case TYPE_STRING:
- String stringValue = (String) value;
- output.writeStringNoTag(stringValue);
- break;
- case TYPE_BYTES:
- byte[] bytesValue = (byte[]) value;
- output.writeBytesNoTag(bytesValue);
- break;
- case TYPE_UINT32:
- Integer uint32Value = (Integer) value;
- output.writeUInt32NoTag(uint32Value);
- break;
- case TYPE_ENUM:
- Integer enumValue = (Integer) value;
- output.writeEnumNoTag(enumValue);
- break;
- case TYPE_SFIXED32:
- Integer sfixed32Value = (Integer) value;
- output.writeSFixed32NoTag(sfixed32Value);
- break;
- case TYPE_SFIXED64:
- Long sfixed64Value = (Long) value;
- output.writeSFixed64NoTag(sfixed64Value);
- break;
- case TYPE_SINT32:
- Integer sint32Value = (Integer) value;
- output.writeSInt32NoTag(sint32Value);
- break;
- case TYPE_SINT64:
- Long sint64Value = (Long) value;
- output.writeSInt64NoTag(sint64Value);
- break;
- default:
- throw new IllegalArgumentException("Unknown type " + type);
- }
- } catch (IOException e) {
- // Should not happen
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- protected void writeRepeatedData(Object array, CodedOutputByteBufferNano output) {
- if (tag == nonPackedTag) {
- // Use base implementation for non-packed data
- super.writeRepeatedData(array, output);
- } else if (tag == packedTag) {
- // Packed. Note that the array element type is guaranteed to be primitive, so there
- // won't be any null elements, so no null check in this block.
- int arrayLength = Array.getLength(array);
- int dataSize = computePackedDataSize(array);
-
- try {
- output.writeRawVarint32(tag);
- output.writeRawVarint32(dataSize);
- switch (type) {
- case TYPE_BOOL:
- for (int i = 0; i < arrayLength; i++) {
- output.writeBoolNoTag(Array.getBoolean(array, i));
- }
- break;
- case TYPE_FIXED32:
- for (int i = 0; i < arrayLength; i++) {
- output.writeFixed32NoTag(Array.getInt(array, i));
- }
- break;
- case TYPE_SFIXED32:
- for (int i = 0; i < arrayLength; i++) {
- output.writeSFixed32NoTag(Array.getInt(array, i));
- }
- break;
- case TYPE_FLOAT:
- for (int i = 0; i < arrayLength; i++) {
- output.writeFloatNoTag(Array.getFloat(array, i));
- }
- break;
- case TYPE_FIXED64:
- for (int i = 0; i < arrayLength; i++) {
- output.writeFixed64NoTag(Array.getLong(array, i));
- }
- break;
- case TYPE_SFIXED64:
- for (int i = 0; i < arrayLength; i++) {
- output.writeSFixed64NoTag(Array.getLong(array, i));
- }
- break;
- case TYPE_DOUBLE:
- for (int i = 0; i < arrayLength; i++) {
- output.writeDoubleNoTag(Array.getDouble(array, i));
- }
- break;
- case TYPE_INT32:
- for (int i = 0; i < arrayLength; i++) {
- output.writeInt32NoTag(Array.getInt(array, i));
- }
- break;
- case TYPE_SINT32:
- for (int i = 0; i < arrayLength; i++) {
- output.writeSInt32NoTag(Array.getInt(array, i));
- }
- break;
- case TYPE_UINT32:
- for (int i = 0; i < arrayLength; i++) {
- output.writeUInt32NoTag(Array.getInt(array, i));
- }
- break;
- case TYPE_INT64:
- for (int i = 0; i < arrayLength; i++) {
- output.writeInt64NoTag(Array.getLong(array, i));
- }
- break;
- case TYPE_SINT64:
- for (int i = 0; i < arrayLength; i++) {
- output.writeSInt64NoTag(Array.getLong(array, i));
- }
- break;
- case TYPE_UINT64:
- for (int i = 0; i < arrayLength; i++) {
- output.writeUInt64NoTag(Array.getLong(array, i));
- }
- break;
- case TYPE_ENUM:
- for (int i = 0; i < arrayLength; i++) {
- output.writeEnumNoTag(Array.getInt(array, i));
- }
- break;
- default:
- throw new IllegalArgumentException("Unpackable type " + type);
- }
- } catch (IOException e) {
- // Should not happen.
- throw new IllegalStateException(e);
- }
- } else {
- throw new IllegalArgumentException("Unexpected repeated extension tag " + tag
- + ", unequal to both non-packed variant " + nonPackedTag
- + " and packed variant " + packedTag);
- }
- }
-
- private int computePackedDataSize(Object array) {
- int dataSize = 0;
- int arrayLength = Array.getLength(array);
- switch (type) {
- case TYPE_BOOL:
- // Bools are stored as int32 but just as 0 or 1, so 1 byte each.
- dataSize = arrayLength;
- break;
- case TYPE_FIXED32:
- case TYPE_SFIXED32:
- case TYPE_FLOAT:
- dataSize = arrayLength * CodedOutputByteBufferNano.LITTLE_ENDIAN_32_SIZE;
- break;
- case TYPE_FIXED64:
- case TYPE_SFIXED64:
- case TYPE_DOUBLE:
- dataSize = arrayLength * CodedOutputByteBufferNano.LITTLE_ENDIAN_64_SIZE;
- break;
- case TYPE_INT32:
- for (int i = 0; i < arrayLength; i++) {
- dataSize += CodedOutputByteBufferNano.computeInt32SizeNoTag(
- Array.getInt(array, i));
- }
- break;
- case TYPE_SINT32:
- for (int i = 0; i < arrayLength; i++) {
- dataSize += CodedOutputByteBufferNano.computeSInt32SizeNoTag(
- Array.getInt(array, i));
- }
- break;
- case TYPE_UINT32:
- for (int i = 0; i < arrayLength; i++) {
- dataSize += CodedOutputByteBufferNano.computeUInt32SizeNoTag(
- Array.getInt(array, i));
- }
- break;
- case TYPE_INT64:
- for (int i = 0; i < arrayLength; i++) {
- dataSize += CodedOutputByteBufferNano.computeInt64SizeNoTag(
- Array.getLong(array, i));
- }
- break;
- case TYPE_SINT64:
- for (int i = 0; i < arrayLength; i++) {
- dataSize += CodedOutputByteBufferNano.computeSInt64SizeNoTag(
- Array.getLong(array, i));
- }
- break;
- case TYPE_UINT64:
- for (int i = 0; i < arrayLength; i++) {
- dataSize += CodedOutputByteBufferNano.computeUInt64SizeNoTag(
- Array.getLong(array, i));
- }
- break;
- case TYPE_ENUM:
- for (int i = 0; i < arrayLength; i++) {
- dataSize += CodedOutputByteBufferNano.computeEnumSizeNoTag(
- Array.getInt(array, i));
- }
- break;
- default:
- throw new IllegalArgumentException("Unexpected non-packable type " + type);
- }
- return dataSize;
- }
-
- @Override
- protected int computeRepeatedSerializedSize(Object array) {
- if (tag == nonPackedTag) {
- // Use base implementation for non-packed data
- return super.computeRepeatedSerializedSize(array);
- } else if (tag == packedTag) {
- // Packed.
- int dataSize = computePackedDataSize(array);
- int payloadSize =
- dataSize + CodedOutputByteBufferNano.computeRawVarint32Size(dataSize);
- return payloadSize + CodedOutputByteBufferNano.computeRawVarint32Size(tag);
- } else {
- throw new IllegalArgumentException("Unexpected repeated extension tag " + tag
- + ", unequal to both non-packed variant " + nonPackedTag
- + " and packed variant " + packedTag);
- }
- }
-
- @Override
- protected final int computeSingularSerializedSize(Object value) {
- int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
- switch (type) {
- case TYPE_DOUBLE:
- Double doubleValue = (Double) value;
- return CodedOutputByteBufferNano.computeDoubleSize(fieldNumber, doubleValue);
- case TYPE_FLOAT:
- Float floatValue = (Float) value;
- return CodedOutputByteBufferNano.computeFloatSize(fieldNumber, floatValue);
- case TYPE_INT64:
- Long int64Value = (Long) value;
- return CodedOutputByteBufferNano.computeInt64Size(fieldNumber, int64Value);
- case TYPE_UINT64:
- Long uint64Value = (Long) value;
- return CodedOutputByteBufferNano.computeUInt64Size(fieldNumber, uint64Value);
- case TYPE_INT32:
- Integer int32Value = (Integer) value;
- return CodedOutputByteBufferNano.computeInt32Size(fieldNumber, int32Value);
- case TYPE_FIXED64:
- Long fixed64Value = (Long) value;
- return CodedOutputByteBufferNano.computeFixed64Size(fieldNumber, fixed64Value);
- case TYPE_FIXED32:
- Integer fixed32Value = (Integer) value;
- return CodedOutputByteBufferNano.computeFixed32Size(fieldNumber, fixed32Value);
- case TYPE_BOOL:
- Boolean boolValue = (Boolean) value;
- return CodedOutputByteBufferNano.computeBoolSize(fieldNumber, boolValue);
- case TYPE_STRING:
- String stringValue = (String) value;
- return CodedOutputByteBufferNano.computeStringSize(fieldNumber, stringValue);
- case TYPE_BYTES:
- byte[] bytesValue = (byte[]) value;
- return CodedOutputByteBufferNano.computeBytesSize(fieldNumber, bytesValue);
- case TYPE_UINT32:
- Integer uint32Value = (Integer) value;
- return CodedOutputByteBufferNano.computeUInt32Size(fieldNumber, uint32Value);
- case TYPE_ENUM:
- Integer enumValue = (Integer) value;
- return CodedOutputByteBufferNano.computeEnumSize(fieldNumber, enumValue);
- case TYPE_SFIXED32:
- Integer sfixed32Value = (Integer) value;
- return CodedOutputByteBufferNano.computeSFixed32Size(fieldNumber,
- sfixed32Value);
- case TYPE_SFIXED64:
- Long sfixed64Value = (Long) value;
- return CodedOutputByteBufferNano.computeSFixed64Size(fieldNumber,
- sfixed64Value);
- case TYPE_SINT32:
- Integer sint32Value = (Integer) value;
- return CodedOutputByteBufferNano.computeSInt32Size(fieldNumber, sint32Value);
- case TYPE_SINT64:
- Long sint64Value = (Long) value;
- return CodedOutputByteBufferNano.computeSInt64Size(fieldNumber, sint64Value);
- default:
- throw new IllegalArgumentException("Unknown type " + type);
- }
- }
- }
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/FieldArray.java b/javanano/src/main/java/com/google/protobuf/nano/FieldArray.java
deleted file mode 100644
index b49a97fa..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/FieldArray.java
+++ /dev/null
@@ -1,291 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2014 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;
-
-
-/**
- * A custom version of {@code android.util.SparseArray} with the minimal API
- * for storing {@link FieldData} objects.
- *
- * <p>This class is an internal implementation detail of nano and should not
- * be called directly by clients.
- *
- * Based on {@code android.support.v4.util.SpareArrayCompat}.
- */
-public final class FieldArray implements Cloneable {
- private static final FieldData DELETED = new FieldData();
- private boolean mGarbage = false;
-
- private int[] mFieldNumbers;
- private FieldData[] mData;
- private int mSize;
-
- /**
- * Creates a new FieldArray containing no fields.
- */
- FieldArray() {
- this(10);
- }
-
- /**
- * Creates a new FieldArray containing no mappings that will not
- * require any additional memory allocation to store the specified
- * number of mappings.
- */
- FieldArray(int initialCapacity) {
- initialCapacity = idealIntArraySize(initialCapacity);
- mFieldNumbers = new int[initialCapacity];
- mData = new FieldData[initialCapacity];
- mSize = 0;
- }
-
- /**
- * Gets the FieldData mapped from the specified fieldNumber, or <code>null</code>
- * if no such mapping has been made.
- */
- FieldData get(int fieldNumber) {
- int i = binarySearch(fieldNumber);
-
- if (i < 0 || mData[i] == DELETED) {
- return null;
- } else {
- return mData[i];
- }
- }
-
- /**
- * Removes the data from the specified fieldNumber, if there was any.
- */
- void remove(int fieldNumber) {
- int i = binarySearch(fieldNumber);
-
- if (i >= 0 && mData[i] != DELETED) {
- mData[i] = DELETED;
- mGarbage = true;
- }
- }
-
- private void gc() {
- int n = mSize;
- int o = 0;
- int[] keys = mFieldNumbers;
- FieldData[] values = mData;
-
- for (int i = 0; i < n; i++) {
- FieldData val = values[i];
-
- if (val != DELETED) {
- if (i != o) {
- keys[o] = keys[i];
- values[o] = val;
- values[i] = null;
- }
-
- o++;
- }
- }
-
- mGarbage = false;
- mSize = o;
- }
-
- /**
- * Adds a mapping from the specified fieldNumber to the specified data,
- * replacing the previous mapping if there was one.
- */
- void put(int fieldNumber, FieldData data) {
- int i = binarySearch(fieldNumber);
-
- if (i >= 0) {
- mData[i] = data;
- } else {
- i = ~i;
-
- if (i < mSize && mData[i] == DELETED) {
- mFieldNumbers[i] = fieldNumber;
- mData[i] = data;
- return;
- }
-
- if (mGarbage && mSize >= mFieldNumbers.length) {
- gc();
-
- // Search again because indices may have changed.
- i = ~ binarySearch(fieldNumber);
- }
-
- if (mSize >= mFieldNumbers.length) {
- int n = idealIntArraySize(mSize + 1);
-
- int[] nkeys = new int[n];
- FieldData[] nvalues = new FieldData[n];
-
- System.arraycopy(mFieldNumbers, 0, nkeys, 0, mFieldNumbers.length);
- System.arraycopy(mData, 0, nvalues, 0, mData.length);
-
- mFieldNumbers = nkeys;
- mData = nvalues;
- }
-
- if (mSize - i != 0) {
- System.arraycopy(mFieldNumbers, i, mFieldNumbers, i + 1, mSize - i);
- System.arraycopy(mData, i, mData, i + 1, mSize - i);
- }
-
- mFieldNumbers[i] = fieldNumber;
- mData[i] = data;
- mSize++;
- }
- }
-
- /**
- * Returns the number of key-value mappings that this FieldArray
- * currently stores.
- */
- int size() {
- if (mGarbage) {
- gc();
- }
-
- return mSize;
- }
-
- public boolean isEmpty() {
- return size() == 0;
- }
-
- /**
- * Given an index in the range <code>0...size()-1</code>, returns
- * the value from the <code>index</code>th key-value mapping that this
- * FieldArray stores.
- */
- FieldData dataAt(int index) {
- if (mGarbage) {
- gc();
- }
-
- return mData[index];
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof FieldArray)) {
- return false;
- }
-
- FieldArray other = (FieldArray) o;
- if (size() != other.size()) { // size() will call gc() if necessary.
- return false;
- }
- return arrayEquals(mFieldNumbers, other.mFieldNumbers, mSize) &&
- arrayEquals(mData, other.mData, mSize);
- }
-
- @Override
- public int hashCode() {
- if (mGarbage) {
- gc();
- }
- int result = 17;
- for (int i = 0; i < mSize; i++) {
- result = 31 * result + mFieldNumbers[i];
- result = 31 * result + mData[i].hashCode();
- }
- return result;
- }
-
- private int idealIntArraySize(int need) {
- return idealByteArraySize(need * 4) / 4;
- }
-
- private int idealByteArraySize(int need) {
- for (int i = 4; i < 32; i++)
- if (need <= (1 << i) - 12)
- return (1 << i) - 12;
-
- return need;
- }
-
- private int binarySearch(int value) {
- int lo = 0;
- int hi = mSize - 1;
-
- while (lo <= hi) {
- int mid = (lo + hi) >>> 1;
- int midVal = mFieldNumbers[mid];
-
- if (midVal < value) {
- lo = mid + 1;
- } else if (midVal > value) {
- hi = mid - 1;
- } else {
- return mid; // value found
- }
- }
- return ~lo; // value not present
- }
-
- private boolean arrayEquals(int[] a, int[] b, int size) {
- for (int i = 0; i < size; i++) {
- if (a[i] != b[i]) {
- return false;
- }
- }
- return true;
- }
-
- private boolean arrayEquals(FieldData[] a, FieldData[] b, int size) {
- for (int i = 0; i < size; i++) {
- if (!a[i].equals(b[i])) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public final FieldArray clone() {
- // Trigger GC so we compact and don't copy DELETED elements.
- int size = size();
- FieldArray clone = new FieldArray(size);
- System.arraycopy(mFieldNumbers, 0, clone.mFieldNumbers, 0, size);
- for (int i = 0; i < size; i++) {
- if (mData[i] != null) {
- clone.mData[i] = mData[i].clone();
- }
- }
- clone.mSize = size;
- return clone;
- }
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/FieldData.java b/javanano/src/main/java/com/google/protobuf/nano/FieldData.java
deleted file mode 100644
index ebebabc8..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/FieldData.java
+++ /dev/null
@@ -1,240 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2014 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;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Stores unknown fields. These might be extensions or fields that the generated API doesn't
- * know about yet.
- */
-class FieldData implements Cloneable {
- private Extension<?, ?> cachedExtension;
- private Object value;
- /** The serialised values for this object. Will be cleared if getValue is called */
- private List<UnknownFieldData> unknownFieldData;
-
- <T> FieldData(Extension<?, T> extension, T newValue) {
- cachedExtension = extension;
- value = newValue;
- }
-
- FieldData() {
- unknownFieldData = new ArrayList<UnknownFieldData>();
- }
-
- void addUnknownField(UnknownFieldData unknownField) {
- unknownFieldData.add(unknownField);
- }
-
- UnknownFieldData getUnknownField(int index) {
- if (unknownFieldData == null) {
- return null;
- }
- if (index < unknownFieldData.size()) {
- return unknownFieldData.get(index);
- }
- return null;
- }
-
- int getUnknownFieldSize() {
- if (unknownFieldData == null) {
- return 0;
- }
- return unknownFieldData.size();
- }
-
- <T> T getValue(Extension<?, T> extension) {
- if (value != null){
- if (cachedExtension != extension) { // Extension objects are singletons.
- throw new IllegalStateException(
- "Tried to getExtension with a differernt Extension.");
- }
- } else {
- cachedExtension = extension;
- value = extension.getValueFrom(unknownFieldData);
- unknownFieldData = null;
- }
- return (T) value;
- }
-
- <T> void setValue(Extension<?, T> extension, T newValue) {
- cachedExtension = extension;
- value = newValue;
- unknownFieldData = null;
- }
-
- int computeSerializedSize() {
- int size = 0;
- if (value != null) {
- size = cachedExtension.computeSerializedSize(value);
- } else {
- for (UnknownFieldData unknownField : unknownFieldData) {
- size += unknownField.computeSerializedSize();
- }
- }
- return size;
- }
-
- void writeTo(CodedOutputByteBufferNano output) throws IOException {
- if (value != null) {
- cachedExtension.writeTo(value, output);
- } else {
- for (UnknownFieldData unknownField : unknownFieldData) {
- unknownField.writeTo(output);
- }
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof FieldData)) {
- return false;
- }
-
- FieldData other = (FieldData) o;
- if (value != null && other.value != null) {
- // If both objects have deserialized values, compare those.
- // Since unknown fields are only compared if messages have generated equals methods
- // we know this will be a meaningful comparison (not identity) for all values.
- if (cachedExtension != other.cachedExtension) { // Extension objects are singletons.
- return false;
- }
- if (!cachedExtension.clazz.isArray()) {
- // Can't test (!cachedExtension.repeated) due to 'bytes' -> 'byte[]'
- return value.equals(other.value);
- }
- if (value instanceof byte[]) {
- return Arrays.equals((byte[]) value, (byte[]) other.value);
- } else if (value instanceof int[]) {
- return Arrays.equals((int[]) value, (int[]) other.value);
- } else if (value instanceof long[]) {
- return Arrays.equals((long[]) value, (long[]) other.value);
- } else if (value instanceof float[]) {
- return Arrays.equals((float[]) value, (float[]) other.value);
- } else if (value instanceof double[]) {
- return Arrays.equals((double[]) value, (double[]) other.value);
- } else if (value instanceof boolean[]) {
- return Arrays.equals((boolean[]) value, (boolean[]) other.value);
- } else {
- return Arrays.deepEquals((Object[]) value, (Object[]) other.value);
- }
- }
- if (unknownFieldData != null && other.unknownFieldData != null) {
- // If both objects have byte arrays compare those directly.
- return unknownFieldData.equals(other.unknownFieldData);
- }
- try {
- // As a last resort, serialize and compare the resulting byte arrays.
- return Arrays.equals(toByteArray(), other.toByteArray());
- } catch (IOException e) {
- // Should not happen.
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- try {
- // The only way to generate a consistent hash is to use the serialized form.
- result = 31 * result + Arrays.hashCode(toByteArray());
- } catch (IOException e) {
- // Should not happen.
- throw new IllegalStateException(e);
- }
- return result;
- }
-
- private byte[] toByteArray() throws IOException {
- byte[] result = new byte[computeSerializedSize()];
- CodedOutputByteBufferNano output = CodedOutputByteBufferNano.newInstance(result);
- writeTo(output);
- return result;
- }
-
- @Override
- public final FieldData clone() {
- FieldData clone = new FieldData();
- try {
- clone.cachedExtension = cachedExtension;
- if (unknownFieldData == null) {
- clone.unknownFieldData = null;
- } else {
- clone.unknownFieldData.addAll(unknownFieldData);
- }
-
- // Whether we need to deep clone value depends on its type. Primitive reference types
- // (e.g. Integer, Long etc.) are ok, since they're immutable. We need to clone arrays
- // and messages.
- if (value == null) {
- // No cloning required.
- } else if (value instanceof MessageNano) {
- clone.value = ((MessageNano) value).clone();
- } else if (value instanceof byte[]) {
- clone.value = ((byte[]) value).clone();
- } else if (value instanceof byte[][]) {
- byte[][] valueArray = (byte[][]) value;
- byte[][] cloneArray = new byte[valueArray.length][];
- clone.value = cloneArray;
- for (int i = 0; i < valueArray.length; i++) {
- cloneArray[i] = valueArray[i].clone();
- }
- } else if (value instanceof boolean[]) {
- clone.value = ((boolean[]) value).clone();
- } else if (value instanceof int[]) {
- clone.value = ((int[]) value).clone();
- } else if (value instanceof long[]) {
- clone.value = ((long[]) value).clone();
- } else if (value instanceof float[]) {
- clone.value = ((float[]) value).clone();
- } else if (value instanceof double[]) {
- clone.value = ((double[]) value).clone();
- } else if (value instanceof MessageNano[]) {
- MessageNano[] valueArray = (MessageNano[]) value;
- MessageNano[] cloneArray = new MessageNano[valueArray.length];
- clone.value = cloneArray;
- for (int i = 0; i < valueArray.length; i++) {
- cloneArray[i] = valueArray[i].clone();
- }
- }
- return clone;
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/InternalNano.java b/javanano/src/main/java/com/google/protobuf/nano/InternalNano.java
deleted file mode 100644
index 278368a0..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/InternalNano.java
+++ /dev/null
@@ -1,547 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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 com.google.protobuf.nano.MapFactories.MapFactory;
-
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The classes contained within are used internally by the Protocol Buffer
- * library and generated message implementations. They are public only because
- * those generated messages do not reside in the {@code protobuf} package.
- * Others should not use this class directly.
- *
- * @author kenton@google.com (Kenton Varda)
- */
-public final class InternalNano {
-
- public static final int TYPE_DOUBLE = 1;
- public static final int TYPE_FLOAT = 2;
- public static final int TYPE_INT64 = 3;
- public static final int TYPE_UINT64 = 4;
- public static final int TYPE_INT32 = 5;
- public static final int TYPE_FIXED64 = 6;
- public static final int TYPE_FIXED32 = 7;
- public static final int TYPE_BOOL = 8;
- public static final int TYPE_STRING = 9;
- public static final int TYPE_GROUP = 10;
- public static final int TYPE_MESSAGE = 11;
- public static final int TYPE_BYTES = 12;
- public static final int TYPE_UINT32 = 13;
- public static final int TYPE_ENUM = 14;
- public static final int TYPE_SFIXED32 = 15;
- public static final int TYPE_SFIXED64 = 16;
- public static final int TYPE_SINT32 = 17;
- public static final int TYPE_SINT64 = 18;
-
- static final Charset UTF_8 = Charset.forName("UTF-8");
- static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
-
- private InternalNano() {}
-
- /**
- * An object to provide synchronization when lazily initializing static fields
- * of {@link MessageNano} subclasses.
- * <p>
- * To enable earlier versions of ProGuard to inline short methods from a
- * generated MessageNano subclass to the call sites, that class must not have
- * a class initializer, which will be created if there is any static variable
- * initializers. To lazily initialize the static variables in a thread-safe
- * manner, the initialization code will synchronize on this object.
- */
- public static final Object LAZY_INIT_LOCK = new Object();
-
- /**
- * Helper called by generated code to construct default values for string
- * fields.
- * <p>
- * The protocol compiler does not actually contain a UTF-8 decoder -- it
- * just pushes UTF-8-encoded text around without touching it. The one place
- * where this presents a problem is when generating Java string literals.
- * Unicode characters in the string literal would normally need to be encoded
- * using a Unicode escape sequence, which would require decoding them.
- * To get around this, protoc instead embeds the UTF-8 bytes into the
- * generated code and leaves it to the runtime library to decode them.
- * <p>
- * It gets worse, though. If protoc just generated a byte array, like:
- * new byte[] {0x12, 0x34, 0x56, 0x78}
- * Java actually generates *code* which allocates an array and then fills
- * in each value. This is much less efficient than just embedding the bytes
- * directly into the bytecode. To get around this, we need another
- * work-around. String literals are embedded directly, so protoc actually
- * generates a string literal corresponding to the bytes. The easiest way
- * to do this is to use the ISO-8859-1 character set, which corresponds to
- * the first 256 characters of the Unicode range. Protoc can then use
- * good old CEscape to generate the string.
- * <p>
- * So we have a string literal which represents a set of bytes which
- * represents another string. This function -- stringDefaultValue --
- * converts from the generated string to the string we actually want. The
- * generated code calls this automatically.
- */
- public static String stringDefaultValue(String bytes) {
- return new String(bytes.getBytes(ISO_8859_1), InternalNano.UTF_8);
- }
-
- /**
- * Helper called by generated code to construct default values for bytes
- * fields.
- * <p>
- * This is a lot like {@link #stringDefaultValue}, but for bytes fields.
- * In this case we only need the second of the two hacks -- allowing us to
- * embed raw bytes as a string literal with ISO-8859-1 encoding.
- */
- public static byte[] bytesDefaultValue(String bytes) {
- return bytes.getBytes(ISO_8859_1);
- }
-
- /**
- * Helper function to convert a string into UTF-8 while turning the
- * UnsupportedEncodingException to a RuntimeException.
- */
- public static byte[] copyFromUtf8(final String text) {
- return text.getBytes(InternalNano.UTF_8);
- }
-
- /**
- * Checks repeated int field equality; null-value and 0-length fields are
- * considered equal.
- */
- public static boolean equals(int[] field1, int[] field2) {
- if (field1 == null || field1.length == 0) {
- return field2 == null || field2.length == 0;
- } else {
- return Arrays.equals(field1, field2);
- }
- }
-
- /**
- * Checks repeated long field equality; null-value and 0-length fields are
- * considered equal.
- */
- public static boolean equals(long[] field1, long[] field2) {
- if (field1 == null || field1.length == 0) {
- return field2 == null || field2.length == 0;
- } else {
- return Arrays.equals(field1, field2);
- }
- }
-
- /**
- * Checks repeated float field equality; null-value and 0-length fields are
- * considered equal.
- */
- public static boolean equals(float[] field1, float[] field2) {
- if (field1 == null || field1.length == 0) {
- return field2 == null || field2.length == 0;
- } else {
- return Arrays.equals(field1, field2);
- }
- }
-
- /**
- * Checks repeated double field equality; null-value and 0-length fields are
- * considered equal.
- */
- public static boolean equals(double[] field1, double[] field2) {
- if (field1 == null || field1.length == 0) {
- return field2 == null || field2.length == 0;
- } else {
- return Arrays.equals(field1, field2);
- }
- }
-
- /**
- * Checks repeated boolean field equality; null-value and 0-length fields are
- * considered equal.
- */
- public static boolean equals(boolean[] field1, boolean[] field2) {
- if (field1 == null || field1.length == 0) {
- return field2 == null || field2.length == 0;
- } else {
- return Arrays.equals(field1, field2);
- }
- }
-
- /**
- * Checks repeated bytes field equality. Only non-null elements are tested.
- * Returns true if the two fields have the same sequence of non-null
- * elements. Null-value fields and fields of any length with only null
- * elements are considered equal.
- */
- public static boolean equals(byte[][] field1, byte[][] field2) {
- int index1 = 0;
- int length1 = field1 == null ? 0 : field1.length;
- int index2 = 0;
- int length2 = field2 == null ? 0 : field2.length;
- while (true) {
- while (index1 < length1 && field1[index1] == null) {
- index1++;
- }
- while (index2 < length2 && field2[index2] == null) {
- index2++;
- }
- boolean atEndOf1 = index1 >= length1;
- boolean atEndOf2 = index2 >= length2;
- if (atEndOf1 && atEndOf2) {
- // no more non-null elements to test in both arrays
- return true;
- } else if (atEndOf1 != atEndOf2) {
- // one of the arrays have extra non-null elements
- return false;
- } else if (!Arrays.equals(field1[index1], field2[index2])) {
- // element mismatch
- return false;
- }
- index1++;
- index2++;
- }
- }
-
- /**
- * Checks repeated string/message field equality. Only non-null elements are
- * tested. Returns true if the two fields have the same sequence of non-null
- * elements. Null-value fields and fields of any length with only null
- * elements are considered equal.
- */
- public static boolean equals(Object[] field1, Object[] field2) {
- int index1 = 0;
- int length1 = field1 == null ? 0 : field1.length;
- int index2 = 0;
- int length2 = field2 == null ? 0 : field2.length;
- while (true) {
- while (index1 < length1 && field1[index1] == null) {
- index1++;
- }
- while (index2 < length2 && field2[index2] == null) {
- index2++;
- }
- boolean atEndOf1 = index1 >= length1;
- boolean atEndOf2 = index2 >= length2;
- if (atEndOf1 && atEndOf2) {
- // no more non-null elements to test in both arrays
- return true;
- } else if (atEndOf1 != atEndOf2) {
- // one of the arrays have extra non-null elements
- return false;
- } else if (!field1[index1].equals(field2[index2])) {
- // element mismatch
- return false;
- }
- index1++;
- index2++;
- }
- }
-
- /**
- * Computes the hash code of a repeated int field. Null-value and 0-length
- * fields have the same hash code.
- */
- public static int hashCode(int[] field) {
- return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
- }
-
- /**
- * Computes the hash code of a repeated long field. Null-value and 0-length
- * fields have the same hash code.
- */
- public static int hashCode(long[] field) {
- return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
- }
-
- /**
- * Computes the hash code of a repeated float field. Null-value and 0-length
- * fields have the same hash code.
- */
- public static int hashCode(float[] field) {
- return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
- }
-
- /**
- * Computes the hash code of a repeated double field. Null-value and 0-length
- * fields have the same hash code.
- */
- public static int hashCode(double[] field) {
- return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
- }
-
- /**
- * Computes the hash code of a repeated boolean field. Null-value and 0-length
- * fields have the same hash code.
- */
- public static int hashCode(boolean[] field) {
- return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
- }
-
- /**
- * Computes the hash code of a repeated bytes field. Only the sequence of all
- * non-null elements are used in the computation. Null-value fields and fields
- * of any length with only null elements have the same hash code.
- */
- public static int hashCode(byte[][] field) {
- int result = 0;
- for (int i = 0, size = field == null ? 0 : field.length; i < size; i++) {
- byte[] element = field[i];
- if (element != null) {
- result = 31 * result + Arrays.hashCode(element);
- }
- }
- return result;
- }
-
- /**
- * Computes the hash code of a repeated string/message field. Only the
- * sequence of all non-null elements are used in the computation. Null-value
- * fields and fields of any length with only null elements have the same hash
- * code.
- */
- public static int hashCode(Object[] field) {
- int result = 0;
- for (int i = 0, size = field == null ? 0 : field.length; i < size; i++) {
- Object element = field[i];
- if (element != null) {
- result = 31 * result + element.hashCode();
- }
- }
- return result;
- }
- private static Object primitiveDefaultValue(int type) {
- switch (type) {
- case TYPE_BOOL:
- return Boolean.FALSE;
- case TYPE_BYTES:
- return WireFormatNano.EMPTY_BYTES;
- case TYPE_STRING:
- return "";
- case TYPE_FLOAT:
- return Float.valueOf(0);
- case TYPE_DOUBLE:
- return Double.valueOf(0);
- case TYPE_ENUM:
- case TYPE_FIXED32:
- case TYPE_INT32:
- case TYPE_UINT32:
- case TYPE_SINT32:
- case TYPE_SFIXED32:
- return Integer.valueOf(0);
- case TYPE_INT64:
- case TYPE_UINT64:
- case TYPE_SINT64:
- case TYPE_FIXED64:
- case TYPE_SFIXED64:
- return Long.valueOf(0L);
- case TYPE_MESSAGE:
- case TYPE_GROUP:
- default:
- throw new IllegalArgumentException(
- "Type: " + type + " is not a primitive type.");
- }
- }
-
- /**
- * Merges the map entry into the map field. Note this is only supposed to
- * be called by generated messages.
- *
- * @param map the map field; may be null, in which case a map will be
- * instantiated using the {@link MapFactories.MapFactory}
- * @param input the input byte buffer
- * @param keyType key type, as defined in InternalNano.TYPE_*
- * @param valueType value type, as defined in InternalNano.TYPE_*
- * @param value an new instance of the value, if the value is a TYPE_MESSAGE;
- * otherwise this parameter can be null and will be ignored.
- * @param keyTag wire tag for the key
- * @param valueTag wire tag for the value
- * @return the map field
- * @throws IOException
- */
- @SuppressWarnings("unchecked")
- public static final <K, V> Map<K, V> mergeMapEntry(
- CodedInputByteBufferNano input,
- Map<K, V> map,
- MapFactory mapFactory,
- int keyType,
- int valueType,
- V value,
- int keyTag,
- int valueTag) throws IOException {
- map = mapFactory.forMap(map);
- final int length = input.readRawVarint32();
- final int oldLimit = input.pushLimit(length);
- K key = null;
- while (true) {
- int tag = input.readTag();
- if (tag == 0) {
- break;
- }
- if (tag == keyTag) {
- key = (K) input.readPrimitiveField(keyType);
- } else if (tag == valueTag) {
- if (valueType == TYPE_MESSAGE) {
- input.readMessage((MessageNano) value);
- } else {
- value = (V) input.readPrimitiveField(valueType);
- }
- } else {
- if (!input.skipField(tag)) {
- break;
- }
- }
- }
- input.checkLastTagWas(0);
- input.popLimit(oldLimit);
-
- if (key == null) {
- // key can only be primitive types.
- key = (K) primitiveDefaultValue(keyType);
- }
-
- if (value == null) {
- // message type value will be initialized by code-gen.
- value = (V) primitiveDefaultValue(valueType);
- }
-
- map.put(key, value);
- return map;
- }
-
- public static <K, V> void serializeMapField(
- CodedOutputByteBufferNano output,
- Map<K, V> map, int number, int keyType, int valueType)
- throws IOException {
- for (Entry<K, V> entry: map.entrySet()) {
- K key = entry.getKey();
- V value = entry.getValue();
- if (key == null || value == null) {
- throw new IllegalStateException(
- "keys and values in maps cannot be null");
- }
- int entrySize =
- CodedOutputByteBufferNano.computeFieldSize(1, keyType, key) +
- CodedOutputByteBufferNano.computeFieldSize(2, valueType, value);
- output.writeTag(number, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
- output.writeRawVarint32(entrySize);
- output.writeField(1, keyType, key);
- output.writeField(2, valueType, value);
- }
- }
-
- public static <K, V> int computeMapFieldSize(
- Map<K, V> map, int number, int keyType, int valueType) {
- int size = 0;
- int tagSize = CodedOutputByteBufferNano.computeTagSize(number);
- for (Entry<K, V> entry: map.entrySet()) {
- K key = entry.getKey();
- V value = entry.getValue();
- if (key == null || value == null) {
- throw new IllegalStateException(
- "keys and values in maps cannot be null");
- }
- int entrySize =
- CodedOutputByteBufferNano.computeFieldSize(1, keyType, key) +
- CodedOutputByteBufferNano.computeFieldSize(2, valueType, value);
- size += tagSize + entrySize
- + CodedOutputByteBufferNano.computeRawVarint32Size(entrySize);
- }
- return size;
- }
-
- /**
- * Checks whether two {@link Map} are equal. We don't use the default equals
- * method of {@link Map} because it compares by identity not by content for
- * byte arrays.
- */
- public static <K, V> boolean equals(Map<K, V> a, Map<K, V> b) {
- if (a == b) {
- return true;
- }
- if (a == null) {
- return b.size() == 0;
- }
- if (b == null) {
- return a.size() == 0;
- }
- if (a.size() != b.size()) {
- return false;
- }
- for (Entry<K, V> entry : a.entrySet()) {
- if (!b.containsKey(entry.getKey())) {
- return false;
- }
- if (!equalsMapValue(entry.getValue(), b.get(entry.getKey()))) {
- return false;
- }
- }
- return true;
- }
-
- private static boolean equalsMapValue(Object a, Object b) {
- if (a == null || b == null) {
- throw new IllegalStateException(
- "keys and values in maps cannot be null");
- }
- if (a instanceof byte[] && b instanceof byte[]) {
- return Arrays.equals((byte[]) a, (byte[]) b);
- }
- return a.equals(b);
- }
-
- public static <K, V> int hashCode(Map<K, V> map) {
- if (map == null) {
- return 0;
- }
- int result = 0;
- for (Entry<K, V> entry : map.entrySet()) {
- result += hashCodeForMap(entry.getKey())
- ^ hashCodeForMap(entry.getValue());
- }
- return result;
- }
-
- private static int hashCodeForMap(Object o) {
- if (o instanceof byte[]) {
- return Arrays.hashCode((byte[]) o);
- }
- return o.hashCode();
- }
-
- // This avoids having to make FieldArray public.
- public static void cloneUnknownFieldData(ExtendableMessageNano original,
- ExtendableMessageNano cloned) {
- if (original.unknownFieldData != null) {
- cloned.unknownFieldData = (FieldArray) original.unknownFieldData.clone();
- }
- }
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java b/javanano/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java
deleted file mode 100644
index 9a83d6d3..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java
+++ /dev/null
@@ -1,93 +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;
-
-/**
- * Thrown when a protocol message being parsed is invalid in some way,
- * e.g. it contains a malformed varint or a negative byte length.
- *
- * @author kenton@google.com Kenton Varda
- */
-public class InvalidProtocolBufferNanoException extends IOException {
- private static final long serialVersionUID = -1616151763072450476L;
-
- public InvalidProtocolBufferNanoException(final String description) {
- super(description);
- }
-
- static InvalidProtocolBufferNanoException truncatedMessage() {
- return new InvalidProtocolBufferNanoException(
- "While parsing a protocol message, the input ended unexpectedly " +
- "in the middle of a field. This could mean either that the " +
- "input has been truncated or that an embedded message " +
- "misreported its own length.");
- }
-
- static InvalidProtocolBufferNanoException negativeSize() {
- return new InvalidProtocolBufferNanoException(
- "CodedInputStream encountered an embedded string or message " +
- "which claimed to have negative size.");
- }
-
- static InvalidProtocolBufferNanoException malformedVarint() {
- return new InvalidProtocolBufferNanoException(
- "CodedInputStream encountered a malformed varint.");
- }
-
- static InvalidProtocolBufferNanoException invalidTag() {
- return new InvalidProtocolBufferNanoException(
- "Protocol message contained an invalid tag (zero).");
- }
-
- static InvalidProtocolBufferNanoException invalidEndTag() {
- return new InvalidProtocolBufferNanoException(
- "Protocol message end-group tag did not match expected tag.");
- }
-
- static InvalidProtocolBufferNanoException invalidWireType() {
- return new InvalidProtocolBufferNanoException(
- "Protocol message tag had invalid wire type.");
- }
-
- static InvalidProtocolBufferNanoException recursionLimitExceeded() {
- return new InvalidProtocolBufferNanoException(
- "Protocol message had too many levels of nesting. May be malicious. " +
- "Use CodedInputStream.setRecursionLimit() to increase the depth limit.");
- }
-
- static InvalidProtocolBufferNanoException sizeLimitExceeded() {
- return new InvalidProtocolBufferNanoException(
- "Protocol message was too large. May be malicious. " +
- "Use CodedInputStream.setSizeLimit() to increase the size limit.");
- }
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/MapFactories.java b/javanano/src/main/java/com/google/protobuf/nano/MapFactories.java
deleted file mode 100644
index 98fa4877..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/MapFactories.java
+++ /dev/null
@@ -1,67 +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.util.HashMap;
-import java.util.Map;
-
-/**
- * Utility class for maps support.
- */
-public final class MapFactories {
- public static interface MapFactory {
- <K, V> Map<K, V> forMap(Map<K, V> oldMap);
- }
-
- // NOTE(liujisi): The factory setter is temporarily marked as package private.
- // The way to provide customized implementations of maps for different
- // platforms are still under discussion. Mark it as private to avoid exposing
- // the API in proto3 alpha release.
- /* public */ static void setMapFactory(MapFactory newMapFactory) {
- mapFactory = newMapFactory;
- }
-
- public static MapFactory getMapFactory() {
- return mapFactory;
- }
-
- private static class DefaultMapFactory implements MapFactory {
- public <K, V> Map<K, V> forMap(Map<K, V> oldMap) {
- if (oldMap == null) {
- return new HashMap<K, V>();
- }
- return oldMap;
- }
- }
- private static volatile MapFactory mapFactory = new DefaultMapFactory();
-
- private MapFactories() {}
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/MessageNano.java b/javanano/src/main/java/com/google/protobuf/nano/MessageNano.java
deleted file mode 100644
index 23475027..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/MessageNano.java
+++ /dev/null
@@ -1,198 +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;
-import java.util.Arrays;
-
-/**
- * Abstract interface implemented by Protocol Message objects.
- *
- * @author wink@google.com Wink Saville
- */
-public abstract class MessageNano {
- protected volatile int cachedSize = -1;
-
- /**
- * Get the number of bytes required to encode this message.
- * Returns the cached size or calls getSerializedSize which
- * sets the cached size. This is used internally when serializing
- * so the size is only computed once. If a member is modified
- * then this could be stale call getSerializedSize if in doubt.
- */
- public int getCachedSize() {
- if (cachedSize < 0) {
- // getSerializedSize sets cachedSize
- getSerializedSize();
- }
- return cachedSize;
- }
-
- /**
- * Computes the number of bytes required to encode this message.
- * The size is cached and the cached result can be retrieved
- * using getCachedSize().
- */
- public int getSerializedSize() {
- int size = computeSerializedSize();
- cachedSize = size;
- return size;
- }
-
- /**
- * Computes the number of bytes required to encode this message. This does not update the
- * cached size.
- */
- protected int computeSerializedSize() {
- // This is overridden if the generated message has serialized fields.
- return 0;
- }
-
- /**
- * Serializes the message and writes it to {@code output}.
- *
- * @param output the output to receive the serialized form.
- * @throws IOException if an error occurred writing to {@code output}.
- */
- public void writeTo(CodedOutputByteBufferNano output) throws IOException {
- // Does nothing by default. Overridden by subclasses which have data to write.
- }
-
- /**
- * Parse {@code input} as a message of this type and merge it with the
- * message being built.
- */
- public abstract MessageNano mergeFrom(CodedInputByteBufferNano input) throws IOException;
-
- /**
- * Serialize to a byte array.
- * @return byte array with the serialized data.
- */
- public static final byte[] toByteArray(MessageNano msg) {
- final byte[] result = new byte[msg.getSerializedSize()];
- toByteArray(msg, result, 0, result.length);
- return result;
- }
-
- /**
- * Serialize to a byte array starting at offset through length. The
- * method getSerializedSize must have been called prior to calling
- * this method so the proper length is know. If an attempt to
- * write more than length bytes OutOfSpaceException will be thrown
- * and if length bytes are not written then IllegalStateException
- * is thrown.
- */
- public static final void toByteArray(MessageNano msg, byte[] data, int offset, int length) {
- try {
- final CodedOutputByteBufferNano output =
- CodedOutputByteBufferNano.newInstance(data, offset, length);
- msg.writeTo(output);
- output.checkNoSpaceLeft();
- } catch (IOException e) {
- throw new RuntimeException("Serializing to a byte array threw an IOException "
- + "(should never happen).", e);
- }
- }
-
- /**
- * Parse {@code data} as a message of this type and merge it with the
- * message being built.
- */
- public static final <T extends MessageNano> T mergeFrom(T msg, final byte[] data)
- throws InvalidProtocolBufferNanoException {
- return mergeFrom(msg, data, 0, data.length);
- }
-
- /**
- * Parse {@code data} as a message of this type and merge it with the
- * message being built.
- */
- public static final <T extends MessageNano> T mergeFrom(T msg, final byte[] data,
- final int off, final int len) throws InvalidProtocolBufferNanoException {
- try {
- final CodedInputByteBufferNano input =
- CodedInputByteBufferNano.newInstance(data, off, len);
- msg.mergeFrom(input);
- input.checkLastTagWas(0);
- return msg;
- } catch (InvalidProtocolBufferNanoException e) {
- throw e;
- } catch (IOException e) {
- throw new RuntimeException("Reading from a byte array threw an IOException (should "
- + "never happen).");
- }
- }
-
- /**
- * Compares two {@code MessageNano}s and returns true if the message's are the same class and
- * have serialized form equality (i.e. all of the field values are the same).
- */
- public static final boolean messageNanoEquals(MessageNano a, MessageNano b) {
- if (a == b) {
- return true;
- }
- if (a == null || b == null) {
- return false;
- }
- if (a.getClass() != b.getClass()) {
- return false;
- }
- final int serializedSize = a.getSerializedSize();
- if (b.getSerializedSize() != serializedSize) {
- return false;
- }
- final byte[] aByteArray = new byte[serializedSize];
- final byte[] bByteArray = new byte[serializedSize];
- toByteArray(a, aByteArray, 0, serializedSize);
- toByteArray(b, bByteArray, 0, serializedSize);
- return Arrays.equals(aByteArray, bByteArray);
- }
-
- /**
- * Returns a string that is (mostly) compatible with ProtoBuffer's TextFormat. Note that groups
- * (which are deprecated) are not serialized with the correct field name.
- *
- * <p>This is implemented using reflection, so it is not especially fast nor is it guaranteed
- * to find all fields if you have method removal turned on for proguard.
- */
- @Override
- public String toString() {
- return MessageNanoPrinter.print(this);
- }
-
- /**
- * Provides support for cloning. This only works if you specify the generate_clone method.
- */
- @Override
- public MessageNano clone() throws CloneNotSupportedException {
- return (MessageNano) super.clone();
- }
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java b/javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
deleted file mode 100644
index 5f329f02..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
+++ /dev/null
@@ -1,275 +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.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Map;
-
-/**
- * Static helper methods for printing nano protos.
- *
- * @author flynn@google.com Andrew Flynn
- */
-public final class MessageNanoPrinter {
- // Do not allow instantiation
- private MessageNanoPrinter() {}
-
- private static final String INDENT = " ";
- private static final int MAX_STRING_LEN = 200;
-
- /**
- * Returns an text representation of a MessageNano suitable for debugging. The returned string
- * is mostly compatible with Protocol Buffer's TextFormat (as provided by non-nano protocol
- * buffers) -- groups (which are deprecated) are output with an underscore name (e.g. foo_bar
- * instead of FooBar) and will thus not parse.
- *
- * <p>Employs Java reflection on the given object and recursively prints primitive fields,
- * groups, and messages.</p>
- */
- public static <T extends MessageNano> String print(T message) {
- if (message == null) {
- return "";
- }
-
- StringBuffer buf = new StringBuffer();
- try {
- print(null, message, new StringBuffer(), buf);
- } catch (IllegalAccessException e) {
- return "Error printing proto: " + e.getMessage();
- } catch (InvocationTargetException e) {
- return "Error printing proto: " + e.getMessage();
- }
- return buf.toString();
- }
-
- /**
- * Function that will print the given message/field into the StringBuffer.
- * Meant to be called recursively.
- *
- * @param identifier the identifier to use, or {@code null} if this is the root message to
- * print.
- * @param object the value to print. May in fact be a primitive value or byte array and not a
- * message.
- * @param indentBuf the indentation each line should begin with.
- * @param buf the output buffer.
- */
- private static void print(String identifier, Object object,
- StringBuffer indentBuf, StringBuffer buf) throws IllegalAccessException,
- InvocationTargetException {
- if (object == null) {
- // This can happen if...
- // - we're about to print a message, String, or byte[], but it not present;
- // - we're about to print a primitive, but "reftype" optional style is enabled, and
- // the field is unset.
- // In both cases the appropriate behavior is to output nothing.
- } else if (object instanceof MessageNano) { // Nano proto message
- int origIndentBufLength = indentBuf.length();
- if (identifier != null) {
- buf.append(indentBuf).append(deCamelCaseify(identifier)).append(" <\n");
- indentBuf.append(INDENT);
- }
- Class<?> clazz = object.getClass();
-
- // Proto fields follow one of two formats:
- //
- // 1) Public, non-static variables that do not begin or end with '_'
- // Find and print these using declared public fields
- for (Field field : clazz.getFields()) {
- int modifiers = field.getModifiers();
- String fieldName = field.getName();
- if ("cachedSize".equals(fieldName)) {
- // TODO(bduff): perhaps cachedSize should have a more obscure name.
- continue;
- }
-
- if ((modifiers & Modifier.PUBLIC) == Modifier.PUBLIC
- && (modifiers & Modifier.STATIC) != Modifier.STATIC
- && !fieldName.startsWith("_")
- && !fieldName.endsWith("_")) {
- Class<?> fieldType = field.getType();
- Object value = field.get(object);
-
- if (fieldType.isArray()) {
- Class<?> arrayType = fieldType.getComponentType();
-
- // bytes is special since it's not repeated, but is represented by an array
- if (arrayType == byte.class) {
- print(fieldName, value, indentBuf, buf);
- } else {
- int len = value == null ? 0 : Array.getLength(value);
- for (int i = 0; i < len; i++) {
- Object elem = Array.get(value, i);
- print(fieldName, elem, indentBuf, buf);
- }
- }
- } else {
- print(fieldName, value, indentBuf, buf);
- }
- }
- }
-
- // 2) Fields that are accessed via getter methods (when accessors
- // mode is turned on)
- // Find and print these using getter methods.
- for (Method method : clazz.getMethods()) {
- String name = method.getName();
- // Check for the setter accessor method since getters and hazzers both have
- // non-proto-field name collisions (hashCode() and getSerializedSize())
- if (name.startsWith("set")) {
- String subfieldName = name.substring(3);
-
- Method hazzer = null;
- try {
- hazzer = clazz.getMethod("has" + subfieldName);
- } catch (NoSuchMethodException e) {
- continue;
- }
- // If hazzer doesn't exist or returns false, no need to continue
- if (!(Boolean) hazzer.invoke(object)) {
- continue;
- }
-
- Method getter = null;
- try {
- getter = clazz.getMethod("get" + subfieldName);
- } catch (NoSuchMethodException e) {
- continue;
- }
-
- print(subfieldName, getter.invoke(object), indentBuf, buf);
- }
- }
- if (identifier != null) {
- indentBuf.setLength(origIndentBufLength);
- buf.append(indentBuf).append(">\n");
- }
- } else if (object instanceof Map) {
- Map<?,?> map = (Map<?,?>) object;
- identifier = deCamelCaseify(identifier);
-
- for (Map.Entry<?,?> entry : map.entrySet()) {
- buf.append(indentBuf).append(identifier).append(" <\n");
- int origIndentBufLength = indentBuf.length();
- indentBuf.append(INDENT);
- print("key", entry.getKey(), indentBuf, buf);
- print("value", entry.getValue(), indentBuf, buf);
- indentBuf.setLength(origIndentBufLength);
- buf.append(indentBuf).append(">\n");
- }
- } else {
- // Non-null primitive value
- identifier = deCamelCaseify(identifier);
- buf.append(indentBuf).append(identifier).append(": ");
- if (object instanceof String) {
- String stringMessage = sanitizeString((String) object);
- buf.append("\"").append(stringMessage).append("\"");
- } else if (object instanceof byte[]) {
- appendQuotedBytes((byte[]) object, buf);
- } else {
- buf.append(object);
- }
- buf.append("\n");
- }
- }
-
- /**
- * Converts an identifier of the format "FieldName" into "field_name".
- */
- private static String deCamelCaseify(String identifier) {
- StringBuffer out = new StringBuffer();
- for (int i = 0; i < identifier.length(); i++) {
- char currentChar = identifier.charAt(i);
- if (i == 0) {
- out.append(Character.toLowerCase(currentChar));
- } else if (Character.isUpperCase(currentChar)) {
- out.append('_').append(Character.toLowerCase(currentChar));
- } else {
- out.append(currentChar);
- }
- }
- return out.toString();
- }
-
- /**
- * Shortens and escapes the given string.
- */
- private static String sanitizeString(String str) {
- if (!str.startsWith("http") && str.length() > MAX_STRING_LEN) {
- // Trim non-URL strings.
- str = str.substring(0, MAX_STRING_LEN) + "[...]";
- }
- return escapeString(str);
- }
-
- /**
- * Escape everything except for low ASCII code points.
- */
- private static String escapeString(String str) {
- int strLen = str.length();
- StringBuilder b = new StringBuilder(strLen);
- for (int i = 0; i < strLen; i++) {
- char original = str.charAt(i);
- if (original >= ' ' && original <= '~' && original != '"' && original != '\'') {
- b.append(original);
- } else {
- b.append(String.format("\\u%04x", (int) original));
- }
- }
- return b.toString();
- }
-
- /**
- * Appends a quoted byte array to the provided {@code StringBuffer}.
- */
- private static void appendQuotedBytes(byte[] bytes, StringBuffer builder) {
- if (bytes == null) {
- builder.append("\"\"");
- return;
- }
-
- builder.append('"');
- for (int i = 0; i < bytes.length; ++i) {
- int ch = bytes[i] & 0xff;
- if (ch == '\\' || ch == '"') {
- builder.append('\\').append((char) ch);
- } else if (ch >= 32 && ch < 127) {
- builder.append((char) ch);
- } else {
- builder.append(String.format("\\%03o", ch));
- }
- }
- builder.append('"');
- }
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/UnknownFieldData.java b/javanano/src/main/java/com/google/protobuf/nano/UnknownFieldData.java
deleted file mode 100644
index b1678d1b..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/UnknownFieldData.java
+++ /dev/null
@@ -1,88 +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;
-import java.util.Arrays;
-
-/**
- * Stores unknown fields. These might be extensions or fields that the generated
- * API doesn't know about yet.
- *
- * @author bduff@google.com (Brian Duff)
- */
-final class UnknownFieldData {
-
- final int tag;
- /**
- * Important: this should be treated as immutable, even though it's possible
- * to change the array values.
- */
- final byte[] bytes;
-
- UnknownFieldData(int tag, byte[] bytes) {
- this.tag = tag;
- this.bytes = bytes;
- }
-
- int computeSerializedSize() {
- int size = 0;
- size += CodedOutputByteBufferNano.computeRawVarint32Size(tag);
- size += bytes.length;
- return size;
- }
-
- void writeTo(CodedOutputByteBufferNano output) throws IOException {
- output.writeRawVarint32(tag);
- output.writeRawBytes(bytes);
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof UnknownFieldData)) {
- return false;
- }
-
- UnknownFieldData other = (UnknownFieldData) o;
- return tag == other.tag && Arrays.equals(bytes, other.bytes);
- }
-
- @Override
- public int hashCode() {
- int result = 17;
- result = 31 * result + tag;
- result = 31 * result + Arrays.hashCode(bytes);
- return result;
- }
-}
diff --git a/javanano/src/main/java/com/google/protobuf/nano/WireFormatNano.java b/javanano/src/main/java/com/google/protobuf/nano/WireFormatNano.java
deleted file mode 100644
index bbb6370a..00000000
--- a/javanano/src/main/java/com/google/protobuf/nano/WireFormatNano.java
+++ /dev/null
@@ -1,124 +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;
-
-/**
- * This class is used internally by the Protocol Buffer library and generated
- * message implementations. It is public only because those generated messages
- * do not reside in the {@code protobuf} package. Others should not use this
- * class directly.
- *
- * This class contains constants and helper functions useful for dealing with
- * the Protocol Buffer wire format.
- *
- * @author kenton@google.com Kenton Varda
- */
-public final class WireFormatNano {
- // Do not allow instantiation.
- private WireFormatNano() {}
-
- static final int WIRETYPE_VARINT = 0;
- static final int WIRETYPE_FIXED64 = 1;
- static final int WIRETYPE_LENGTH_DELIMITED = 2;
- static final int WIRETYPE_START_GROUP = 3;
- static final int WIRETYPE_END_GROUP = 4;
- static final int WIRETYPE_FIXED32 = 5;
-
- static final int TAG_TYPE_BITS = 3;
- static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;
-
- /** Given a tag value, determines the wire type (the lower 3 bits). */
- static int getTagWireType(final int tag) {
- return tag & TAG_TYPE_MASK;
- }
-
- /** Given a tag value, determines the field number (the upper 29 bits). */
- public static int getTagFieldNumber(final int tag) {
- return tag >>> TAG_TYPE_BITS;
- }
-
- /** Makes a tag value given a field number and wire type. */
- static int makeTag(final int fieldNumber, final int wireType) {
- return (fieldNumber << TAG_TYPE_BITS) | wireType;
- }
-
- public static final int EMPTY_INT_ARRAY[] = {};
- public static final long EMPTY_LONG_ARRAY[] = {};
- public static final float EMPTY_FLOAT_ARRAY[] = {};
- public static final double EMPTY_DOUBLE_ARRAY[] = {};
- public static final boolean EMPTY_BOOLEAN_ARRAY[] = {};
- public static final String EMPTY_STRING_ARRAY[] = {};
- public static final byte[] EMPTY_BYTES_ARRAY[] = {};
- public static final byte[] EMPTY_BYTES = {};
-
- /**
- * Parses an unknown field. This implementation skips the field.
- *
- * <p>Generated messages will call this for unknown fields if the store_unknown_fields
- * option is off.
- *
- * @return {@literal true} unless the tag is an end-group tag.
- */
- public static boolean parseUnknownField(
- final CodedInputByteBufferNano input,
- final int tag) throws IOException {
- return input.skipField(tag);
- }
-
- /**
- * Computes the array length of a repeated field. We assume that in the common case repeated
- * fields are contiguously serialized but we still correctly handle interspersed values of a
- * repeated field (but with extra allocations).
- *
- * Rewinds to current input position before returning.
- *
- * @param input stream input, pointing to the byte after the first tag
- * @param tag repeated field tag just read
- * @return length of array
- * @throws IOException
- */
- public static final int getRepeatedFieldArrayLength(
- final CodedInputByteBufferNano input,
- final int tag) throws IOException {
- int arrayLength = 1;
- int startPos = input.getPosition();
- input.skipField(tag);
- while (input.readTag() == tag) {
- input.skipField(tag);
- arrayLength++;
- }
- input.rewindToPosition(startPos);
- return arrayLength;
- }
-
-}