Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
90 Kevin 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 {
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
 
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
 
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
 
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
104
    public abstract BuilderType clone();
105
 
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.
112
    public abstract BuilderType mergeFrom(
113
        final CodedInputStream input,
114
        final ExtensionRegistryLite extensionRegistry)
115
        throws IOException;
116
 
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
 
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
 
151
    public BuilderType mergeFrom(final byte[] data)
152
        throws InvalidProtocolBufferException {
153
      return mergeFrom(data, 0, data.length);
154
    }
155
 
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
 
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
 
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
 
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
 
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
 
226
      LimitedInputStream(InputStream in, int limit) {
227
        super(in);
228
        this.limit = limit;
229
      }
230
 
231
      @Override
232
      public int available() throws IOException {
233
        return Math.min(super.available(), limit);
234
      }
235
 
236
      @Override
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
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
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
 
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
 
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
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
     */
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
        final Collection<T> collection = (Collection<T>) values;
317
        list.addAll(collection);
318
      } else {
319
        for (final T value : values) {
320
          list.add(value);
321
        }
322
      }
323
    }
324
  }
325
}