• 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.OutputStream;
34 import java.io.IOException;
35 import java.io.UnsupportedEncodingException;
36 
37 /**
38  * Encodes and writes protocol message fields.
39  *
40  * <p>This class contains two kinds of methods:  methods that write specific
41  * protocol message constructs and field types (e.g. {@link #writeTag} and
42  * {@link #writeInt32}) and methods that write low-level values (e.g.
43  * {@link #writeRawVarint32} and {@link #writeRawBytes}).  If you are
44  * writing encoded protocol messages, you should use the former methods, but if
45  * you are writing some other format of your own design, use the latter.
46  *
47  * <p>This class is totally unsynchronized.
48  *
49  * @author kneton@google.com Kenton Varda
50  */
51 public final class CodedOutputStream {
52   private final byte[] buffer;
53   private final int limit;
54   private int position;
55 
56   private final OutputStream output;
57 
58   /**
59    * The buffer size used in {@link #newInstance(OutputStream)}.
60    */
61   public static final int DEFAULT_BUFFER_SIZE = 4096;
62 
63   /**
64    * Returns the buffer size to efficiently write dataLength bytes to this
65    * CodedOutputStream. Used by AbstractMessageLite.
66    *
67    * @return the buffer size to efficiently write dataLength bytes to this
68    *         CodedOutputStream.
69    */
computePreferredBufferSize(int dataLength)70   static int computePreferredBufferSize(int dataLength) {
71     if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE;
72     return dataLength;
73   }
74 
CodedOutputStream(final byte[] buffer, final int offset, final int length)75   private CodedOutputStream(final byte[] buffer, final int offset,
76                             final int length) {
77     output = null;
78     this.buffer = buffer;
79     position = offset;
80     limit = offset + length;
81   }
82 
CodedOutputStream(final OutputStream output, final byte[] buffer)83   private CodedOutputStream(final OutputStream output, final byte[] buffer) {
84     this.output = output;
85     this.buffer = buffer;
86     position = 0;
87     limit = buffer.length;
88   }
89 
90   /**
91    * Create a new {@code CodedOutputStream} wrapping the given
92    * {@code OutputStream}.
93    */
newInstance(final OutputStream output)94   public static CodedOutputStream newInstance(final OutputStream output) {
95     return newInstance(output, DEFAULT_BUFFER_SIZE);
96   }
97 
98   /**
99    * Create a new {@code CodedOutputStream} wrapping the given
100    * {@code OutputStream} with a given buffer size.
101    */
newInstance(final OutputStream output, final int bufferSize)102   public static CodedOutputStream newInstance(final OutputStream output,
103       final int bufferSize) {
104     return new CodedOutputStream(output, new byte[bufferSize]);
105   }
106 
107   /**
108    * Create a new {@code CodedOutputStream} that writes directly to the given
109    * byte array.  If more bytes are written than fit in the array,
110    * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
111    * array is faster than writing to an {@code OutputStream}.  See also
112    * {@link ByteString#newCodedBuilder}.
113    */
newInstance(final byte[] flatArray)114   public static CodedOutputStream newInstance(final byte[] flatArray) {
115     return newInstance(flatArray, 0, flatArray.length);
116   }
117 
118   /**
119    * Create a new {@code CodedOutputStream} that writes directly to the given
120    * byte array slice.  If more bytes are written than fit in the slice,
121    * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
122    * array is faster than writing to an {@code OutputStream}.  See also
123    * {@link ByteString#newCodedBuilder}.
124    */
newInstance(final byte[] flatArray, final int offset, final int length)125   public static CodedOutputStream newInstance(final byte[] flatArray,
126                                               final int offset,
127                                               final int length) {
128     return new CodedOutputStream(flatArray, offset, length);
129   }
130 
131   // -----------------------------------------------------------------
132 
133   /** Write a {@code double} field, including tag, to the stream. */
writeDouble(final int fieldNumber, final double value)134   public void writeDouble(final int fieldNumber, final double value)
135                           throws IOException {
136     writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
137     writeDoubleNoTag(value);
138   }
139 
140   /** Write a {@code float} field, including tag, to the stream. */
writeFloat(final int fieldNumber, final float value)141   public void writeFloat(final int fieldNumber, final float value)
142                          throws IOException {
143     writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
144     writeFloatNoTag(value);
145   }
146 
147   /** Write a {@code uint64} field, including tag, to the stream. */
writeUInt64(final int fieldNumber, final long value)148   public void writeUInt64(final int fieldNumber, final long value)
149                           throws IOException {
150     writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
151     writeUInt64NoTag(value);
152   }
153 
154   /** Write an {@code int64} field, including tag, to the stream. */
writeInt64(final int fieldNumber, final long value)155   public void writeInt64(final int fieldNumber, final long value)
156                          throws IOException {
157     writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
158     writeInt64NoTag(value);
159   }
160 
161   /** Write an {@code int32} field, including tag, to the stream. */
writeInt32(final int fieldNumber, final int value)162   public void writeInt32(final int fieldNumber, final int value)
163                          throws IOException {
164     writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
165     writeInt32NoTag(value);
166   }
167 
168   /** Write a {@code fixed64} field, including tag, to the stream. */
writeFixed64(final int fieldNumber, final long value)169   public void writeFixed64(final int fieldNumber, final long value)
170                            throws IOException {
171     writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
172     writeFixed64NoTag(value);
173   }
174 
175   /** Write a {@code fixed32} field, including tag, to the stream. */
writeFixed32(final int fieldNumber, final int value)176   public void writeFixed32(final int fieldNumber, final int value)
177                            throws IOException {
178     writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
179     writeFixed32NoTag(value);
180   }
181 
182   /** Write a {@code bool} field, including tag, to the stream. */
writeBool(final int fieldNumber, final boolean value)183   public void writeBool(final int fieldNumber, final boolean value)
184                         throws IOException {
185     writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
186     writeBoolNoTag(value);
187   }
188 
189   /** Write a {@code string} field, including tag, to the stream. */
writeString(final int fieldNumber, final String value)190   public void writeString(final int fieldNumber, final String value)
191                           throws IOException {
192     writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
193     writeStringNoTag(value);
194   }
195 
196   /** Write a {@code group} field, including tag, to the stream. */
writeGroup(final int fieldNumber, final MessageLite value)197   public void writeGroup(final int fieldNumber, final MessageLite value)
198                          throws IOException {
199     writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
200     writeGroupNoTag(value);
201     writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
202   }
203 
204   /**
205    * Write a group represented by an {@link UnknownFieldSet}.
206    *
207    * @deprecated UnknownFieldSet now implements MessageLite, so you can just
208    *             call {@link #writeGroup}.
209    */
210   @Deprecated
writeUnknownGroup(final int fieldNumber, final MessageLite value)211   public void writeUnknownGroup(final int fieldNumber,
212                                 final MessageLite value)
213                                 throws IOException {
214     writeGroup(fieldNumber, value);
215   }
216 
217   /** Write an embedded message field, including tag, to the stream. */
writeMessage(final int fieldNumber, final MessageLite value)218   public void writeMessage(final int fieldNumber, final MessageLite value)
219                            throws IOException {
220     writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
221     writeMessageNoTag(value);
222   }
223 
224   /** Write a {@code bytes} field, including tag, to the stream. */
writeBytes(final int fieldNumber, final ByteString value)225   public void writeBytes(final int fieldNumber, final ByteString value)
226                          throws IOException {
227     writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
228     writeBytesNoTag(value);
229   }
230 
231   /** Write a {@code uint32} field, including tag, to the stream. */
writeUInt32(final int fieldNumber, final int value)232   public void writeUInt32(final int fieldNumber, final int value)
233                           throws IOException {
234     writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
235     writeUInt32NoTag(value);
236   }
237 
238   /**
239    * Write an enum field, including tag, to the stream.  Caller is responsible
240    * for converting the enum value to its numeric value.
241    */
writeEnum(final int fieldNumber, final int value)242   public void writeEnum(final int fieldNumber, final int value)
243                         throws IOException {
244     writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
245     writeEnumNoTag(value);
246   }
247 
248   /** Write an {@code sfixed32} field, including tag, to the stream. */
writeSFixed32(final int fieldNumber, final int value)249   public void writeSFixed32(final int fieldNumber, final int value)
250                             throws IOException {
251     writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
252     writeSFixed32NoTag(value);
253   }
254 
255   /** Write an {@code sfixed64} field, including tag, to the stream. */
writeSFixed64(final int fieldNumber, final long value)256   public void writeSFixed64(final int fieldNumber, final long value)
257                             throws IOException {
258     writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
259     writeSFixed64NoTag(value);
260   }
261 
262   /** Write an {@code sint32} field, including tag, to the stream. */
writeSInt32(final int fieldNumber, final int value)263   public void writeSInt32(final int fieldNumber, final int value)
264                           throws IOException {
265     writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
266     writeSInt32NoTag(value);
267   }
268 
269   /** Write an {@code sint64} field, including tag, to the stream. */
writeSInt64(final int fieldNumber, final long value)270   public void writeSInt64(final int fieldNumber, final long value)
271                           throws IOException {
272     writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
273     writeSInt64NoTag(value);
274   }
275 
276   /**
277    * Write a MessageSet extension field to the stream.  For historical reasons,
278    * the wire format differs from normal fields.
279    */
writeMessageSetExtension(final int fieldNumber, final MessageLite value)280   public void writeMessageSetExtension(final int fieldNumber,
281                                        final MessageLite value)
282                                        throws IOException {
283     writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
284     writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
285     writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
286     writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
287   }
288 
289   /**
290    * Write an unparsed MessageSet extension field to the stream.  For
291    * historical reasons, the wire format differs from normal fields.
292    */
writeRawMessageSetExtension(final int fieldNumber, final ByteString value)293   public void writeRawMessageSetExtension(final int fieldNumber,
294                                           final ByteString value)
295                                           throws IOException {
296     writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
297     writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
298     writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
299     writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
300   }
301 
302   // -----------------------------------------------------------------
303 
304   /** Write a {@code double} field to the stream. */
writeDoubleNoTag(final double value)305   public void writeDoubleNoTag(final double value) throws IOException {
306     writeRawLittleEndian64(Double.doubleToRawLongBits(value));
307   }
308 
309   /** Write a {@code float} field to the stream. */
writeFloatNoTag(final float value)310   public void writeFloatNoTag(final float value) throws IOException {
311     writeRawLittleEndian32(Float.floatToRawIntBits(value));
312   }
313 
314   /** Write a {@code uint64} field to the stream. */
writeUInt64NoTag(final long value)315   public void writeUInt64NoTag(final long value) throws IOException {
316     writeRawVarint64(value);
317   }
318 
319   /** Write an {@code int64} field to the stream. */
writeInt64NoTag(final long value)320   public void writeInt64NoTag(final long value) throws IOException {
321     writeRawVarint64(value);
322   }
323 
324   /** Write an {@code int32} field to the stream. */
writeInt32NoTag(final int value)325   public void writeInt32NoTag(final int value) throws IOException {
326     if (value >= 0) {
327       writeRawVarint32(value);
328     } else {
329       // Must sign-extend.
330       writeRawVarint64(value);
331     }
332   }
333 
334   /** Write a {@code fixed64} field to the stream. */
writeFixed64NoTag(final long value)335   public void writeFixed64NoTag(final long value) throws IOException {
336     writeRawLittleEndian64(value);
337   }
338 
339   /** Write a {@code fixed32} field to the stream. */
writeFixed32NoTag(final int value)340   public void writeFixed32NoTag(final int value) throws IOException {
341     writeRawLittleEndian32(value);
342   }
343 
344   /** Write a {@code bool} field to the stream. */
writeBoolNoTag(final boolean value)345   public void writeBoolNoTag(final boolean value) throws IOException {
346     writeRawByte(value ? 1 : 0);
347   }
348 
349   /** Write a {@code string} field to the stream. */
writeStringNoTag(final String value)350   public void writeStringNoTag(final String value) throws IOException {
351     // Unfortunately there does not appear to be any way to tell Java to encode
352     // UTF-8 directly into our buffer, so we have to let it create its own byte
353     // array and then copy.
354     final byte[] bytes = value.getBytes("UTF-8");
355     writeRawVarint32(bytes.length);
356     writeRawBytes(bytes);
357   }
358 
359   /** Write a {@code group} field to the stream. */
writeGroupNoTag(final MessageLite value)360   public void writeGroupNoTag(final MessageLite value) throws IOException {
361     value.writeTo(this);
362   }
363 
364   /**
365    * Write a group represented by an {@link UnknownFieldSet}.
366    *
367    * @deprecated UnknownFieldSet now implements MessageLite, so you can just
368    *             call {@link #writeGroupNoTag}.
369    */
370   @Deprecated
writeUnknownGroupNoTag(final MessageLite value)371   public void writeUnknownGroupNoTag(final MessageLite value)
372       throws IOException {
373     writeGroupNoTag(value);
374   }
375 
376   /** Write an embedded message field to the stream. */
writeMessageNoTag(final MessageLite value)377   public void writeMessageNoTag(final MessageLite value) throws IOException {
378     writeRawVarint32(value.getSerializedSize());
379     value.writeTo(this);
380   }
381 
382   /** Write a {@code bytes} field to the stream. */
writeBytesNoTag(final ByteString value)383   public void writeBytesNoTag(final ByteString value) throws IOException {
384     final byte[] bytes = value.toByteArray();
385     writeRawVarint32(bytes.length);
386     writeRawBytes(bytes);
387   }
388 
389   /** Write a {@code uint32} field to the stream. */
writeUInt32NoTag(final int value)390   public void writeUInt32NoTag(final int value) throws IOException {
391     writeRawVarint32(value);
392   }
393 
394   /**
395    * Write an enum field to the stream.  Caller is responsible
396    * for converting the enum value to its numeric value.
397    */
writeEnumNoTag(final int value)398   public void writeEnumNoTag(final int value) throws IOException {
399     writeRawVarint32(value);
400   }
401 
402   /** Write an {@code sfixed32} field to the stream. */
writeSFixed32NoTag(final int value)403   public void writeSFixed32NoTag(final int value) throws IOException {
404     writeRawLittleEndian32(value);
405   }
406 
407   /** Write an {@code sfixed64} field to the stream. */
writeSFixed64NoTag(final long value)408   public void writeSFixed64NoTag(final long value) throws IOException {
409     writeRawLittleEndian64(value);
410   }
411 
412   /** Write an {@code sint32} field to the stream. */
writeSInt32NoTag(final int value)413   public void writeSInt32NoTag(final int value) throws IOException {
414     writeRawVarint32(encodeZigZag32(value));
415   }
416 
417   /** Write an {@code sint64} field to the stream. */
writeSInt64NoTag(final long value)418   public void writeSInt64NoTag(final long value) throws IOException {
419     writeRawVarint64(encodeZigZag64(value));
420   }
421 
422   // =================================================================
423 
424   /**
425    * Compute the number of bytes that would be needed to encode a
426    * {@code double} field, including tag.
427    */
computeDoubleSize(final int fieldNumber, final double value)428   public static int computeDoubleSize(final int fieldNumber,
429                                       final double value) {
430     return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
431   }
432 
433   /**
434    * Compute the number of bytes that would be needed to encode a
435    * {@code float} field, including tag.
436    */
computeFloatSize(final int fieldNumber, final float value)437   public static int computeFloatSize(final int fieldNumber, final float value) {
438     return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
439   }
440 
441   /**
442    * Compute the number of bytes that would be needed to encode a
443    * {@code uint64} field, including tag.
444    */
computeUInt64Size(final int fieldNumber, final long value)445   public static int computeUInt64Size(final int fieldNumber, final long value) {
446     return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
447   }
448 
449   /**
450    * Compute the number of bytes that would be needed to encode an
451    * {@code int64} field, including tag.
452    */
computeInt64Size(final int fieldNumber, final long value)453   public static int computeInt64Size(final int fieldNumber, final long value) {
454     return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
455   }
456 
457   /**
458    * Compute the number of bytes that would be needed to encode an
459    * {@code int32} field, including tag.
460    */
computeInt32Size(final int fieldNumber, final int value)461   public static int computeInt32Size(final int fieldNumber, final int value) {
462     return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
463   }
464 
465   /**
466    * Compute the number of bytes that would be needed to encode a
467    * {@code fixed64} field, including tag.
468    */
computeFixed64Size(final int fieldNumber, final long value)469   public static int computeFixed64Size(final int fieldNumber,
470                                        final long value) {
471     return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
472   }
473 
474   /**
475    * Compute the number of bytes that would be needed to encode a
476    * {@code fixed32} field, including tag.
477    */
computeFixed32Size(final int fieldNumber, final int value)478   public static int computeFixed32Size(final int fieldNumber,
479                                        final int value) {
480     return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
481   }
482 
483   /**
484    * Compute the number of bytes that would be needed to encode a
485    * {@code bool} field, including tag.
486    */
computeBoolSize(final int fieldNumber, final boolean value)487   public static int computeBoolSize(final int fieldNumber,
488                                     final boolean value) {
489     return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
490   }
491 
492   /**
493    * Compute the number of bytes that would be needed to encode a
494    * {@code string} field, including tag.
495    */
computeStringSize(final int fieldNumber, final String value)496   public static int computeStringSize(final int fieldNumber,
497                                       final String value) {
498     return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
499   }
500 
501   /**
502    * Compute the number of bytes that would be needed to encode a
503    * {@code group} field, including tag.
504    */
computeGroupSize(final int fieldNumber, final MessageLite value)505   public static int computeGroupSize(final int fieldNumber,
506                                      final MessageLite value) {
507     return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
508   }
509 
510   /**
511    * Compute the number of bytes that would be needed to encode a
512    * {@code group} field represented by an {@code UnknownFieldSet}, including
513    * tag.
514    *
515    * @deprecated UnknownFieldSet now implements MessageLite, so you can just
516    *             call {@link #computeGroupSize}.
517    */
518   @Deprecated
computeUnknownGroupSize(final int fieldNumber, final MessageLite value)519   public static int computeUnknownGroupSize(final int fieldNumber,
520                                             final MessageLite value) {
521     return computeGroupSize(fieldNumber, value);
522   }
523 
524   /**
525    * Compute the number of bytes that would be needed to encode an
526    * embedded message field, including tag.
527    */
computeMessageSize(final int fieldNumber, final MessageLite value)528   public static int computeMessageSize(final int fieldNumber,
529                                        final MessageLite value) {
530     return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
531   }
532 
533   /**
534    * Compute the number of bytes that would be needed to encode a
535    * {@code bytes} field, including tag.
536    */
computeBytesSize(final int fieldNumber, final ByteString value)537   public static int computeBytesSize(final int fieldNumber,
538                                      final ByteString value) {
539     return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
540   }
541 
542   /**
543    * Compute the number of bytes that would be needed to encode a
544    * {@code uint32} field, including tag.
545    */
computeUInt32Size(final int fieldNumber, final int value)546   public static int computeUInt32Size(final int fieldNumber, final int value) {
547     return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
548   }
549 
550   /**
551    * Compute the number of bytes that would be needed to encode an
552    * enum field, including tag.  Caller is responsible for converting the
553    * enum value to its numeric value.
554    */
computeEnumSize(final int fieldNumber, final int value)555   public static int computeEnumSize(final int fieldNumber, final int value) {
556     return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
557   }
558 
559   /**
560    * Compute the number of bytes that would be needed to encode an
561    * {@code sfixed32} field, including tag.
562    */
computeSFixed32Size(final int fieldNumber, final int value)563   public static int computeSFixed32Size(final int fieldNumber,
564                                         final int value) {
565     return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
566   }
567 
568   /**
569    * Compute the number of bytes that would be needed to encode an
570    * {@code sfixed64} field, including tag.
571    */
computeSFixed64Size(final int fieldNumber, final long value)572   public static int computeSFixed64Size(final int fieldNumber,
573                                         final long value) {
574     return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
575   }
576 
577   /**
578    * Compute the number of bytes that would be needed to encode an
579    * {@code sint32} field, including tag.
580    */
computeSInt32Size(final int fieldNumber, final int value)581   public static int computeSInt32Size(final int fieldNumber, final int value) {
582     return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
583   }
584 
585   /**
586    * Compute the number of bytes that would be needed to encode an
587    * {@code sint64} field, including tag.
588    */
computeSInt64Size(final int fieldNumber, final long value)589   public static int computeSInt64Size(final int fieldNumber, final long value) {
590     return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
591   }
592 
593   /**
594    * Compute the number of bytes that would be needed to encode a
595    * MessageSet extension to the stream.  For historical reasons,
596    * the wire format differs from normal fields.
597    */
computeMessageSetExtensionSize( final int fieldNumber, final MessageLite value)598   public static int computeMessageSetExtensionSize(
599       final int fieldNumber, final MessageLite value) {
600     return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
601            computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
602            computeMessageSize(WireFormat.MESSAGE_SET_MESSAGE, value);
603   }
604 
605   /**
606    * Compute the number of bytes that would be needed to encode an
607    * unparsed MessageSet extension field to the stream.  For
608    * historical reasons, the wire format differs from normal fields.
609    */
computeRawMessageSetExtensionSize( final int fieldNumber, final ByteString value)610   public static int computeRawMessageSetExtensionSize(
611       final int fieldNumber, final ByteString value) {
612     return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
613            computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
614            computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value);
615   }
616 
617   // -----------------------------------------------------------------
618 
619   /**
620    * Compute the number of bytes that would be needed to encode a
621    * {@code double} field, including tag.
622    */
computeDoubleSizeNoTag(final double value)623   public static int computeDoubleSizeNoTag(final double value) {
624     return LITTLE_ENDIAN_64_SIZE;
625   }
626 
627   /**
628    * Compute the number of bytes that would be needed to encode a
629    * {@code float} field, including tag.
630    */
computeFloatSizeNoTag(final float value)631   public static int computeFloatSizeNoTag(final float value) {
632     return LITTLE_ENDIAN_32_SIZE;
633   }
634 
635   /**
636    * Compute the number of bytes that would be needed to encode a
637    * {@code uint64} field, including tag.
638    */
computeUInt64SizeNoTag(final long value)639   public static int computeUInt64SizeNoTag(final long value) {
640     return computeRawVarint64Size(value);
641   }
642 
643   /**
644    * Compute the number of bytes that would be needed to encode an
645    * {@code int64} field, including tag.
646    */
computeInt64SizeNoTag(final long value)647   public static int computeInt64SizeNoTag(final long value) {
648     return computeRawVarint64Size(value);
649   }
650 
651   /**
652    * Compute the number of bytes that would be needed to encode an
653    * {@code int32} field, including tag.
654    */
computeInt32SizeNoTag(final int value)655   public static int computeInt32SizeNoTag(final int value) {
656     if (value >= 0) {
657       return computeRawVarint32Size(value);
658     } else {
659       // Must sign-extend.
660       return 10;
661     }
662   }
663 
664   /**
665    * Compute the number of bytes that would be needed to encode a
666    * {@code fixed64} field.
667    */
computeFixed64SizeNoTag(final long value)668   public static int computeFixed64SizeNoTag(final long value) {
669     return LITTLE_ENDIAN_64_SIZE;
670   }
671 
672   /**
673    * Compute the number of bytes that would be needed to encode a
674    * {@code fixed32} field.
675    */
computeFixed32SizeNoTag(final int value)676   public static int computeFixed32SizeNoTag(final int value) {
677     return LITTLE_ENDIAN_32_SIZE;
678   }
679 
680   /**
681    * Compute the number of bytes that would be needed to encode a
682    * {@code bool} field.
683    */
computeBoolSizeNoTag(final boolean value)684   public static int computeBoolSizeNoTag(final boolean value) {
685     return 1;
686   }
687 
688   /**
689    * Compute the number of bytes that would be needed to encode a
690    * {@code string} field.
691    */
computeStringSizeNoTag(final String value)692   public static int computeStringSizeNoTag(final String value) {
693     try {
694       final byte[] bytes = value.getBytes("UTF-8");
695       return computeRawVarint32Size(bytes.length) +
696              bytes.length;
697     } catch (UnsupportedEncodingException e) {
698       throw new RuntimeException("UTF-8 not supported.", e);
699     }
700   }
701 
702   /**
703    * Compute the number of bytes that would be needed to encode a
704    * {@code group} field.
705    */
computeGroupSizeNoTag(final MessageLite value)706   public static int computeGroupSizeNoTag(final MessageLite value) {
707     return value.getSerializedSize();
708   }
709 
710   /**
711    * Compute the number of bytes that would be needed to encode a
712    * {@code group} field represented by an {@code UnknownFieldSet}, including
713    * tag.
714    *
715    * @deprecated UnknownFieldSet now implements MessageLite, so you can just
716    *             call {@link #computeUnknownGroupSizeNoTag}.
717    */
718   @Deprecated
computeUnknownGroupSizeNoTag(final MessageLite value)719   public static int computeUnknownGroupSizeNoTag(final MessageLite value) {
720     return computeGroupSizeNoTag(value);
721   }
722 
723   /**
724    * Compute the number of bytes that would be needed to encode an embedded
725    * message field.
726    */
computeMessageSizeNoTag(final MessageLite value)727   public static int computeMessageSizeNoTag(final MessageLite value) {
728     final int size = value.getSerializedSize();
729     return computeRawVarint32Size(size) + size;
730   }
731 
732   /**
733    * Compute the number of bytes that would be needed to encode a
734    * {@code bytes} field.
735    */
computeBytesSizeNoTag(final ByteString value)736   public static int computeBytesSizeNoTag(final ByteString value) {
737     return computeRawVarint32Size(value.size()) +
738            value.size();
739   }
740 
741   /**
742    * Compute the number of bytes that would be needed to encode a
743    * {@code uint32} field.
744    */
computeUInt32SizeNoTag(final int value)745   public static int computeUInt32SizeNoTag(final int value) {
746     return computeRawVarint32Size(value);
747   }
748 
749   /**
750    * Compute the number of bytes that would be needed to encode an enum field.
751    * Caller is responsible for converting the enum value to its numeric value.
752    */
computeEnumSizeNoTag(final int value)753   public static int computeEnumSizeNoTag(final int value) {
754     return computeRawVarint32Size(value);
755   }
756 
757   /**
758    * Compute the number of bytes that would be needed to encode an
759    * {@code sfixed32} field.
760    */
computeSFixed32SizeNoTag(final int value)761   public static int computeSFixed32SizeNoTag(final int value) {
762     return LITTLE_ENDIAN_32_SIZE;
763   }
764 
765   /**
766    * Compute the number of bytes that would be needed to encode an
767    * {@code sfixed64} field.
768    */
computeSFixed64SizeNoTag(final long value)769   public static int computeSFixed64SizeNoTag(final long value) {
770     return LITTLE_ENDIAN_64_SIZE;
771   }
772 
773   /**
774    * Compute the number of bytes that would be needed to encode an
775    * {@code sint32} field.
776    */
computeSInt32SizeNoTag(final int value)777   public static int computeSInt32SizeNoTag(final int value) {
778     return computeRawVarint32Size(encodeZigZag32(value));
779   }
780 
781   /**
782    * Compute the number of bytes that would be needed to encode an
783    * {@code sint64} field.
784    */
computeSInt64SizeNoTag(final long value)785   public static int computeSInt64SizeNoTag(final long value) {
786     return computeRawVarint64Size(encodeZigZag64(value));
787   }
788 
789   // =================================================================
790 
791   /**
792    * Internal helper that writes the current buffer to the output. The
793    * buffer position is reset to its initial value when this returns.
794    */
refreshBuffer()795   private void refreshBuffer() throws IOException {
796     if (output == null) {
797       // We're writing to a single buffer.
798       throw new OutOfSpaceException();
799     }
800 
801     // Since we have an output stream, this is our buffer
802     // and buffer offset == 0
803     output.write(buffer, 0, position);
804     position = 0;
805   }
806 
807   /**
808    * Flushes the stream and forces any buffered bytes to be written.  This
809    * does not flush the underlying OutputStream.
810    */
flush()811   public void flush() throws IOException {
812     if (output != null) {
813       refreshBuffer();
814     }
815   }
816 
817   /**
818    * If writing to a flat array, return the space left in the array.
819    * Otherwise, throws {@code UnsupportedOperationException}.
820    */
spaceLeft()821   public int spaceLeft() {
822     if (output == null) {
823       return limit - position;
824     } else {
825       throw new UnsupportedOperationException(
826         "spaceLeft() can only be called on CodedOutputStreams that are " +
827         "writing to a flat array.");
828     }
829   }
830 
831   /**
832    * Verifies that {@link #spaceLeft()} returns zero.  It's common to create
833    * a byte array that is exactly big enough to hold a message, then write to
834    * it with a {@code CodedOutputStream}.  Calling {@code checkNoSpaceLeft()}
835    * after writing verifies that the message was actually as big as expected,
836    * which can help catch bugs.
837    */
checkNoSpaceLeft()838   public void checkNoSpaceLeft() {
839     if (spaceLeft() != 0) {
840       throw new IllegalStateException(
841         "Did not write as much data as expected.");
842     }
843   }
844 
845   /**
846    * If you create a CodedOutputStream around a simple flat array, you must
847    * not attempt to write more bytes than the array has space.  Otherwise,
848    * this exception will be thrown.
849    */
850   public static class OutOfSpaceException extends IOException {
851     private static final long serialVersionUID = -6947486886997889499L;
852 
OutOfSpaceException()853     OutOfSpaceException() {
854       super("CodedOutputStream was writing to a flat byte array and ran " +
855             "out of space.");
856     }
857   }
858 
859   /** Write a single byte. */
writeRawByte(final byte value)860   public void writeRawByte(final byte value) throws IOException {
861     if (position == limit) {
862       refreshBuffer();
863     }
864 
865     buffer[position++] = value;
866   }
867 
868   /** Write a single byte, represented by an integer value. */
writeRawByte(final int value)869   public void writeRawByte(final int value) throws IOException {
870     writeRawByte((byte) value);
871   }
872 
873   /** Write an array of bytes. */
writeRawBytes(final byte[] value)874   public void writeRawBytes(final byte[] value) throws IOException {
875     writeRawBytes(value, 0, value.length);
876   }
877 
878   /** Write part of an array of bytes. */
writeRawBytes(final byte[] value, int offset, int length)879   public void writeRawBytes(final byte[] value, int offset, int length)
880                             throws IOException {
881     if (limit - position >= length) {
882       // We have room in the current buffer.
883       System.arraycopy(value, offset, buffer, position, length);
884       position += length;
885     } else {
886       // Write extends past current buffer.  Fill the rest of this buffer and
887       // flush.
888       final int bytesWritten = limit - position;
889       System.arraycopy(value, offset, buffer, position, bytesWritten);
890       offset += bytesWritten;
891       length -= bytesWritten;
892       position = limit;
893       refreshBuffer();
894 
895       // Now deal with the rest.
896       // Since we have an output stream, this is our buffer
897       // and buffer offset == 0
898       if (length <= limit) {
899         // Fits in new buffer.
900         System.arraycopy(value, offset, buffer, 0, length);
901         position = length;
902       } else {
903         // Write is very big.  Let's do it all at once.
904         output.write(value, offset, length);
905       }
906     }
907   }
908 
909   /** Encode and write a tag. */
writeTag(final int fieldNumber, final int wireType)910   public void writeTag(final int fieldNumber, final int wireType)
911                        throws IOException {
912     writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType));
913   }
914 
915   /** Compute the number of bytes that would be needed to encode a tag. */
computeTagSize(final int fieldNumber)916   public static int computeTagSize(final int fieldNumber) {
917     return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0));
918   }
919 
920   /**
921    * Encode and write a varint.  {@code value} is treated as
922    * unsigned, so it won't be sign-extended if negative.
923    */
writeRawVarint32(int value)924   public void writeRawVarint32(int value) throws IOException {
925     while (true) {
926       if ((value & ~0x7F) == 0) {
927         writeRawByte(value);
928         return;
929       } else {
930         writeRawByte((value & 0x7F) | 0x80);
931         value >>>= 7;
932       }
933     }
934   }
935 
936   /**
937    * Compute the number of bytes that would be needed to encode a varint.
938    * {@code value} is treated as unsigned, so it won't be sign-extended if
939    * negative.
940    */
computeRawVarint32Size(final int value)941   public static int computeRawVarint32Size(final int value) {
942     if ((value & (0xffffffff <<  7)) == 0) return 1;
943     if ((value & (0xffffffff << 14)) == 0) return 2;
944     if ((value & (0xffffffff << 21)) == 0) return 3;
945     if ((value & (0xffffffff << 28)) == 0) return 4;
946     return 5;
947   }
948 
949   /** Encode and write a varint. */
writeRawVarint64(long value)950   public void writeRawVarint64(long value) throws IOException {
951     while (true) {
952       if ((value & ~0x7FL) == 0) {
953         writeRawByte((int)value);
954         return;
955       } else {
956         writeRawByte(((int)value & 0x7F) | 0x80);
957         value >>>= 7;
958       }
959     }
960   }
961 
962   /** Compute the number of bytes that would be needed to encode a varint. */
computeRawVarint64Size(final long value)963   public static int computeRawVarint64Size(final long value) {
964     if ((value & (0xffffffffffffffffL <<  7)) == 0) return 1;
965     if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
966     if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
967     if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
968     if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
969     if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
970     if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
971     if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
972     if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
973     return 10;
974   }
975 
976   /** Write a little-endian 32-bit integer. */
writeRawLittleEndian32(final int value)977   public void writeRawLittleEndian32(final int value) throws IOException {
978     writeRawByte((value      ) & 0xFF);
979     writeRawByte((value >>  8) & 0xFF);
980     writeRawByte((value >> 16) & 0xFF);
981     writeRawByte((value >> 24) & 0xFF);
982   }
983 
984   public static final int LITTLE_ENDIAN_32_SIZE = 4;
985 
986   /** Write a little-endian 64-bit integer. */
writeRawLittleEndian64(final long value)987   public void writeRawLittleEndian64(final long value) throws IOException {
988     writeRawByte((int)(value      ) & 0xFF);
989     writeRawByte((int)(value >>  8) & 0xFF);
990     writeRawByte((int)(value >> 16) & 0xFF);
991     writeRawByte((int)(value >> 24) & 0xFF);
992     writeRawByte((int)(value >> 32) & 0xFF);
993     writeRawByte((int)(value >> 40) & 0xFF);
994     writeRawByte((int)(value >> 48) & 0xFF);
995     writeRawByte((int)(value >> 56) & 0xFF);
996   }
997 
998   public static final int LITTLE_ENDIAN_64_SIZE = 8;
999 
1000   /**
1001    * Encode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
1002    * into values that can be efficiently encoded with varint.  (Otherwise,
1003    * negative values must be sign-extended to 64 bits to be varint encoded,
1004    * thus always taking 10 bytes on the wire.)
1005    *
1006    * @param n A signed 32-bit integer.
1007    * @return An unsigned 32-bit integer, stored in a signed int because
1008    *         Java has no explicit unsigned support.
1009    */
encodeZigZag32(final int n)1010   public static int encodeZigZag32(final int n) {
1011     // Note:  the right-shift must be arithmetic
1012     return (n << 1) ^ (n >> 31);
1013   }
1014 
1015   /**
1016    * Encode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
1017    * into values that can be efficiently encoded with varint.  (Otherwise,
1018    * negative values must be sign-extended to 64 bits to be varint encoded,
1019    * thus always taking 10 bytes on the wire.)
1020    *
1021    * @param n A signed 64-bit integer.
1022    * @return An unsigned 64-bit integer, stored in a signed int because
1023    *         Java has no explicit unsigned support.
1024    */
encodeZigZag64(final long n)1025   public static long encodeZigZag64(final long n) {
1026     // Note:  the right-shift must be arithmetic
1027     return (n << 1) ^ (n >> 63);
1028   }
1029 }
1030