Forked the coded input/output streams from the google proto buff project so that we don't need them as a dependency and also because we want to do some optimizations to them.
git-svn-id: https://svn.apache.org/repos/asf/activemq/sandbox/activemq-protobuf@713432 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/activemq-protobuf-test/src/test/java/com/google/protobuf/TestUtil.java b/activemq-protobuf-test/src/test/java/com/google/protobuf/TestUtil.java
index c1d456a..8cad790 100644
--- a/activemq-protobuf-test/src/test/java/com/google/protobuf/TestUtil.java
+++ b/activemq-protobuf-test/src/test/java/com/google/protobuf/TestUtil.java
@@ -22,20 +22,21 @@
package com.google.protobuf;
-import protobuf_unittest.UnittestProto;
-import protobuf_unittest.UnittestProto.TestAllTypes;
-import protobuf_unittest.UnittestProto.TestAllExtensions;
-import protobuf_unittest.UnittestProto.ForeignMessage;
-import protobuf_unittest.UnittestProto.ForeignEnum;
-import com.google.protobuf.test.UnittestImport.ImportMessage;
-import com.google.protobuf.test.UnittestImport.ImportEnum;
-
-import junit.framework.Assert;
-
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
+import junit.framework.Assert;
+
+import org.apache.activemq.protobuf.ByteString;
+
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+
+import com.google.protobuf.test.UnittestImport.ImportEnum;
+import com.google.protobuf.test.UnittestImport.ImportMessage;
+
/**
* Contains methods for setting all fields of {@code TestAllTypes} to
* some vaules as well as checking that all the fields are set to those values.
diff --git a/activemq-protobuf-test/src/test/java/com/google/protobuf/WireFormatTest.java b/activemq-protobuf-test/src/test/java/com/google/protobuf/WireFormatTest.java
index d96dc9e..60513fd 100644
--- a/activemq-protobuf-test/src/test/java/com/google/protobuf/WireFormatTest.java
+++ b/activemq-protobuf-test/src/test/java/com/google/protobuf/WireFormatTest.java
@@ -17,6 +17,10 @@
package com.google.protobuf;
import junit.framework.TestCase;
+
+import org.apache.activemq.protobuf.ByteString;
+import org.apache.activemq.protobuf.CodedInputStream;
+
import protobuf_unittest.UnittestProto.TestAllTypes;
/**
diff --git a/activemq-protobuf-test/src/test/java/org/apache/activemq/protobuf/DeferredUnmarshalTest.java b/activemq-protobuf-test/src/test/java/org/apache/activemq/protobuf/DeferredUnmarshalTest.java
index 5340848..d5f9fc8 100644
--- a/activemq-protobuf-test/src/test/java/org/apache/activemq/protobuf/DeferredUnmarshalTest.java
+++ b/activemq-protobuf-test/src/test/java/org/apache/activemq/protobuf/DeferredUnmarshalTest.java
@@ -16,13 +16,11 @@
*/
package org.apache.activemq.protobuf;
-import org.apache.activemq.protobuf.DeferredUnmarshal.Foo;
-import org.apache.activemq.protobuf.DeferredUnmarshal.Bar;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-
import junit.framework.TestCase;
+import org.apache.activemq.protobuf.DeferredUnmarshal.Bar;
+import org.apache.activemq.protobuf.DeferredUnmarshal.Foo;
+
public class DeferredUnmarshalTest extends TestCase {
public void testDeferredDecoding() throws InvalidProtocolBufferException {
diff --git a/activemq-protobuf/pom.xml b/activemq-protobuf/pom.xml
index d9d73fa..23781db 100644
--- a/activemq-protobuf/pom.xml
+++ b/activemq-protobuf/pom.xml
@@ -37,12 +37,6 @@
<dependencies>
<dependency>
- <groupId>com.google.protobuf</groupId>
- <artifactId>protobuf-java</artifactId>
- <version>2.0.1</version>
- </dependency>
-
- <dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
@@ -63,14 +57,6 @@
</dependency>
</dependencies>
- <repositories>
- <repository>
- <id>google</id>
- <name>Google Maven Repo</name>
- <url>http://google-maven-repository.googlecode.com/svn/repository</url>
- </repository>
- </repositories>
-
<build>
<plugins>
<plugin>
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/BaseMessage.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/BaseMessage.java
index 2e2753c..270af4c 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/BaseMessage.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/BaseMessage.java
@@ -16,10 +16,10 @@
*/
package org.apache.activemq.protobuf;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_END_GROUP;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_LENGTH_DELIMITED;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_START_GROUP;
-import static org.apache.activemq.protobuf.WireInfo.makeTag;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_END_GROUP;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_START_GROUP;
+import static org.apache.activemq.protobuf.WireFormat.makeTag;
import java.io.IOException;
import java.io.InputStream;
@@ -28,11 +28,6 @@
import java.util.Collection;
import java.util.List;
-import com.google.protobuf.ByteString;
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.CodedOutputStream;
-import com.google.protobuf.InvalidProtocolBufferException;
-
abstract public class BaseMessage<T> implements Message<T> {
protected int memoizedSerializedSize = -1;
@@ -84,7 +79,7 @@
}
- public void writeUnframed(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
+ public void writeUnframed(CodedOutputStream output) throws java.io.IOException {
// if (encodedForm == null) {
// encodedForm = new byte[serializedSizeUnframed()];
// com.google.protobuf.CodedOutputStream original = output;
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/ByteString.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/ByteString.java
new file mode 100644
index 0000000..e77b219
--- /dev/null
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/ByteString.java
@@ -0,0 +1,318 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.activemq.protobuf;
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Immutable array of bytes.
+ *
+ * @author crazybob@google.com Bob Lee
+ * @author kenton@google.com Kenton Varda
+ */
+public final class ByteString {
+ private final byte[] bytes;
+
+ private ByteString(byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ /**
+ * Gets the byte at the given index.
+ *
+ * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
+ */
+ public byte byteAt(int index) {
+ return bytes[index];
+ }
+
+ /**
+ * Gets the number of bytes.
+ */
+ public int size() {
+ return this.bytes.length;
+ }
+
+ /**
+ * Returns {@code true} if the size is {@code 0}, {@code false} otherwise.
+ */
+ public boolean isEmpty() {
+ return this.bytes.length == 0;
+ }
+
+ // =================================================================
+ // byte[] -> ByteString
+
+ /**
+ * Empty ByteString.
+ */
+ public static final ByteString EMPTY = new ByteString(new byte[0]);
+
+ /**
+ * Copies the given bytes into a {@code ByteString}.
+ */
+ public static ByteString copyFrom(byte[] bytes, int offset, int size) {
+ byte[] copy = new byte[size];
+ System.arraycopy(bytes, offset, copy, 0, size);
+ return new ByteString(copy);
+ }
+
+ /**
+ * Copies the given bytes into a {@code ByteString}.
+ */
+ public static ByteString copyFrom(byte[] bytes) {
+ return copyFrom(bytes, 0, bytes.length);
+ }
+
+ /**
+ * Encodes {@code text} into a sequence of bytes using the named charset
+ * and returns the result as a {@code ByteString}.
+ */
+ public static ByteString copyFrom(String text, String charsetName)
+ throws UnsupportedEncodingException {
+ return new ByteString(text.getBytes(charsetName));
+ }
+
+ /**
+ * Encodes {@code text} into a sequence of UTF-8 bytes and returns the
+ * result as a {@code ByteString}.
+ */
+ public static ByteString copyFromUtf8(String text) {
+ try {
+ return new ByteString(text.getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported?", e);
+ }
+ }
+
+ // =================================================================
+ // ByteString -> byte[]
+
+ /**
+ * Copies bytes into a buffer at the given offset.
+ *
+ * @param target buffer to copy into
+ * @param offset in the target buffer
+ */
+ public void copyTo(byte[] target, int offset) {
+ System.arraycopy(bytes, 0, target, offset, bytes.length);
+ }
+
+ /**
+ * Copies bytes into a buffer.
+ *
+ * @param target buffer to copy into
+ * @param sourceOffset offset within these bytes
+ * @param targetOffset offset within the target buffer
+ * @param size number of bytes to copy
+ */
+ public void copyTo(byte[] target, int sourceOffset, int targetOffset,
+ int size) {
+ System.arraycopy(bytes, sourceOffset, target, targetOffset, size);
+ }
+
+ /**
+ * Copies bytes to a {@code byte[]}.
+ */
+ public byte[] toByteArray() {
+ int size = this.bytes.length;
+ byte[] copy = new byte[size];
+ System.arraycopy(this.bytes, 0, copy, 0, size);
+ return copy;
+ }
+
+ /**
+ * Constructs a new {@code String} by decoding the bytes using the
+ * specified charset.
+ */
+ public String toString(String charsetName)
+ throws UnsupportedEncodingException {
+ return new String(this.bytes, charsetName);
+ }
+
+ /**
+ * Constructs a new {@code String} by decoding the bytes as UTF-8.
+ */
+ public String toStringUtf8() {
+ try {
+ return new String(this.bytes, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported?", e);
+ }
+ }
+
+ // =================================================================
+ // equals() and hashCode()
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+
+ if (!(o instanceof ByteString)) {
+ return false;
+ }
+
+ ByteString other = (ByteString) o;
+ int size = this.bytes.length;
+ if (size != other.bytes.length) {
+ return false;
+ }
+
+ byte[] bytes = this.bytes;
+ byte[] otherBytes = other.bytes;
+ for (int i = 0; i < size; i++) {
+ if (bytes[i] != otherBytes[i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ volatile int hash = 0;
+
+ @Override
+ public int hashCode() {
+ int h = this.hash;
+
+ if (h == 0) {
+ byte[] bytes = this.bytes;
+ int size = this.bytes.length;
+
+ h = size;
+ for (int i = 0; i < size; i++) {
+ h = h * 31 + bytes[i];
+ }
+ if (h == 0) {
+ h = 1;
+ }
+
+ this.hash = h;
+ }
+
+ return h;
+ }
+
+ // =================================================================
+ // Input stream
+
+ /**
+ * Creates an {@code InputStream} which can be used to read the bytes.
+ */
+ public InputStream newInput() {
+ return new ByteArrayInputStream(bytes);
+ }
+
+ /**
+ * Creates a {@link CodedInputStream} which can be used to read the bytes.
+ * Using this is more efficient than creating a {@link CodedInputStream}
+ * wrapping the result of {@link #newInput()}.
+ */
+ public CodedInputStream newCodedInput() {
+ // We trust CodedInputStream not to modify the bytes, or to give anyone
+ // else access to them.
+ return CodedInputStream.newInstance(bytes);
+ }
+
+ // =================================================================
+ // Output stream
+
+ /**
+ * Creates a new {@link Output} with the given initial capacity.
+ */
+ public static Output newOutput(int initialCapacity) {
+ return new Output(new ByteArrayOutputStream(initialCapacity));
+ }
+
+ /**
+ * Creates a new {@link Output}.
+ */
+ public static Output newOutput() {
+ return newOutput(32);
+ }
+
+ /**
+ * Outputs to a {@code ByteString} instance. Call {@link #toByteString()} to
+ * create the {@code ByteString} instance.
+ */
+ public static final class Output extends FilterOutputStream {
+ private final ByteArrayOutputStream bout;
+
+ /**
+ * Constructs a new output with the given initial capacity.
+ */
+ private Output(ByteArrayOutputStream bout) {
+ super(bout);
+ this.bout = bout;
+ }
+
+ /**
+ * Creates a {@code ByteString} instance from this {@code Output}.
+ */
+ public ByteString toByteString() {
+ byte[] byteArray = bout.toByteArray();
+ return new ByteString(byteArray);
+ }
+ }
+
+ /**
+ * Constructs a new ByteString builder, which allows you to efficiently
+ * construct a {@code ByteString} by writing to a {@link CodedOutputSteam}.
+ * Using this is much more efficient than calling {@code newOutput()} and
+ * wrapping that in a {@code CodedOutputStream}.
+ *
+ * <p>This is package-private because it's a somewhat confusing interface.
+ * Users can call {@link Message#toByteString()} instead of calling this
+ * directly.
+ *
+ * @param size The target byte size of the {@code ByteString}. You must
+ * write exactly this many bytes before building the result.
+ */
+ static CodedBuilder newCodedBuilder(int size) {
+ return new CodedBuilder(size);
+ }
+
+ /** See {@link ByteString#newCodedBuilder(int)}. */
+ static final class CodedBuilder {
+ private final CodedOutputStream output;
+ private final byte[] buffer;
+
+ private CodedBuilder(int size) {
+ buffer = new byte[size];
+ output = CodedOutputStream.newInstance(buffer);
+ }
+
+ public ByteString build() {
+ output.checkNoSpaceLeft();
+
+ // We can be confident that the CodedOutputStream will not modify the
+ // underlying bytes anymore because it already wrote all of them. So,
+ // no need to make a copy.
+ return new ByteString(buffer);
+ }
+
+ public CodedOutputStream getCodedOutput() {
+ return output;
+ }
+ }
+}
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java
new file mode 100644
index 0000000..2ebb710
--- /dev/null
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java
@@ -0,0 +1,676 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.activemq.protobuf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 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 CodedInputStream {
+
+ /**
+ * Create a new CodedInputStream wrapping the given InputStream.
+ */
+ public static CodedInputStream newInstance(InputStream input) {
+ return new CodedInputStream(input);
+ }
+
+ /**
+ * Create a new CodedInputStream wrapping the given byte array.
+ */
+ public static CodedInputStream newInstance(byte[] buf) {
+ return new CodedInputStream(buf);
+ }
+
+ // -----------------------------------------------------------------
+
+ /**
+ * 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 (bufferPos == bufferSize && !refillBuffer(false)) {
+ lastTag = 0;
+ return 0;
+ }
+
+ lastTag = readRawVarint32();
+ if (lastTag == 0) {
+ // If we actually read zero, that's not a valid tag.
+ throw InvalidProtocolBufferException.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 InvalidProtocolBufferException
+ * {@code value} does not match the last tag.
+ */
+ public void checkLastTagWas(int value) throws InvalidProtocolBufferException {
+ if (lastTag != value) {
+ throw InvalidProtocolBufferException.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(int tag) throws IOException {
+ switch (WireFormat.getTagWireType(tag)) {
+ case WireFormat.WIRETYPE_VARINT:
+ readInt32();
+ return true;
+ case WireFormat.WIRETYPE_FIXED64:
+ readRawLittleEndian64();
+ return true;
+ case WireFormat.WIRETYPE_LENGTH_DELIMITED:
+ skipRawBytes(readRawVarint32());
+ return true;
+ case WireFormat.WIRETYPE_START_GROUP:
+ skipMessage();
+ checkLastTagWas(WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
+ return true;
+ case WireFormat.WIRETYPE_END_GROUP:
+ return false;
+ case WireFormat.WIRETYPE_FIXED32:
+ readRawLittleEndian32();
+ return true;
+ default:
+ throw InvalidProtocolBufferException.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) {
+ 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 {
+ int size = readRawVarint32();
+ if (size < bufferSize - bufferPos && size > 0) {
+ // Fast path: We already have the bytes in a contiguous buffer, so
+ // just copy directly from it.
+ String result = new String(buffer, bufferPos, size, "UTF-8");
+ bufferPos += size;
+ return result;
+ } else {
+ // Slow path: Build a byte array first then copy it.
+ return new String(readRawBytes(size), "UTF-8");
+ }
+ }
+
+ /** Read a {@code bytes} field value from the stream. */
+ public ByteString readBytes() throws IOException {
+ int size = readRawVarint32();
+ if (size < bufferSize - bufferPos && size > 0) {
+ // Fast path: We already have the bytes in a contiguous buffer, so
+ // just copy directly from it.
+ ByteString result = ByteString.copyFrom(buffer, bufferPos, size);
+ bufferPos += size;
+ return result;
+ } else {
+ // Slow path: Build a byte array first then copy it.
+ return ByteString.copyFrom(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 InvalidProtocolBufferException.malformedVarint();
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /** Read a raw Varint from the stream. */
+ public long readRawVarint64() throws IOException {
+ int shift = 0;
+ long result = 0;
+ while (shift < 64) {
+ byte b = readRawByte();
+ result |= (long) (b & 0x7F) << shift;
+ if ((b & 0x80) == 0)
+ return result;
+ shift += 7;
+ }
+ throw InvalidProtocolBufferException.malformedVarint();
+ }
+
+ /** Read a 32-bit little-endian integer from the stream. */
+ public int readRawLittleEndian32() throws IOException {
+ byte b1 = readRawByte();
+ byte b2 = readRawByte();
+ byte b3 = readRawByte();
+ byte b4 = readRawByte();
+ return (((int) b1 & 0xff)) | (((int) b2 & 0xff) << 8) | (((int) b3 & 0xff) << 16) | (((int) b4 & 0xff) << 24);
+ }
+
+ /** Read a 64-bit little-endian integer from the stream. */
+ public long readRawLittleEndian64() throws IOException {
+ byte b1 = readRawByte();
+ byte b2 = readRawByte();
+ byte b3 = readRawByte();
+ byte b4 = readRawByte();
+ byte b5 = readRawByte();
+ byte b6 = readRawByte();
+ byte b7 = readRawByte();
+ byte b8 = readRawByte();
+ 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(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(long n) {
+ return (n >>> 1) ^ -(n & 1);
+ }
+
+ // -----------------------------------------------------------------
+
+ private byte[] buffer;
+ private int bufferSize;
+ private int bufferSizeAfterLimit = 0;
+ private int bufferPos = 0;
+ private InputStream input;
+ private int lastTag = 0;
+
+ /**
+ * The total number of bytes read before the current buffer. The total bytes
+ * read up to the current position can be computed as {@code
+ * totalBytesRetired + bufferPos}.
+ */
+ private int totalBytesRetired = 0;
+
+ /** The absolute position of the end of the current message. */
+ private int currentLimit = Integer.MAX_VALUE;
+
+ /** See setRecursionLimit() */
+ private int recursionDepth = 0;
+ 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 static final int BUFFER_SIZE = 4096;
+
+ private CodedInputStream(byte[] buffer) {
+ this.buffer = buffer;
+ this.bufferSize = buffer.length;
+ this.input = null;
+ }
+
+ private CodedInputStream(InputStream input) {
+ this.buffer = new byte[BUFFER_SIZE];
+ this.bufferSize = 0;
+ this.input = input;
+ }
+
+ /**
+ * 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(int limit) {
+ if (limit < 0) {
+ throw new IllegalArgumentException("Recursion limit cannot be negative: " + limit);
+ }
+ 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 (nor
+ * with {@link ByteString#newCodedInput}).
+ *
+ * @return the old limit.
+ */
+ public int setSizeLimit(int limit) {
+ if (limit < 0) {
+ throw new IllegalArgumentException("Size limit cannot be negative: " + limit);
+ }
+ int oldLimit = sizeLimit;
+ sizeLimit = limit;
+ return oldLimit;
+ }
+
+ /**
+ * 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 InvalidProtocolBufferException {
+ if (byteLimit < 0) {
+ throw InvalidProtocolBufferException.negativeSize();
+ }
+ byteLimit += totalBytesRetired + bufferPos;
+ int oldLimit = currentLimit;
+ if (byteLimit > oldLimit) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ currentLimit = byteLimit;
+
+ recomputeBufferSizeAfterLimit();
+
+ return oldLimit;
+ }
+
+ private void recomputeBufferSizeAfterLimit() {
+ bufferSize += bufferSizeAfterLimit;
+ int bufferEnd = totalBytesRetired + 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(int oldLimit) {
+ currentLimit = oldLimit;
+ recomputeBufferSizeAfterLimit();
+ }
+
+ /**
+ * Called with {@code this.buffer} is empty to read more bytes from the
+ * input. If {@code mustSucceed} is true, refillBuffer() gurantees that
+ * either there will be at least one byte in the buffer when it returns or
+ * it will throw an exception. If {@code mustSucceed} is false,
+ * refillBuffer() returns false if no more bytes were available.
+ */
+ private boolean refillBuffer(boolean mustSucceed) throws IOException {
+ if (bufferPos < bufferSize) {
+ throw new IllegalStateException("refillBuffer() called when buffer wasn't empty.");
+ }
+
+ if (totalBytesRetired + bufferSize == currentLimit) {
+ // Oops, we hit a limit.
+ if (mustSucceed) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ } else {
+ return false;
+ }
+ }
+
+ totalBytesRetired += bufferSize;
+
+ bufferPos = 0;
+ bufferSize = (input == null) ? -1 : input.read(buffer);
+ if (bufferSize == -1) {
+ bufferSize = 0;
+ if (mustSucceed) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ } else {
+ return false;
+ }
+ } else {
+ recomputeBufferSizeAfterLimit();
+ int totalBytesRead = totalBytesRetired + bufferSize + bufferSizeAfterLimit;
+ if (totalBytesRead > sizeLimit || totalBytesRead < 0) {
+ throw InvalidProtocolBufferException.sizeLimitExceeded();
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Read one byte from the input.
+ *
+ * @throws InvalidProtocolBufferException
+ * The end of the stream or the current limit was reached.
+ */
+ public byte readRawByte() throws IOException {
+ if (bufferPos == bufferSize) {
+ refillBuffer(true);
+ }
+ return buffer[bufferPos++];
+ }
+
+ /**
+ * Read a fixed size of bytes from the input.
+ *
+ * @throws InvalidProtocolBufferException
+ * The end of the stream or the current limit was reached.
+ */
+ public byte[] readRawBytes(int size) throws IOException {
+ if (size < 0) {
+ throw InvalidProtocolBufferException.negativeSize();
+ }
+
+ if (totalBytesRetired + bufferPos + size > currentLimit) {
+ // Read to the end of the stream anyway.
+ skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+ // Then fail.
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+
+ if (size <= bufferSize - bufferPos) {
+ // We have all the bytes we need already.
+ byte[] bytes = new byte[size];
+ System.arraycopy(buffer, bufferPos, bytes, 0, size);
+ bufferPos += size;
+ return bytes;
+ } else if (size < BUFFER_SIZE) {
+ // Reading more bytes than are in the buffer, but not an excessive
+ // number
+ // of bytes. We can safely allocate the resulting array ahead of
+ // time.
+
+ // First copy what we have.
+ byte[] bytes = new byte[size];
+ int pos = bufferSize - bufferPos;
+ System.arraycopy(buffer, bufferPos, bytes, 0, pos);
+ bufferPos = bufferSize;
+
+ // We want to use refillBuffer() and then copy from the buffer into
+ // our
+ // byte array rather than reading directly into our byte array
+ // because
+ // the input may be unbuffered.
+ refillBuffer(true);
+
+ while (size - pos > bufferSize) {
+ System.arraycopy(buffer, 0, bytes, pos, bufferSize);
+ pos += bufferSize;
+ bufferPos = bufferSize;
+ refillBuffer(true);
+ }
+
+ System.arraycopy(buffer, 0, bytes, pos, size - pos);
+ bufferPos = size - pos;
+
+ return bytes;
+ } else {
+ // The size is very large. For security reasons, we can't allocate
+ // the
+ // entire byte array yet. The size comes directly from the input, so
+ // a
+ // maliciously-crafted message could provide a bogus very large size
+ // in
+ // order to trick the app into allocating a lot of memory. We avoid
+ // this
+ // by allocating and reading only a small chunk at a time, so that
+ // the
+ // malicious message must actually *be* extremely large to cause
+ // problems. Meanwhile, we limit the allowed size of a message
+ // elsewhere.
+
+ // Remember the buffer markers since we'll have to copy the bytes
+ // out of
+ // it later.
+ int originalBufferPos = bufferPos;
+ int originalBufferSize = bufferSize;
+
+ // Mark the current buffer consumed.
+ totalBytesRetired += bufferSize;
+ bufferPos = 0;
+ bufferSize = 0;
+
+ // Read all the rest of the bytes we need.
+ int sizeLeft = size - (originalBufferSize - originalBufferPos);
+ List<byte[]> chunks = new ArrayList<byte[]>();
+
+ while (sizeLeft > 0) {
+ byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)];
+ int pos = 0;
+ while (pos < chunk.length) {
+ int n = (input == null) ? -1 : input.read(chunk, pos, chunk.length - pos);
+ if (n == -1) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ totalBytesRetired += n;
+ pos += n;
+ }
+ sizeLeft -= chunk.length;
+ chunks.add(chunk);
+ }
+
+ // OK, got everything. Now concatenate it all into one buffer.
+ byte[] bytes = new byte[size];
+
+ // Start by copying the leftover bytes from this.buffer.
+ int pos = originalBufferSize - originalBufferPos;
+ System.arraycopy(buffer, originalBufferPos, bytes, 0, pos);
+
+ // And now all the chunks.
+ for (byte[] chunk : chunks) {
+ System.arraycopy(chunk, 0, bytes, pos, chunk.length);
+ pos += chunk.length;
+ }
+
+ // Done.
+ return bytes;
+ }
+ }
+
+ /**
+ * Reads and discards {@code size} bytes.
+ *
+ * @throws InvalidProtocolBufferException
+ * The end of the stream or the current limit was reached.
+ */
+ public void skipRawBytes(int size) throws IOException {
+ if (size < 0) {
+ throw InvalidProtocolBufferException.negativeSize();
+ }
+
+ if (totalBytesRetired + bufferPos + size > currentLimit) {
+ // Read to the end of the stream anyway.
+ skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+ // Then fail.
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+
+ if (size < bufferSize - bufferPos) {
+ // We have all the bytes we need already.
+ bufferPos += size;
+ } else {
+ // Skipping more bytes than are in the buffer. First skip what we
+ // have.
+ int pos = bufferSize - bufferPos;
+ totalBytesRetired += pos;
+ bufferPos = 0;
+ bufferSize = 0;
+
+ // Then skip directly from the InputStream for the rest.
+ while (pos < size) {
+ int n = (input == null) ? -1 : (int) input.skip(size - pos);
+ if (n <= 0) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ pos += n;
+ totalBytesRetired += n;
+ }
+ }
+ }
+}
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedOutputStream.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedOutputStream.java
new file mode 100644
index 0000000..7e391f8
--- /dev/null
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedOutputStream.java
@@ -0,0 +1,599 @@
+
+//Protocol Buffers - Google's data interchange format
+//Copyright 2008 Google Inc.
+//http://code.google.com/p/protobuf/
+//
+//Licensed under the Apache License, Version 2.0 (the "License");
+//you may not use this file except in compliance with the License.
+//You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing, software
+//distributed under the License is distributed on an "AS IS" BASIS,
+//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//See the License for the specific language governing permissions and
+//limitations under the License.
+package org.apache.activemq.protobuf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+* 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 CodedOutputStream {
+private final byte[] buffer;
+private final int limit;
+private int position;
+
+private final OutputStream output;
+
+/**
+* The buffer size used in {@link #newInstance(java.io.OutputStream)}.
+*/
+public static final int DEFAULT_BUFFER_SIZE = 4096;
+
+private CodedOutputStream(byte[] buffer, int offset, int length) {
+ this.output = null;
+ this.buffer = buffer;
+ this.position = offset;
+ this.limit = offset + length;
+}
+
+private CodedOutputStream(OutputStream output, byte[] buffer) {
+ this.output = output;
+ this.buffer = buffer;
+ this.position = 0;
+ this.limit = buffer.length;
+}
+
+/**
+* Create a new {@code CodedOutputStream} wrapping the given
+* {@code OutputStream}.
+*/
+public static CodedOutputStream newInstance(OutputStream output) {
+ return newInstance(output, DEFAULT_BUFFER_SIZE);
+}
+
+/**
+* Create a new {@code CodedOutputStream} wrapping the given
+* {@code OutputStream} with a given buffer size.
+*/
+public static CodedOutputStream newInstance(OutputStream output,
+ int bufferSize) {
+ return new CodedOutputStream(output, new byte[bufferSize]);
+}
+
+/**
+* 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}. See also
+* {@link ByteString#newCodedBuilder}.
+*/
+public static CodedOutputStream newInstance(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}. See also
+* {@link ByteString#newCodedBuilder}.
+*/
+public static CodedOutputStream newInstance(byte[] flatArray, int offset,
+ int length) {
+ return new CodedOutputStream(flatArray, offset, length);
+}
+
+// -----------------------------------------------------------------
+
+/** Write a {@code double} field, including tag, to the stream. */
+public void writeDouble(int fieldNumber, double value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ writeRawLittleEndian64(Double.doubleToRawLongBits(value));
+}
+
+/** Write a {@code float} field, including tag, to the stream. */
+public void writeFloat(int fieldNumber, float value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ writeRawLittleEndian32(Float.floatToRawIntBits(value));
+}
+
+/** Write a {@code uint64} field, including tag, to the stream. */
+public void writeUInt64(int fieldNumber, long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeRawVarint64(value);
+}
+
+/** Write an {@code int64} field, including tag, to the stream. */
+public void writeInt64(int fieldNumber, long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeRawVarint64(value);
+}
+
+/** Write an {@code int32} field, including tag, to the stream. */
+public void writeInt32(int fieldNumber, int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ if (value >= 0) {
+ writeRawVarint32(value);
+ } else {
+ // Must sign-extend.
+ writeRawVarint64(value);
+ }
+}
+
+/** Write a {@code fixed64} field, including tag, to the stream. */
+public void writeFixed64(int fieldNumber, long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ writeRawLittleEndian64(value);
+}
+
+/** Write a {@code fixed32} field, including tag, to the stream. */
+public void writeFixed32(int fieldNumber, int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ writeRawLittleEndian32(value);
+}
+
+/** Write a {@code bool} field, including tag, to the stream. */
+public void writeBool(int fieldNumber, boolean value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeRawByte(value ? 1 : 0);
+}
+
+/** Write a {@code string} field, including tag, to the stream. */
+public void writeString(int fieldNumber, String value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ // Unfortunately there does not appear to be any way to tell Java to encode
+ // UTF-8 directly into our buffer, so we have to let it create its own byte
+ // array and then copy.
+ byte[] bytes = value.getBytes("UTF-8");
+ writeRawVarint32(bytes.length);
+ writeRawBytes(bytes);
+}
+
+/** Write a {@code bytes} field, including tag, to the stream. */
+public void writeBytes(int fieldNumber, ByteString value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ byte[] bytes = value.toByteArray();
+ writeRawVarint32(bytes.length);
+ writeRawBytes(bytes);
+}
+
+/** Write a {@code uint32} field, including tag, to the stream. */
+public void writeUInt32(int fieldNumber, int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeRawVarint32(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(int fieldNumber, int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeRawVarint32(value);
+}
+
+/** Write an {@code sfixed32} field, including tag, to the stream. */
+public void writeSFixed32(int fieldNumber, int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ writeRawLittleEndian32(value);
+}
+
+/** Write an {@code sfixed64} field, including tag, to the stream. */
+public void writeSFixed64(int fieldNumber, long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ writeRawLittleEndian64(value);
+}
+
+/** Write an {@code sint32} field, including tag, to the stream. */
+public void writeSInt32(int fieldNumber, int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeRawVarint32(encodeZigZag32(value));
+}
+
+/** Write an {@code sint64} field, including tag, to the stream. */
+public void writeSInt64(int fieldNumber, long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeRawVarint64(encodeZigZag64(value));
+}
+
+// =================================================================
+
+/**
+* Compute the number of bytes that would be needed to encode a
+* {@code double} field, including tag.
+*/
+public static int computeDoubleSize(int fieldNumber, double value) {
+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;
+}
+
+/**
+* Compute the number of bytes that would be needed to encode a
+* {@code float} field, including tag.
+*/
+public static int computeFloatSize(int fieldNumber, float value) {
+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;
+}
+
+/**
+* Compute the number of bytes that would be needed to encode a
+* {@code uint64} field, including tag.
+*/
+public static int computeUInt64Size(int fieldNumber, long value) {
+ return computeTagSize(fieldNumber) + computeRawVarint64Size(value);
+}
+
+/**
+* Compute the number of bytes that would be needed to encode an
+* {@code int64} field, including tag.
+*/
+public static int computeInt64Size(int fieldNumber, long value) {
+ return computeTagSize(fieldNumber) + computeRawVarint64Size(value);
+}
+
+/**
+* Compute the number of bytes that would be needed to encode an
+* {@code int32} field, including tag.
+*/
+public static int computeInt32Size(int fieldNumber, int value) {
+ if (value >= 0) {
+ return computeTagSize(fieldNumber) + computeRawVarint32Size(value);
+ } else {
+ // Must sign-extend.
+ return computeTagSize(fieldNumber) + 10;
+ }
+}
+
+/**
+* Compute the number of bytes that would be needed to encode a
+* {@code fixed64} field, including tag.
+*/
+public static int computeFixed64Size(int fieldNumber, long value) {
+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;
+}
+
+/**
+* Compute the number of bytes that would be needed to encode a
+* {@code fixed32} field, including tag.
+*/
+public static int computeFixed32Size(int fieldNumber, int value) {
+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;
+}
+
+/**
+* Compute the number of bytes that would be needed to encode a
+* {@code bool} field, including tag.
+*/
+public static int computeBoolSize(int fieldNumber, boolean value) {
+ return computeTagSize(fieldNumber) + 1;
+}
+
+/**
+* Compute the number of bytes that would be needed to encode a
+* {@code string} field, including tag.
+*/
+public static int computeStringSize(int fieldNumber, String value) {
+ try {
+ byte[] bytes = value.getBytes("UTF-8");
+ return computeTagSize(fieldNumber) +
+ computeRawVarint32Size(bytes.length) +
+ bytes.length;
+ } catch (java.io.UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported.", e);
+ }
+}
+
+/**
+* Compute the number of bytes that would be needed to encode a
+* {@code bytes} field, including tag.
+*/
+public static int computeBytesSize(int fieldNumber, ByteString value) {
+ return computeTagSize(fieldNumber) +
+ computeRawVarint32Size(value.size()) +
+ value.size();
+}
+
+/**
+* Compute the number of bytes that would be needed to encode a
+* {@code uint32} field, including tag.
+*/
+public static int computeUInt32Size(int fieldNumber, int value) {
+ return computeTagSize(fieldNumber) + computeRawVarint32Size(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(int fieldNumber, int value) {
+ return computeTagSize(fieldNumber) + computeRawVarint32Size(value);
+}
+
+/**
+* Compute the number of bytes that would be needed to encode an
+* {@code sfixed32} field, including tag.
+*/
+public static int computeSFixed32Size(int fieldNumber, int value) {
+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;
+}
+
+/**
+* Compute the number of bytes that would be needed to encode an
+* {@code sfixed64} field, including tag.
+*/
+public static int computeSFixed64Size(int fieldNumber, long value) {
+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;
+}
+
+/**
+* Compute the number of bytes that would be needed to encode an
+* {@code sint32} field, including tag.
+*/
+public static int computeSInt32Size(int fieldNumber, int value) {
+ return computeTagSize(fieldNumber) +
+ computeRawVarint32Size(encodeZigZag32(value));
+}
+
+/**
+* Compute the number of bytes that would be needed to encode an
+* {@code sint64} field, including tag.
+*/
+public static int computeSInt64Size(int fieldNumber, long value) {
+ return computeTagSize(fieldNumber) +
+ computeRawVarint64Size(encodeZigZag64(value));
+}
+
+// =================================================================
+
+/**
+* Internal helper that writes the current buffer to the output. The
+* buffer position is reset to its initial value when this returns.
+*/
+private void refreshBuffer() throws IOException {
+ if (output == null) {
+ // We're writing to a single buffer.
+ throw new OutOfSpaceException();
+ }
+
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ output.write(buffer, 0, position);
+ position = 0;
+}
+
+/**
+* Flushes the stream and forces any buffered bytes to be written. This
+* does not flush the underlying OutputStream.
+*/
+public void flush() throws IOException {
+ if (output != null) {
+ refreshBuffer();
+ }
+}
+
+/**
+* If writing to a flat array, return the space left in the array.
+* Otherwise, throws {@code UnsupportedOperationException}.
+*/
+public int spaceLeft() {
+ if (output == null) {
+ return limit - position;
+ } else {
+ throw new UnsupportedOperationException(
+ "spaceLeft() can only be called on CodedOutputStreams that are " +
+ "writing to a flat array.");
+ }
+}
+
+/**
+* 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.");
+ }
+}
+
+/**
+* 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 {
+ OutOfSpaceException() {
+ super("CodedOutputStream was writing to a flat byte array and ran " +
+ "out of space.");
+ }
+}
+
+/** Write a single byte. */
+public void writeRawByte(byte value) throws IOException {
+ if (position == limit) {
+ refreshBuffer();
+ }
+
+ buffer[position++] = value;
+}
+
+/** Write a single byte, represented by an integer value. */
+public void writeRawByte(int value) throws IOException {
+ writeRawByte((byte) value);
+}
+
+/** Write an array of bytes. */
+public void writeRawBytes(byte[] value) throws IOException {
+ writeRawBytes(value, 0, value.length);
+}
+
+/** Write part of an array of bytes. */
+public void writeRawBytes(byte[] value, int offset, int length)
+ throws IOException {
+ if (limit - position >= length) {
+ // We have room in the current buffer.
+ System.arraycopy(value, offset, buffer, position, length);
+ position += length;
+ } else {
+ // Write extends past current buffer. Fill the rest of this buffer and
+ // flush.
+ int bytesWritten = limit - position;
+ System.arraycopy(value, offset, buffer, position, bytesWritten);
+ offset += bytesWritten;
+ length -= bytesWritten;
+ position = limit;
+ refreshBuffer();
+
+ // Now deal with the rest.
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ if (length <= limit) {
+ // Fits in new buffer.
+ System.arraycopy(value, offset, buffer, 0, length);
+ position = length;
+ } else {
+ // Write is very big. Let's do it all at once.
+ output.write(value, offset, length);
+ }
+ }
+}
+
+/** Encode and write a tag. */
+public void writeTag(int fieldNumber, int wireType) throws IOException {
+ writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType));
+}
+
+/** Compute the number of bytes that would be needed to encode a tag. */
+public static int computeTagSize(int fieldNumber) {
+ return computeRawVarint32Size(WireFormat.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(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(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(int value) throws IOException {
+ writeRawByte((value ) & 0xFF);
+ writeRawByte((value >> 8) & 0xFF);
+ writeRawByte((value >> 16) & 0xFF);
+ writeRawByte((value >> 24) & 0xFF);
+}
+
+public static final int LITTLE_ENDIAN_32_SIZE = 4;
+
+/** Write a little-endian 64-bit integer. */
+public void writeRawLittleEndian64(long value) throws IOException {
+ writeRawByte((int)(value ) & 0xFF);
+ writeRawByte((int)(value >> 8) & 0xFF);
+ writeRawByte((int)(value >> 16) & 0xFF);
+ writeRawByte((int)(value >> 24) & 0xFF);
+ writeRawByte((int)(value >> 32) & 0xFF);
+ writeRawByte((int)(value >> 40) & 0xFF);
+ writeRawByte((int)(value >> 48) & 0xFF);
+ writeRawByte((int)(value >> 56) & 0xFF);
+}
+
+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(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(long n) {
+ // Note: the right-shift must be arithmetic
+ return (n << 1) ^ (n >> 63);
+}
+}
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/DeferredDecodeMessage.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/DeferredDecodeMessage.java
index f914acc..f789073 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/DeferredDecodeMessage.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/DeferredDecodeMessage.java
@@ -18,9 +18,6 @@
import java.io.IOException;
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.InvalidProtocolBufferException;
-
abstract public class DeferredDecodeMessage<T> extends BaseMessage<T> {
protected byte[] encodedForm;
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/InvalidProtocolBufferException.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/InvalidProtocolBufferException.java
new file mode 100644
index 0000000..f624605
--- /dev/null
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/InvalidProtocolBufferException.java
@@ -0,0 +1,66 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.activemq.protobuf;
+
+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 InvalidProtocolBufferException extends IOException {
+ private static final long serialVersionUID = 5685337441004132240L;
+
+ public InvalidProtocolBufferException(String description) {
+ super(description);
+ }
+
+ static InvalidProtocolBufferException truncatedMessage() {
+ return new InvalidProtocolBufferException("While parsing a protocol message, the input ended unexpectedly " + "in the middle of a field. This could mean either than the " + "input has been truncated or that an embedded message "
+ + "misreported its own length.");
+ }
+
+ static InvalidProtocolBufferException negativeSize() {
+ return new InvalidProtocolBufferException("CodedInputStream encountered an embedded string or message " + "which claimed to have negative size.");
+ }
+
+ static InvalidProtocolBufferException malformedVarint() {
+ return new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint.");
+ }
+
+ static InvalidProtocolBufferException invalidTag() {
+ return new InvalidProtocolBufferException("Protocol message contained an invalid tag (zero).");
+ }
+
+ static InvalidProtocolBufferException invalidEndTag() {
+ return new InvalidProtocolBufferException("Protocol message end-group tag did not match expected tag.");
+ }
+
+ static InvalidProtocolBufferException invalidWireType() {
+ return new InvalidProtocolBufferException("Protocol message tag had invalid wire type.");
+ }
+
+ static InvalidProtocolBufferException recursionLimitExceeded() {
+ return new InvalidProtocolBufferException("Protocol message had too many levels of nesting. May be malicious. " + "Use CodedInputStream.setRecursionLimit() to increase the depth limit.");
+ }
+
+ static InvalidProtocolBufferException sizeLimitExceeded() {
+ return new InvalidProtocolBufferException("Protocol message was too large. May be malicious. " + "Use CodedInputStream.setSizeLimit() to increase the size limit.");
+ }
+}
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Message.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Message.java
index 36757d6..7f13031 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Message.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Message.java
@@ -20,11 +20,6 @@
import java.io.InputStream;
import java.io.OutputStream;
-import com.google.protobuf.ByteString;
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.CodedOutputStream;
-import com.google.protobuf.InvalidProtocolBufferException;
-
public interface Message<T> {
public T clone() throws CloneNotSupportedException;
@@ -35,7 +30,7 @@
public void clear();
- public T assertInitialized() throws com.google.protobuf.UninitializedMessageException;
+ public T assertInitialized() throws UninitializedMessageException;
public T mergeFrom(T other);
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UninitializedMessageException.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UninitializedMessageException.java
index 4824b15..3e17dae 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UninitializedMessageException.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UninitializedMessageException.java
@@ -16,67 +16,61 @@
package org.apache.activemq.protobuf;
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
/**
* Thrown when attempting to build a protocol message that is missing required
- * fields. This is a {@code RuntimeException} because it normally represents
- * a programming error: it happens when some code which constructs a message
- * fails to set all the fields. {@code parseFrom()} methods <b>do not</b>
- * throw this; they throw an {@link InvalidProtocolBufferException} if
- * required fields are missing, because it is not a programming error to
- * receive an incomplete message. In other words,
- * {@code UninitializedMessageException} should never be thrown by correct
- * code, but {@code InvalidProtocolBufferException} might be.
- *
+ * fields. This is a {@code RuntimeException} because it normally represents a
+ * programming error: it happens when some code which constructs a message fails
+ * to set all the fields. {@code parseFrom()} methods <b>do not</b> throw this;
+ * they throw an {@link InvalidProtocolBufferException} if required fields are
+ * missing, because it is not a programming error to receive an incomplete
+ * message. In other words, {@code UninitializedMessageException} should never
+ * be thrown by correct code, but {@code InvalidProtocolBufferException} might
+ * be.
+ *
* @author kenton@google.com Kenton Varda
*/
public class UninitializedMessageException extends RuntimeException {
- public UninitializedMessageException(List<String> missingFields) {
- super(buildDescription(missingFields));
- this.missingFields = missingFields;
- }
-
- private final List<String> missingFields;
-
- /**
- * Get a list of human-readable names of required fields missing from this
- * message. Each name is a full path to a field, e.g. "foo.bar[5].baz".
- */
- public List<String> getMissingFields() {
- return Collections.unmodifiableList(missingFields);
- }
-
- /**
- * Converts this exception to an {@link InvalidProtocolBufferException}.
- * When a parsed message is missing required fields, this should be thrown
- * instead of {@code UninitializedMessageException}.
- */
- public com.google.protobuf.InvalidProtocolBufferException asInvalidProtocolBufferException() {
- return new InvalidProtocolBufferException(getMessage());
- }
-
- /** Construct the description string for this exception. */
- private static String buildDescription(List<String> missingFields) {
- StringBuilder description =
- new StringBuilder("Message missing required fields: ");
- boolean first = true;
- for (String field : missingFields) {
- if (first) {
- first = false;
- } else {
- description.append(", ");
- }
- description.append(field);
+ public UninitializedMessageException(List<String> missingFields) {
+ super(buildDescription(missingFields));
+ this.missingFields = missingFields;
}
- return description.toString();
- }
+
+ private final List<String> missingFields;
+
+ /**
+ * Get a list of human-readable names of required fields missing from this
+ * message. Each name is a full path to a field, e.g. "foo.bar[5].baz".
+ */
+ public List<String> getMissingFields() {
+ return Collections.unmodifiableList(missingFields);
+ }
+
+ /**
+ * Converts this exception to an {@link InvalidProtocolBufferException}.
+ * When a parsed message is missing required fields, this should be thrown
+ * instead of {@code UninitializedMessageException}.
+ */
+ public InvalidProtocolBufferException asInvalidProtocolBufferException() {
+ return new InvalidProtocolBufferException(getMessage());
+ }
+
+ /** Construct the description string for this exception. */
+ private static String buildDescription(List<String> missingFields) {
+ StringBuilder description = new StringBuilder("Message missing required fields: ");
+ boolean first = true;
+ for (String field : missingFields) {
+ if (first) {
+ first = false;
+ } else {
+ description.append(", ");
+ }
+ description.append(field);
+ }
+ return description.toString();
+ }
}
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireFormat.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireFormat.java
new file mode 100644
index 0000000..3018bb7
--- /dev/null
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireFormat.java
@@ -0,0 +1,70 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.activemq.protobuf;
+
+/**
+ * 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 protocol2} 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 WireFormat {
+ // Do not allow instantiation.
+ private WireFormat() {
+ }
+
+ public static final int WIRETYPE_VARINT = 0;
+ public static final int WIRETYPE_FIXED64 = 1;
+ public static final int WIRETYPE_LENGTH_DELIMITED = 2;
+ public static final int WIRETYPE_START_GROUP = 3;
+ public static final int WIRETYPE_END_GROUP = 4;
+ public static final int WIRETYPE_FIXED32 = 5;
+
+ public static final int TAG_TYPE_BITS = 3;
+ public static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;
+
+ /** Given a tag value, determines the wire type (the lower 3 bits). */
+ public static int getTagWireType(int tag) {
+ return tag & TAG_TYPE_MASK;
+ }
+
+ /** Given a tag value, determines the field number (the upper 29 bits). */
+ public static int getTagFieldNumber(int tag) {
+ return tag >>> TAG_TYPE_BITS;
+ }
+
+ /** Makes a tag value given a field number and wire type. */
+ public static int makeTag(int fieldNumber, int wireType) {
+ return (fieldNumber << TAG_TYPE_BITS) | wireType;
+ }
+
+ // Field numbers for feilds in MessageSet wire format.
+ public static final int MESSAGE_SET_ITEM = 1;
+ public static final int MESSAGE_SET_TYPE_ID = 2;
+ public static final int MESSAGE_SET_MESSAGE = 3;
+
+ // Tag numbers.
+ public static final int MESSAGE_SET_ITEM_TAG = makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP);
+ public static final int MESSAGE_SET_ITEM_END_TAG = makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP);
+ public static final int MESSAGE_SET_TYPE_ID_TAG = makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT);
+ public static final int MESSAGE_SET_MESSAGE_TAG = makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED);
+}
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireInfo.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireInfo.java
deleted file mode 100644
index a9c4f41..0000000
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireInfo.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.protobuf;
-
-public class WireInfo {
-
- public static final int WIRETYPE_VARINT = 0;
- public static final int WIRETYPE_FIXED64 = 1;
- public static final int WIRETYPE_LENGTH_DELIMITED = 2;
- public static final int WIRETYPE_START_GROUP = 3;
- public static final int WIRETYPE_END_GROUP = 4;
- public static final int WIRETYPE_FIXED32 = 5;
-
- public static final int TAG_TYPE_BITS = 3;
-
- public static int makeTag(int fieldNumber, int wireType) {
- return (fieldNumber << TAG_TYPE_BITS) | wireType;
- }
-}
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/JavaGenerator.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/JavaGenerator.java
index e407ac7..3a29986 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/JavaGenerator.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/JavaGenerator.java
@@ -16,12 +16,12 @@
*/
package org.apache.activemq.protobuf.compiler;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_FIXED32;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_FIXED64;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_LENGTH_DELIMITED;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_START_GROUP;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_VARINT;
-import static org.apache.activemq.protobuf.WireInfo.makeTag;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_FIXED32;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_FIXED64;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_START_GROUP;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_VARINT;
+import static org.apache.activemq.protobuf.WireFormat.makeTag;
import java.io.File;
import java.io.FileInputStream;
@@ -446,56 +446,56 @@
postMergeProcessing="";
}
- p("public static "+className+" parseUnframed(com.google.protobuf.CodedInputStream data) throws com.google.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+ p("public static "+className+" parseUnframed(org.apache.activemq.protobuf.CodedInputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
indent();
p("return new "+className+"().mergeUnframed(data)"+postMergeProcessing+";");
unindent();
p("}");
p();
- p("public static "+className+" parseUnframed(com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException {");
+ p("public static "+className+" parseUnframed(org.apache.activemq.protobuf.ByteString data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
indent();
p("return new "+className+"().mergeUnframed(data)"+postMergeProcessing+";");
unindent();
p("}");
p();
- p("public static "+className+" parseUnframed(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException {");
+ p("public static "+className+" parseUnframed(byte[] data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
indent();
p("return new "+className+"().mergeUnframed(data)"+postMergeProcessing+";");
unindent();
p("}");
p();
- p("public static "+className+" parseUnframed(java.io.InputStream data) throws com.google.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+ p("public static "+className+" parseUnframed(java.io.InputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
indent();
p("return new "+className+"().mergeUnframed(data)"+postMergeProcessing+";");
unindent();
p("}");
p();
- p("public static "+className+" parseFramed(com.google.protobuf.CodedInputStream data) throws com.google.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+ p("public static "+className+" parseFramed(org.apache.activemq.protobuf.CodedInputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
indent();
p("return new "+className+"().mergeFramed(data)"+postMergeProcessing+";");
unindent();
p("}");
p();
- p("public static "+className+" parseFramed(com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException {");
+ p("public static "+className+" parseFramed(org.apache.activemq.protobuf.ByteString data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
indent();
p("return new "+className+"().mergeFramed(data)"+postMergeProcessing+";");
unindent();
p("}");
p();
- p("public static "+className+" parseFramed(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException {");
+ p("public static "+className+" parseFramed(byte[] data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
indent();
p("return new "+className+"().mergeFramed(data)"+postMergeProcessing+";");
unindent();
p("}");
p();
- p("public static "+className+" parseFramed(java.io.InputStream data) throws com.google.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+ p("public static "+className+" parseFramed(java.io.InputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
indent();
p("return new "+className+"().mergeFramed(data)"+postMergeProcessing+";");
unindent();
@@ -637,37 +637,37 @@
}
if( field.getType()==FieldDescriptor.STRING_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeStringSize("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeStringSize("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.BYTES_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeBytesSize("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeBytesSize("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.BOOL_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeBoolSize("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeBoolSize("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.DOUBLE_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeDoubleSize("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeDoubleSize("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.FLOAT_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeFloatSize("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeFloatSize("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.INT32_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeInt32Size("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeInt32Size("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.INT64_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeInt64Size("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeInt64Size("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.SINT32_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeSInt32Size("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSInt32Size("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.SINT64_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeSInt64Size("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSInt64Size("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.UINT32_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeUInt32Size("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeUInt32Size("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.UINT64_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeUInt64Size("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeUInt64Size("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.FIXED32_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeFixed32Size("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeFixed32Size("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.FIXED64_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeFixed64Size("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeFixed64Size("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.SFIXED32_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeSFixed32Size("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSFixed32Size("+field.getTag()+", "+getter+");");
} else if( field.getType()==FieldDescriptor.SFIXED64_TYPE ) {
- p("size += com.google.protobuf.CodedOutputStream.computeSFixed64Size("+field.getTag()+", "+getter+");");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSFixed64Size("+field.getTag()+", "+getter+");");
} else if( field.getTypeDescriptor().isEnum() ) {
- p("size += com.google.protobuf.CodedOutputStream.computeEnumSize("+field.getTag()+", "+getter+".getNumber());");
+ p("size += org.apache.activemq.protobuf.CodedOutputStream.computeEnumSize("+field.getTag()+", "+getter+".getNumber());");
} else if ( field.getGroup()!=null ) {
p("size += computeGroupSize("+field.getTag()+", "+getter+");");
} else {
@@ -695,15 +695,15 @@
* @param m
*/
private void generateMethodWriteTo(MessageDescriptor m) {
- p("public void writeUnframed(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {");
+ p("public void writeUnframed(org.apache.activemq.protobuf.CodedOutputStream output) throws java.io.IOException {");
indent();
if( deferredDecode ) {
p("if (encodedForm == null) {");
indent();
p("encodedForm = new byte[serializedSizeUnframed()];");
- p("com.google.protobuf.CodedOutputStream original = output;");
- p("output = com.google.protobuf.CodedOutputStream.newInstance(encodedForm);");
+ p("org.apache.activemq.protobuf.CodedOutputStream original = output;");
+ p("output = org.apache.activemq.protobuf.CodedOutputStream.newInstance(encodedForm);");
}
@@ -786,7 +786,7 @@
* @param className
*/
private void generateMethodMergeFromStream(MessageDescriptor m, String className) {
- p("public "+className+" mergeUnframed(com.google.protobuf.CodedInputStream input) throws java.io.IOException {");
+ p("public "+className+" mergeUnframed(org.apache.activemq.protobuf.CodedInputStream input) throws java.io.IOException {");
indent();
{
p("while (true) {");
@@ -1349,7 +1349,7 @@
if( field.isStringType() ) {
return asJavaString(defaultOption.getValue());
} else if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
- return "com.google.protobuf.ByteString.copyFromUtf8("+asJavaString(defaultOption.getValue())+")";
+ return "org.apache.activemq.protobuf.ByteString.copyFromUtf8("+asJavaString(defaultOption.getValue())+")";
} else if( field.isInteger32Type() ) {
int v;
if( field.getType() == FieldDescriptor.UINT32_TYPE ) {
@@ -1529,7 +1529,7 @@
return "java.lang.String";
}
if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
- return "com.google.protobuf.ByteString";
+ return "org.apache.activemq.protobuf.ByteString";
}
if( field.getType() == FieldDescriptor.BOOL_TYPE ) {
return "java.lang.Boolean";
@@ -1556,7 +1556,7 @@
return "java.lang.String";
}
if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
- return "com.google.protobuf.ByteString";
+ return "org.apache.activemq.protobuf.ByteString";
}
if( field.getType() == FieldDescriptor.BOOL_TYPE ) {
return "boolean";
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/ParserSupport.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/ParserSupport.java
index 58c820a..5ad1285 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/ParserSupport.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/ParserSupport.java
@@ -19,7 +19,6 @@
import org.apache.activemq.protobuf.compiler.TextFormat.InvalidEscapeSequence;
import org.apache.activemq.protobuf.compiler.parser.ParseException;
import org.apache.activemq.protobuf.compiler.parser.Token;
-import com.google.protobuf.ByteString;
public class ParserSupport {
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java
index e041e2f..616920a 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java
@@ -16,21 +16,14 @@
package org.apache.activemq.protobuf.compiler;
-import com.google.protobuf.ByteString;
-import com.google.protobuf.Descriptors.Descriptor;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-import com.google.protobuf.Descriptors.EnumDescriptor;
-import com.google.protobuf.Descriptors.EnumValueDescriptor;
-
import java.io.IOException;
-import java.nio.CharBuffer;
import java.math.BigInteger;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.nio.CharBuffer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.activemq.protobuf.ByteString;
+
/**
* Provide ascii text parsing and formatting support for proto2 instances.
* The implementation largely follows google/protobuf/text_format.cc.