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