• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2013 Google Inc.  All rights reserved.
3 // http://code.google.com/p/protobuf/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 package com.google.protobuf.nano;
32 
33 import java.io.IOException;
34 
35 /**
36  * Abstract interface implemented by Protocol Message objects.
37  *
38  * @author wink@google.com Wink Saville
39  */
40 public abstract class MessageNano {
41     protected volatile int cachedSize = -1;
42 
43     /**
44      * Get the number of bytes required to encode this message.
45      * Returns the cached size or calls getSerializedSize which
46      * sets the cached size. This is used internally when serializing
47      * so the size is only computed once. If a member is modified
48      * then this could be stale call getSerializedSize if in doubt.
49      */
getCachedSize()50     public int getCachedSize() {
51         if (cachedSize < 0) {
52             // getSerializedSize sets cachedSize
53             getSerializedSize();
54         }
55         return cachedSize;
56     }
57 
58     /**
59      * Computes the number of bytes required to encode this message.
60      * The size is cached and the cached result can be retrieved
61      * using getCachedSize().
62      */
getSerializedSize()63     public int getSerializedSize() {
64         int size = computeSerializedSize();
65         cachedSize = size;
66         return size;
67     }
68 
69     /**
70      * Computes the number of bytes required to encode this message. This does not update the
71      * cached size.
72      */
computeSerializedSize()73     protected int computeSerializedSize() {
74       // This is overridden if the generated message has serialized fields.
75       return 0;
76     }
77 
78     /**
79      * Serializes the message and writes it to {@code output}.
80      *
81      * @param output the output to receive the serialized form.
82      * @throws IOException if an error occurred writing to {@code output}.
83      */
writeTo(CodedOutputByteBufferNano output)84     public void writeTo(CodedOutputByteBufferNano output) throws IOException {
85         // Does nothing by default. Overridden by subclasses which have data to write.
86     }
87 
88     /**
89      * Parse {@code input} as a message of this type and merge it with the
90      * message being built.
91      */
mergeFrom(CodedInputByteBufferNano input)92     public abstract MessageNano mergeFrom(CodedInputByteBufferNano input) throws IOException;
93 
94     /**
95      * Serialize to a byte array.
96      * @return byte array with the serialized data.
97      */
toByteArray(MessageNano msg)98     public static final byte[] toByteArray(MessageNano msg) {
99         final byte[] result = new byte[msg.getSerializedSize()];
100         toByteArray(msg, result, 0, result.length);
101         return result;
102     }
103 
104     /**
105      * Serialize to a byte array starting at offset through length. The
106      * method getSerializedSize must have been called prior to calling
107      * this method so the proper length is know.  If an attempt to
108      * write more than length bytes OutOfSpaceException will be thrown
109      * and if length bytes are not written then IllegalStateException
110      * is thrown.
111      */
toByteArray(MessageNano msg, byte[] data, int offset, int length)112     public static final void toByteArray(MessageNano msg, byte[] data, int offset, int length) {
113         try {
114             final CodedOutputByteBufferNano output =
115                 CodedOutputByteBufferNano.newInstance(data, offset, length);
116             msg.writeTo(output);
117             output.checkNoSpaceLeft();
118         } catch (IOException e) {
119             throw new RuntimeException("Serializing to a byte array threw an IOException "
120                     + "(should never happen).", e);
121         }
122     }
123 
124     /**
125      * Parse {@code data} as a message of this type and merge it with the
126      * message being built.
127      */
mergeFrom(T msg, final byte[] data)128     public static final <T extends MessageNano> T mergeFrom(T msg, final byte[] data)
129         throws InvalidProtocolBufferNanoException {
130         return mergeFrom(msg, data, 0, data.length);
131     }
132 
133     /**
134      * Parse {@code data} as a message of this type and merge it with the
135      * message being built.
136      */
mergeFrom(T msg, final byte[] data, final int off, final int len)137     public static final <T extends MessageNano> T mergeFrom(T msg, final byte[] data,
138             final int off, final int len) throws InvalidProtocolBufferNanoException {
139         try {
140             final CodedInputByteBufferNano input =
141                 CodedInputByteBufferNano.newInstance(data, off, len);
142             msg.mergeFrom(input);
143             input.checkLastTagWas(0);
144             return msg;
145         } catch (InvalidProtocolBufferNanoException e) {
146             throw e;
147         } catch (IOException e) {
148             throw new RuntimeException("Reading from a byte array threw an IOException (should "
149                     + "never happen).");
150         }
151     }
152 
153     /**
154      * Returns a string that is (mostly) compatible with ProtoBuffer's TextFormat. Note that groups
155      * (which are deprecated) are not serialized with the correct field name.
156      *
157      * <p>This is implemented using reflection, so it is not especially fast nor is it guaranteed
158      * to find all fields if you have method removal turned on for proguard.
159      */
160     @Override
toString()161     public String toString() {
162         return MessageNanoPrinter.print(this);
163     }
164 }
165