• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 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;
32 
33 import java.io.FilterInputStream;
34 import java.io.InputStream;
35 import java.io.IOException;
36 import java.io.OutputStream;
37 import java.util.Collection;
38 
39 /**
40  * A partial implementation of the {@link MessageLite} interface which
41  * implements as many methods of that interface as possible in terms of other
42  * methods.
43  *
44  * @author kenton@google.com Kenton Varda
45  */
46 public abstract class AbstractMessageLite implements MessageLite {
toByteString()47   public ByteString toByteString() {
48     try {
49       final ByteString.CodedBuilder out =
50         ByteString.newCodedBuilder(getSerializedSize());
51       writeTo(out.getCodedOutput());
52       return out.build();
53     } catch (IOException e) {
54       throw new RuntimeException(
55         "Serializing to a ByteString threw an IOException (should " +
56         "never happen).", e);
57     }
58   }
59 
toByteArray()60   public byte[] toByteArray() {
61     try {
62       final byte[] result = new byte[getSerializedSize()];
63       final CodedOutputStream output = CodedOutputStream.newInstance(result);
64       writeTo(output);
65       output.checkNoSpaceLeft();
66       return result;
67     } catch (IOException e) {
68       throw new RuntimeException(
69         "Serializing to a byte array threw an IOException " +
70         "(should never happen).", e);
71     }
72   }
73 
writeTo(final OutputStream output)74   public void writeTo(final OutputStream output) throws IOException {
75     final int bufferSize =
76         CodedOutputStream.computePreferredBufferSize(getSerializedSize());
77     final CodedOutputStream codedOutput =
78         CodedOutputStream.newInstance(output, bufferSize);
79     writeTo(codedOutput);
80     codedOutput.flush();
81   }
82 
writeDelimitedTo(final OutputStream output)83   public void writeDelimitedTo(final OutputStream output) throws IOException {
84     final int serialized = getSerializedSize();
85     final int bufferSize = CodedOutputStream.computePreferredBufferSize(
86         CodedOutputStream.computeRawVarint32Size(serialized) + serialized);
87     final CodedOutputStream codedOutput =
88         CodedOutputStream.newInstance(output, bufferSize);
89     codedOutput.writeRawVarint32(serialized);
90     writeTo(codedOutput);
91     codedOutput.flush();
92   }
93 
94   /**
95    * A partial implementation of the {@link Message.Builder} interface which
96    * implements as many methods of that interface as possible in terms of
97    * other methods.
98    */
99   @SuppressWarnings("unchecked")
100   public static abstract class Builder<BuilderType extends Builder>
101       implements MessageLite.Builder {
102     // The compiler produces an error if this is not declared explicitly.
103     @Override
clone()104     public abstract BuilderType clone();
105 
mergeFrom(final CodedInputStream input)106     public BuilderType mergeFrom(final CodedInputStream input)
107                                  throws IOException {
108       return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
109     }
110 
111     // Re-defined here for return type covariance.
mergeFrom( final CodedInputStream input, final ExtensionRegistryLite extensionRegistry)112     public abstract BuilderType mergeFrom(
113         final CodedInputStream input,
114         final ExtensionRegistryLite extensionRegistry)
115         throws IOException;
116 
mergeFrom(final ByteString data)117     public BuilderType mergeFrom(final ByteString data)
118         throws InvalidProtocolBufferException {
119       try {
120         final CodedInputStream input = data.newCodedInput();
121         mergeFrom(input);
122         input.checkLastTagWas(0);
123         return (BuilderType) this;
124       } catch (InvalidProtocolBufferException e) {
125         throw e;
126       } catch (IOException e) {
127         throw new RuntimeException(
128           "Reading from a ByteString threw an IOException (should " +
129           "never happen).", e);
130       }
131     }
132 
mergeFrom( final ByteString data, final ExtensionRegistryLite extensionRegistry)133     public BuilderType mergeFrom(
134         final ByteString data,
135         final ExtensionRegistryLite extensionRegistry)
136         throws InvalidProtocolBufferException {
137       try {
138         final CodedInputStream input = data.newCodedInput();
139         mergeFrom(input, extensionRegistry);
140         input.checkLastTagWas(0);
141         return (BuilderType) this;
142       } catch (InvalidProtocolBufferException e) {
143         throw e;
144       } catch (IOException e) {
145         throw new RuntimeException(
146           "Reading from a ByteString threw an IOException (should " +
147           "never happen).", e);
148       }
149     }
150 
mergeFrom(final byte[] data)151     public BuilderType mergeFrom(final byte[] data)
152         throws InvalidProtocolBufferException {
153       return mergeFrom(data, 0, data.length);
154     }
155 
mergeFrom(final byte[] data, final int off, final int len)156     public BuilderType mergeFrom(final byte[] data, final int off,
157                                  final int len)
158                                  throws InvalidProtocolBufferException {
159       try {
160         final CodedInputStream input =
161             CodedInputStream.newInstance(data, off, len);
162         mergeFrom(input);
163         input.checkLastTagWas(0);
164         return (BuilderType) this;
165       } catch (InvalidProtocolBufferException e) {
166         throw e;
167       } catch (IOException e) {
168         throw new RuntimeException(
169           "Reading from a byte array threw an IOException (should " +
170           "never happen).", e);
171       }
172     }
173 
mergeFrom( final byte[] data, final ExtensionRegistryLite extensionRegistry)174     public BuilderType mergeFrom(
175         final byte[] data,
176         final ExtensionRegistryLite extensionRegistry)
177         throws InvalidProtocolBufferException {
178       return mergeFrom(data, 0, data.length, extensionRegistry);
179     }
180 
mergeFrom( final byte[] data, final int off, final int len, final ExtensionRegistryLite extensionRegistry)181     public BuilderType mergeFrom(
182         final byte[] data, final int off, final int len,
183         final ExtensionRegistryLite extensionRegistry)
184         throws InvalidProtocolBufferException {
185       try {
186         final CodedInputStream input =
187             CodedInputStream.newInstance(data, off, len);
188         mergeFrom(input, extensionRegistry);
189         input.checkLastTagWas(0);
190         return (BuilderType) this;
191       } catch (InvalidProtocolBufferException e) {
192         throw e;
193       } catch (IOException e) {
194         throw new RuntimeException(
195           "Reading from a byte array threw an IOException (should " +
196           "never happen).", e);
197       }
198     }
199 
mergeFrom(final InputStream input)200     public BuilderType mergeFrom(final InputStream input) throws IOException {
201       final CodedInputStream codedInput = CodedInputStream.newInstance(input);
202       mergeFrom(codedInput);
203       codedInput.checkLastTagWas(0);
204       return (BuilderType) this;
205     }
206 
mergeFrom( final InputStream input, final ExtensionRegistryLite extensionRegistry)207     public BuilderType mergeFrom(
208         final InputStream input,
209         final ExtensionRegistryLite extensionRegistry)
210         throws IOException {
211       final CodedInputStream codedInput = CodedInputStream.newInstance(input);
212       mergeFrom(codedInput, extensionRegistry);
213       codedInput.checkLastTagWas(0);
214       return (BuilderType) this;
215     }
216 
217     /**
218      * An InputStream implementations which reads from some other InputStream
219      * but is limited to a particular number of bytes.  Used by
220      * mergeDelimitedFrom().  This is intentionally package-private so that
221      * UnknownFieldSet can share it.
222      */
223     static final class LimitedInputStream extends FilterInputStream {
224       private int limit;
225 
LimitedInputStream(InputStream in, int limit)226       LimitedInputStream(InputStream in, int limit) {
227         super(in);
228         this.limit = limit;
229       }
230 
231       @Override
available()232       public int available() throws IOException {
233         return Math.min(super.available(), limit);
234       }
235 
236       @Override
read()237       public int read() throws IOException {
238         if (limit <= 0) {
239           return -1;
240         }
241         final int result = super.read();
242         if (result >= 0) {
243           --limit;
244         }
245         return result;
246       }
247 
248       @Override
read(final byte[] b, final int off, int len)249       public int read(final byte[] b, final int off, int len)
250                       throws IOException {
251         if (limit <= 0) {
252           return -1;
253         }
254         len = Math.min(len, limit);
255         final int result = super.read(b, off, len);
256         if (result >= 0) {
257           limit -= result;
258         }
259         return result;
260       }
261 
262       @Override
skip(final long n)263       public long skip(final long n) throws IOException {
264         final long result = super.skip(Math.min(n, limit));
265         if (result >= 0) {
266           limit -= result;
267         }
268         return result;
269       }
270     }
271 
mergeDelimitedFrom( final InputStream input, final ExtensionRegistryLite extensionRegistry)272     public boolean mergeDelimitedFrom(
273         final InputStream input,
274         final ExtensionRegistryLite extensionRegistry)
275         throws IOException {
276       final int firstByte = input.read();
277       if (firstByte == -1) {
278         return false;
279       }
280       final int size = CodedInputStream.readRawVarint32(firstByte, input);
281       final InputStream limitedInput = new LimitedInputStream(input, size);
282       mergeFrom(limitedInput, extensionRegistry);
283       return true;
284     }
285 
mergeDelimitedFrom(final InputStream input)286     public boolean mergeDelimitedFrom(final InputStream input)
287         throws IOException {
288       return mergeDelimitedFrom(input,
289           ExtensionRegistryLite.getEmptyRegistry());
290     }
291 
292     /**
293      * Construct an UninitializedMessageException reporting missing fields in
294      * the given message.
295      */
296     protected static UninitializedMessageException
newUninitializedMessageException(MessageLite message)297         newUninitializedMessageException(MessageLite message) {
298       return new UninitializedMessageException(message);
299     }
300 
301     /**
302      * Adds the {@code values} to the {@code list}.  This is a helper method
303      * used by generated code.  Users should ignore it.
304      *
305      * @throws NullPointerException if any of the elements of {@code values} is
306      * null.
307      */
addAll(final Iterable<T> values, final Collection<? super T> list)308     protected static <T> void addAll(final Iterable<T> values,
309                                      final Collection<? super T> list) {
310       for (final T value : values) {
311         if (value == null) {
312           throw new NullPointerException();
313         }
314       }
315       if (values instanceof Collection) {
316         @SuppressWarnings("unsafe") final
317         Collection<T> collection = (Collection<T>) values;
318         list.addAll(collection);
319       } else {
320         for (final T value : values) {
321           list.add(value);
322         }
323       }
324     }
325   }
326 }
327