summaryrefslogtreecommitdiff
path: root/javanano/src/main/java/com/google/protobuf/nano/MessageNano.java
diff options
context:
space:
mode:
Diffstat (limited to 'javanano/src/main/java/com/google/protobuf/nano/MessageNano.java')
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/MessageNano.java198
1 files changed, 198 insertions, 0 deletions
diff --git a/javanano/src/main/java/com/google/protobuf/nano/MessageNano.java b/javanano/src/main/java/com/google/protobuf/nano/MessageNano.java
new file mode 100644
index 00000000..23475027
--- /dev/null
+++ b/javanano/src/main/java/com/google/protobuf/nano/MessageNano.java
@@ -0,0 +1,198 @@
+// 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();
+ }
+}