• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2013 Google Inc.  All rights reserved.
3 // http://code.google.com/p/protobuf/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 package com.google.protobuf.nano;
32 
33 import java.io.IOException;
34 import java.io.UnsupportedEncodingException;
35 
36 /**
37  * Encodes and writes protocol message fields.
38  *
39  * <p>This class contains two kinds of methods:  methods that write specific
40  * protocol message constructs and field types (e.g. {@link #writeTag} and
41  * {@link #writeInt32}) and methods that write low-level values (e.g.
42  * {@link #writeRawVarint32} and {@link #writeRawBytes}).  If you are
43  * writing encoded protocol messages, you should use the former methods, but if
44  * you are writing some other format of your own design, use the latter.
45  *
46  * <p>This class is totally unsynchronized.
47  *
48  * @author kneton@google.com Kenton Varda
49  */
50 public final class CodedOutputByteBufferNano {
51   private final byte[] buffer;
52   private final int limit;
53   private int position;
54 
CodedOutputByteBufferNano(final byte[] buffer, final int offset, final int length)55   private CodedOutputByteBufferNano(final byte[] buffer, final int offset,
56                             final int length) {
57     this.buffer = buffer;
58     position = offset;
59     limit = offset + length;
60   }
61 
62   /**
63    * Create a new {@code CodedOutputStream} that writes directly to the given
64    * byte array.  If more bytes are written than fit in the array,
65    * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
66    * array is faster than writing to an {@code OutputStream}.
67    */
newInstance(final byte[] flatArray)68   public static CodedOutputByteBufferNano newInstance(final byte[] flatArray) {
69     return newInstance(flatArray, 0, flatArray.length);
70   }
71 
72   /**
73    * Create a new {@code CodedOutputStream} that writes directly to the given
74    * byte array slice.  If more bytes are written than fit in the slice,
75    * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
76    * array is faster than writing to an {@code OutputStream}.
77    */
newInstance(final byte[] flatArray, final int offset, final int length)78   public static CodedOutputByteBufferNano newInstance(final byte[] flatArray,
79                                               final int offset,
80                                               final int length) {
81     return new CodedOutputByteBufferNano(flatArray, offset, length);
82   }
83 
84   // -----------------------------------------------------------------
85 
86   /** Write a {@code double} field, including tag, to the stream. */
writeDouble(final int fieldNumber, final double value)87   public void writeDouble(final int fieldNumber, final double value)
88                           throws IOException {
89     writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
90     writeDoubleNoTag(value);
91   }
92 
93   /** Write a {@code float} field, including tag, to the stream. */
writeFloat(final int fieldNumber, final float value)94   public void writeFloat(final int fieldNumber, final float value)
95                          throws IOException {
96     writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
97     writeFloatNoTag(value);
98   }
99 
100   /** Write a {@code uint64} field, including tag, to the stream. */
writeUInt64(final int fieldNumber, final long value)101   public void writeUInt64(final int fieldNumber, final long value)
102                           throws IOException {
103     writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
104     writeUInt64NoTag(value);
105   }
106 
107   /** Write an {@code int64} field, including tag, to the stream. */
writeInt64(final int fieldNumber, final long value)108   public void writeInt64(final int fieldNumber, final long value)
109                          throws IOException {
110     writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
111     writeInt64NoTag(value);
112   }
113 
114   /** Write an {@code int32} field, including tag, to the stream. */
writeInt32(final int fieldNumber, final int value)115   public void writeInt32(final int fieldNumber, final int value)
116                          throws IOException {
117     writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
118     writeInt32NoTag(value);
119   }
120 
121   /** Write a {@code fixed64} field, including tag, to the stream. */
writeFixed64(final int fieldNumber, final long value)122   public void writeFixed64(final int fieldNumber, final long value)
123                            throws IOException {
124     writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
125     writeFixed64NoTag(value);
126   }
127 
128   /** Write a {@code fixed32} field, including tag, to the stream. */
writeFixed32(final int fieldNumber, final int value)129   public void writeFixed32(final int fieldNumber, final int value)
130                            throws IOException {
131     writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
132     writeFixed32NoTag(value);
133   }
134 
135   /** Write a {@code bool} field, including tag, to the stream. */
writeBool(final int fieldNumber, final boolean value)136   public void writeBool(final int fieldNumber, final boolean value)
137                         throws IOException {
138     writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
139     writeBoolNoTag(value);
140   }
141 
142   /** Write a {@code string} field, including tag, to the stream. */
writeString(final int fieldNumber, final String value)143   public void writeString(final int fieldNumber, final String value)
144                           throws IOException {
145     writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
146     writeStringNoTag(value);
147   }
148 
149   /** Write a {@code group} field, including tag, to the stream. */
writeGroup(final int fieldNumber, final MessageNano value)150   public void writeGroup(final int fieldNumber, final MessageNano value)
151                          throws IOException {
152     writeTag(fieldNumber, WireFormatNano.WIRETYPE_START_GROUP);
153     writeGroupNoTag(value);
154     writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP);
155   }
156 
157   /** Write an embedded message field, including tag, to the stream. */
writeMessage(final int fieldNumber, final MessageNano value)158   public void writeMessage(final int fieldNumber, final MessageNano value)
159                            throws IOException {
160     writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
161     writeMessageNoTag(value);
162   }
163 
164   /** Write a {@code bytes} field, including tag, to the stream. */
writeBytes(final int fieldNumber, final byte[] value)165   public void writeBytes(final int fieldNumber, final byte[] value)
166                          throws IOException {
167     writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
168     writeBytesNoTag(value);
169   }
170 
171   /** Write a {@code byte} field, including tag, to the stream. */
writeByteArray(final int fieldNumber, final byte[] value)172   public void writeByteArray(final int fieldNumber, final byte[] value)
173                          throws IOException {
174     writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
175     writeByteArrayNoTag(value);
176   }
177 
178 
179   /** Write a {@code uint32} field, including tag, to the stream. */
writeUInt32(final int fieldNumber, final int value)180   public void writeUInt32(final int fieldNumber, final int value)
181                           throws IOException {
182     writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
183     writeUInt32NoTag(value);
184   }
185 
186   /**
187    * Write an enum field, including tag, to the stream.  Caller is responsible
188    * for converting the enum value to its numeric value.
189    */
writeEnum(final int fieldNumber, final int value)190   public void writeEnum(final int fieldNumber, final int value)
191                         throws IOException {
192     writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
193     writeEnumNoTag(value);
194   }
195 
196   /** Write an {@code sfixed32} field, including tag, to the stream. */
writeSFixed32(final int fieldNumber, final int value)197   public void writeSFixed32(final int fieldNumber, final int value)
198                             throws IOException {
199     writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
200     writeSFixed32NoTag(value);
201   }
202 
203   /** Write an {@code sfixed64} field, including tag, to the stream. */
writeSFixed64(final int fieldNumber, final long value)204   public void writeSFixed64(final int fieldNumber, final long value)
205                             throws IOException {
206     writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
207     writeSFixed64NoTag(value);
208   }
209 
210   /** Write an {@code sint32} field, including tag, to the stream. */
writeSInt32(final int fieldNumber, final int value)211   public void writeSInt32(final int fieldNumber, final int value)
212                           throws IOException {
213     writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
214     writeSInt32NoTag(value);
215   }
216 
217   /** Write an {@code sint64} field, including tag, to the stream. */
writeSInt64(final int fieldNumber, final long value)218   public void writeSInt64(final int fieldNumber, final long value)
219                           throws IOException {
220     writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
221     writeSInt64NoTag(value);
222   }
223 
224   /**
225    * Write a MessageSet extension field to the stream.  For historical reasons,
226    * the wire format differs from normal fields.
227    */
228 //  public void writeMessageSetExtension(final int fieldNumber,
229 //                                       final MessageMicro value)
230 //                                       throws IOException {
231 //    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
232 //    writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
233 //    writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
234 //    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
235 //  }
236 
237   /**
238    * Write an unparsed MessageSet extension field to the stream.  For
239    * historical reasons, the wire format differs from normal fields.
240    */
241 //  public void writeRawMessageSetExtension(final int fieldNumber,
242 //                                          final ByteStringMicro value)
243 //                                          throws IOException {
244 //    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
245 //    writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
246 //    writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
247 //    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
248 //  }
249 
250   // -----------------------------------------------------------------
251 
252   /** Write a {@code double} field to the stream. */
writeDoubleNoTag(final double value)253   public void writeDoubleNoTag(final double value) throws IOException {
254     writeRawLittleEndian64(Double.doubleToLongBits(value));
255   }
256 
257   /** Write a {@code float} field to the stream. */
writeFloatNoTag(final float value)258   public void writeFloatNoTag(final float value) throws IOException {
259     writeRawLittleEndian32(Float.floatToIntBits(value));
260   }
261 
262   /** Write a {@code uint64} field to the stream. */
writeUInt64NoTag(final long value)263   public void writeUInt64NoTag(final long value) throws IOException {
264     writeRawVarint64(value);
265   }
266 
267   /** Write an {@code int64} field to the stream. */
writeInt64NoTag(final long value)268   public void writeInt64NoTag(final long value) throws IOException {
269     writeRawVarint64(value);
270   }
271 
272   /** Write an {@code int32} field to the stream. */
writeInt32NoTag(final int value)273   public void writeInt32NoTag(final int value) throws IOException {
274     if (value >= 0) {
275       writeRawVarint32(value);
276     } else {
277       // Must sign-extend.
278       writeRawVarint64(value);
279     }
280   }
281 
282   /** Write a {@code fixed64} field to the stream. */
writeFixed64NoTag(final long value)283   public void writeFixed64NoTag(final long value) throws IOException {
284     writeRawLittleEndian64(value);
285   }
286 
287   /** Write a {@code fixed32} field to the stream. */
writeFixed32NoTag(final int value)288   public void writeFixed32NoTag(final int value) throws IOException {
289     writeRawLittleEndian32(value);
290   }
291 
292   /** Write a {@code bool} field to the stream. */
writeBoolNoTag(final boolean value)293   public void writeBoolNoTag(final boolean value) throws IOException {
294     writeRawByte(value ? 1 : 0);
295   }
296 
297   /** Write a {@code string} field to the stream. */
writeStringNoTag(final String value)298   public void writeStringNoTag(final String value) throws IOException {
299     // Unfortunately there does not appear to be any way to tell Java to encode
300     // UTF-8 directly into our buffer, so we have to let it create its own byte
301     // array and then copy.
302     final byte[] bytes = value.getBytes("UTF-8");
303     writeRawVarint32(bytes.length);
304     writeRawBytes(bytes);
305   }
306 
307   /** Write a {@code group} field to the stream. */
writeGroupNoTag(final MessageNano value)308   public void writeGroupNoTag(final MessageNano value) throws IOException {
309     value.writeTo(this);
310   }
311 
312   /** Write an embedded message field to the stream. */
writeMessageNoTag(final MessageNano value)313   public void writeMessageNoTag(final MessageNano value) throws IOException {
314     writeRawVarint32(value.getCachedSize());
315     value.writeTo(this);
316   }
317 
318   /** Write a {@code bytes} field to the stream. */
writeBytesNoTag(final byte[] value)319   public void writeBytesNoTag(final byte[] value) throws IOException {
320     writeRawVarint32(value.length);
321     writeRawBytes(value);
322   }
323 
324   /** Write a {@code byte[]} field to the stream. */
writeByteArrayNoTag(final byte [] value)325   public void writeByteArrayNoTag(final byte [] value) throws IOException {
326     writeRawVarint32(value.length);
327     writeRawBytes(value);
328   }
329 
330   /** Write a {@code uint32} field to the stream. */
writeUInt32NoTag(final int value)331   public void writeUInt32NoTag(final int value) throws IOException {
332     writeRawVarint32(value);
333   }
334 
335   /**
336    * Write an enum field to the stream.  Caller is responsible
337    * for converting the enum value to its numeric value.
338    */
writeEnumNoTag(final int value)339   public void writeEnumNoTag(final int value) throws IOException {
340     writeRawVarint32(value);
341   }
342 
343   /** Write an {@code sfixed32} field to the stream. */
writeSFixed32NoTag(final int value)344   public void writeSFixed32NoTag(final int value) throws IOException {
345     writeRawLittleEndian32(value);
346   }
347 
348   /** Write an {@code sfixed64} field to the stream. */
writeSFixed64NoTag(final long value)349   public void writeSFixed64NoTag(final long value) throws IOException {
350     writeRawLittleEndian64(value);
351   }
352 
353   /** Write an {@code sint32} field to the stream. */
writeSInt32NoTag(final int value)354   public void writeSInt32NoTag(final int value) throws IOException {
355     writeRawVarint32(encodeZigZag32(value));
356   }
357 
358   /** Write an {@code sint64} field to the stream. */
writeSInt64NoTag(final long value)359   public void writeSInt64NoTag(final long value) throws IOException {
360     writeRawVarint64(encodeZigZag64(value));
361   }
362 
363   // =================================================================
364 
365   /**
366    * Compute the number of bytes that would be needed to encode a
367    * {@code double} field, including tag.
368    */
computeDoubleSize(final int fieldNumber, final double value)369   public static int computeDoubleSize(final int fieldNumber,
370                                       final double value) {
371     return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
372   }
373 
374   /**
375    * Compute the number of bytes that would be needed to encode a
376    * {@code float} field, including tag.
377    */
computeFloatSize(final int fieldNumber, final float value)378   public static int computeFloatSize(final int fieldNumber, final float value) {
379     return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
380   }
381 
382   /**
383    * Compute the number of bytes that would be needed to encode a
384    * {@code uint64} field, including tag.
385    */
computeUInt64Size(final int fieldNumber, final long value)386   public static int computeUInt64Size(final int fieldNumber, final long value) {
387     return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
388   }
389 
390   /**
391    * Compute the number of bytes that would be needed to encode an
392    * {@code int64} field, including tag.
393    */
computeInt64Size(final int fieldNumber, final long value)394   public static int computeInt64Size(final int fieldNumber, final long value) {
395     return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
396   }
397 
398   /**
399    * Compute the number of bytes that would be needed to encode an
400    * {@code int32} field, including tag.
401    */
computeInt32Size(final int fieldNumber, final int value)402   public static int computeInt32Size(final int fieldNumber, final int value) {
403     return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
404   }
405 
406   /**
407    * Compute the number of bytes that would be needed to encode a
408    * {@code fixed64} field, including tag.
409    */
computeFixed64Size(final int fieldNumber, final long value)410   public static int computeFixed64Size(final int fieldNumber,
411                                        final long value) {
412     return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
413   }
414 
415   /**
416    * Compute the number of bytes that would be needed to encode a
417    * {@code fixed32} field, including tag.
418    */
computeFixed32Size(final int fieldNumber, final int value)419   public static int computeFixed32Size(final int fieldNumber,
420                                        final int value) {
421     return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
422   }
423 
424   /**
425    * Compute the number of bytes that would be needed to encode a
426    * {@code bool} field, including tag.
427    */
computeBoolSize(final int fieldNumber, final boolean value)428   public static int computeBoolSize(final int fieldNumber,
429                                     final boolean value) {
430     return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
431   }
432 
433   /**
434    * Compute the number of bytes that would be needed to encode a
435    * {@code string} field, including tag.
436    */
computeStringSize(final int fieldNumber, final String value)437   public static int computeStringSize(final int fieldNumber,
438                                       final String value) {
439     return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
440   }
441 
442   /**
443    * Compute the number of bytes that would be needed to encode a
444    * {@code group} field, including tag.
445    */
computeGroupSize(final int fieldNumber, final MessageNano value)446   public static int computeGroupSize(final int fieldNumber,
447                                      final MessageNano value) {
448     return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
449   }
450 
451   /**
452    * Compute the number of bytes that would be needed to encode an
453    * embedded message field, including tag.
454    */
computeMessageSize(final int fieldNumber, final MessageNano value)455   public static int computeMessageSize(final int fieldNumber,
456                                        final MessageNano value) {
457     return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
458   }
459 
460   /**
461    * Compute the number of bytes that would be needed to encode a
462    * {@code bytes} field, including tag.
463    */
computeBytesSize(final int fieldNumber, final byte[] value)464   public static int computeBytesSize(final int fieldNumber,
465                                      final byte[] value) {
466     return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
467   }
468 
469   /**
470    * Compute the number of bytes that would be needed to encode a
471    * {@code byte[]} field, including tag.
472    */
computeByteArraySize(final int fieldNumber, final byte[] value)473   public static int computeByteArraySize(final int fieldNumber,
474                                      final byte[] value) {
475     return computeTagSize(fieldNumber) + computeByteArraySizeNoTag(value);
476   }
477 
478   /**
479    * Compute the number of bytes that would be needed to encode a
480    * {@code uint32} field, including tag.
481    */
computeUInt32Size(final int fieldNumber, final int value)482   public static int computeUInt32Size(final int fieldNumber, final int value) {
483     return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
484   }
485 
486   /**
487    * Compute the number of bytes that would be needed to encode an
488    * enum field, including tag.  Caller is responsible for converting the
489    * enum value to its numeric value.
490    */
computeEnumSize(final int fieldNumber, final int value)491   public static int computeEnumSize(final int fieldNumber, final int value) {
492     return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
493   }
494 
495   /**
496    * Compute the number of bytes that would be needed to encode an
497    * {@code sfixed32} field, including tag.
498    */
computeSFixed32Size(final int fieldNumber, final int value)499   public static int computeSFixed32Size(final int fieldNumber,
500                                         final int value) {
501     return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
502   }
503 
504   /**
505    * Compute the number of bytes that would be needed to encode an
506    * {@code sfixed64} field, including tag.
507    */
computeSFixed64Size(final int fieldNumber, final long value)508   public static int computeSFixed64Size(final int fieldNumber,
509                                         final long value) {
510     return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
511   }
512 
513   /**
514    * Compute the number of bytes that would be needed to encode an
515    * {@code sint32} field, including tag.
516    */
computeSInt32Size(final int fieldNumber, final int value)517   public static int computeSInt32Size(final int fieldNumber, final int value) {
518     return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
519   }
520 
521   /**
522    * Compute the number of bytes that would be needed to encode an
523    * {@code sint64} field, including tag.
524    */
computeSInt64Size(final int fieldNumber, final long value)525   public static int computeSInt64Size(final int fieldNumber, final long value) {
526     return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
527   }
528 
529   /**
530    * Compute the number of bytes that would be needed to encode a
531    * MessageSet extension to the stream.  For historical reasons,
532    * the wire format differs from normal fields.
533    */
534 //  public static int computeMessageSetExtensionSize(
535 //      final int fieldNumber, final MessageMicro value) {
536 //    return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
537 //           computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
538 //           computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
539 //  }
540 
541   /**
542    * Compute the number of bytes that would be needed to encode an
543    * unparsed MessageSet extension field to the stream.  For
544    * historical reasons, the wire format differs from normal fields.
545    */
546 //  public static int computeRawMessageSetExtensionSize(
547 //      final int fieldNumber, final ByteStringMicro value) {
548 //    return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
549 //           computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
550 //           computeBytesSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
551 //  }
552 
553   // -----------------------------------------------------------------
554 
555   /**
556    * Compute the number of bytes that would be needed to encode a
557    * {@code double} field, including tag.
558    */
computeDoubleSizeNoTag(final double value)559   public static int computeDoubleSizeNoTag(final double value) {
560     return LITTLE_ENDIAN_64_SIZE;
561   }
562 
563   /**
564    * Compute the number of bytes that would be needed to encode a
565    * {@code float} field, including tag.
566    */
computeFloatSizeNoTag(final float value)567   public static int computeFloatSizeNoTag(final float value) {
568     return LITTLE_ENDIAN_32_SIZE;
569   }
570 
571   /**
572    * Compute the number of bytes that would be needed to encode a
573    * {@code uint64} field, including tag.
574    */
computeUInt64SizeNoTag(final long value)575   public static int computeUInt64SizeNoTag(final long value) {
576     return computeRawVarint64Size(value);
577   }
578 
579   /**
580    * Compute the number of bytes that would be needed to encode an
581    * {@code int64} field, including tag.
582    */
computeInt64SizeNoTag(final long value)583   public static int computeInt64SizeNoTag(final long value) {
584     return computeRawVarint64Size(value);
585   }
586 
587   /**
588    * Compute the number of bytes that would be needed to encode an
589    * {@code int32} field, including tag.
590    */
computeInt32SizeNoTag(final int value)591   public static int computeInt32SizeNoTag(final int value) {
592     if (value >= 0) {
593       return computeRawVarint32Size(value);
594     } else {
595       // Must sign-extend.
596       return 10;
597     }
598   }
599 
600   /**
601    * Compute the number of bytes that would be needed to encode a
602    * {@code fixed64} field.
603    */
computeFixed64SizeNoTag(final long value)604   public static int computeFixed64SizeNoTag(final long value) {
605     return LITTLE_ENDIAN_64_SIZE;
606   }
607 
608   /**
609    * Compute the number of bytes that would be needed to encode a
610    * {@code fixed32} field.
611    */
computeFixed32SizeNoTag(final int value)612   public static int computeFixed32SizeNoTag(final int value) {
613     return LITTLE_ENDIAN_32_SIZE;
614   }
615 
616   /**
617    * Compute the number of bytes that would be needed to encode a
618    * {@code bool} field.
619    */
computeBoolSizeNoTag(final boolean value)620   public static int computeBoolSizeNoTag(final boolean value) {
621     return 1;
622   }
623 
624   /**
625    * Compute the number of bytes that would be needed to encode a
626    * {@code string} field.
627    */
computeStringSizeNoTag(final String value)628   public static int computeStringSizeNoTag(final String value) {
629     try {
630       final byte[] bytes = value.getBytes("UTF-8");
631       return computeRawVarint32Size(bytes.length) +
632              bytes.length;
633     } catch (UnsupportedEncodingException e) {
634       throw new RuntimeException("UTF-8 not supported.");
635     }
636   }
637 
638   /**
639    * Compute the number of bytes that would be needed to encode a
640    * {@code group} field.
641    */
computeGroupSizeNoTag(final MessageNano value)642   public static int computeGroupSizeNoTag(final MessageNano value) {
643     return value.getSerializedSize();
644   }
645 
646   /**
647    * Compute the number of bytes that would be needed to encode an embedded
648    * message field.
649    */
computeMessageSizeNoTag(final MessageNano value)650   public static int computeMessageSizeNoTag(final MessageNano value) {
651     final int size = value.getSerializedSize();
652     return computeRawVarint32Size(size) + size;
653   }
654 
655   /**
656    * Compute the number of bytes that would be needed to encode a
657    * {@code bytes} field.
658    */
computeBytesSizeNoTag(final byte[] value)659   public static int computeBytesSizeNoTag(final byte[] value) {
660     return computeRawVarint32Size(value.length) + value.length;
661   }
662 
663   /**
664    * Compute the number of bytes that would be needed to encode a
665    * {@code byte[]} field.
666    */
computeByteArraySizeNoTag(final byte[] value)667   public static int computeByteArraySizeNoTag(final byte[] value) {
668     return computeRawVarint32Size(value.length) + value.length;
669   }
670 
671   /**
672    * Compute the number of bytes that would be needed to encode a
673    * {@code uint32} field.
674    */
computeUInt32SizeNoTag(final int value)675   public static int computeUInt32SizeNoTag(final int value) {
676     return computeRawVarint32Size(value);
677   }
678 
679   /**
680    * Compute the number of bytes that would be needed to encode an enum field.
681    * Caller is responsible for converting the enum value to its numeric value.
682    */
computeEnumSizeNoTag(final int value)683   public static int computeEnumSizeNoTag(final int value) {
684     return computeRawVarint32Size(value);
685   }
686 
687   /**
688    * Compute the number of bytes that would be needed to encode an
689    * {@code sfixed32} field.
690    */
computeSFixed32SizeNoTag(final int value)691   public static int computeSFixed32SizeNoTag(final int value) {
692     return LITTLE_ENDIAN_32_SIZE;
693   }
694 
695   /**
696    * Compute the number of bytes that would be needed to encode an
697    * {@code sfixed64} field.
698    */
computeSFixed64SizeNoTag(final long value)699   public static int computeSFixed64SizeNoTag(final long value) {
700     return LITTLE_ENDIAN_64_SIZE;
701   }
702 
703   /**
704    * Compute the number of bytes that would be needed to encode an
705    * {@code sint32} field.
706    */
computeSInt32SizeNoTag(final int value)707   public static int computeSInt32SizeNoTag(final int value) {
708     return computeRawVarint32Size(encodeZigZag32(value));
709   }
710 
711   /**
712    * Compute the number of bytes that would be needed to encode an
713    * {@code sint64} field.
714    */
computeSInt64SizeNoTag(final long value)715   public static int computeSInt64SizeNoTag(final long value) {
716     return computeRawVarint64Size(encodeZigZag64(value));
717   }
718 
719   // =================================================================
720 
721   /**
722    * If writing to a flat array, return the space left in the array.
723    * Otherwise, throws {@code UnsupportedOperationException}.
724    */
spaceLeft()725   public int spaceLeft() {
726     return limit - position;
727   }
728 
729   /**
730    * Verifies that {@link #spaceLeft()} returns zero.  It's common to create
731    * a byte array that is exactly big enough to hold a message, then write to
732    * it with a {@code CodedOutputStream}.  Calling {@code checkNoSpaceLeft()}
733    * after writing verifies that the message was actually as big as expected,
734    * which can help catch bugs.
735    */
checkNoSpaceLeft()736   public void checkNoSpaceLeft() {
737     if (spaceLeft() != 0) {
738       throw new IllegalStateException(
739         "Did not write as much data as expected.");
740     }
741   }
742 
743   /**
744    * If you create a CodedOutputStream around a simple flat array, you must
745    * not attempt to write more bytes than the array has space.  Otherwise,
746    * this exception will be thrown.
747    */
748   public static class OutOfSpaceException extends IOException {
749     private static final long serialVersionUID = -6947486886997889499L;
750 
OutOfSpaceException(int position, int limit)751     OutOfSpaceException(int position, int limit) {
752       super("CodedOutputStream was writing to a flat byte array and ran " +
753             "out of space (pos " + position + " limit " + limit + ").");
754     }
755   }
756 
757   /** Write a single byte. */
writeRawByte(final byte value)758   public void writeRawByte(final byte value) throws IOException {
759     if (position == limit) {
760       // We're writing to a single buffer.
761       throw new OutOfSpaceException(position, limit);
762     }
763 
764     buffer[position++] = value;
765   }
766 
767   /** Write a single byte, represented by an integer value. */
writeRawByte(final int value)768   public void writeRawByte(final int value) throws IOException {
769     writeRawByte((byte) value);
770   }
771 
772   /** Write an array of bytes. */
writeRawBytes(final byte[] value)773   public void writeRawBytes(final byte[] value) throws IOException {
774     writeRawBytes(value, 0, value.length);
775   }
776 
777   /** Write part of an array of bytes. */
writeRawBytes(final byte[] value, int offset, int length)778   public void writeRawBytes(final byte[] value, int offset, int length)
779                             throws IOException {
780     if (limit - position >= length) {
781       // We have room in the current buffer.
782       System.arraycopy(value, offset, buffer, position, length);
783       position += length;
784     } else {
785       // We're writing to a single buffer.
786       throw new OutOfSpaceException(position, limit);
787     }
788   }
789 
790   /** Encode and write a tag. */
writeTag(final int fieldNumber, final int wireType)791   public void writeTag(final int fieldNumber, final int wireType)
792                        throws IOException {
793     writeRawVarint32(WireFormatNano.makeTag(fieldNumber, wireType));
794   }
795 
796   /** Compute the number of bytes that would be needed to encode a tag. */
computeTagSize(final int fieldNumber)797   public static int computeTagSize(final int fieldNumber) {
798     return computeRawVarint32Size(WireFormatNano.makeTag(fieldNumber, 0));
799   }
800 
801   /**
802    * Encode and write a varint.  {@code value} is treated as
803    * unsigned, so it won't be sign-extended if negative.
804    */
writeRawVarint32(int value)805   public void writeRawVarint32(int value) throws IOException {
806     while (true) {
807       if ((value & ~0x7F) == 0) {
808         writeRawByte(value);
809         return;
810       } else {
811         writeRawByte((value & 0x7F) | 0x80);
812         value >>>= 7;
813       }
814     }
815   }
816 
817   /**
818    * Compute the number of bytes that would be needed to encode a varint.
819    * {@code value} is treated as unsigned, so it won't be sign-extended if
820    * negative.
821    */
computeRawVarint32Size(final int value)822   public static int computeRawVarint32Size(final int value) {
823     if ((value & (0xffffffff <<  7)) == 0) return 1;
824     if ((value & (0xffffffff << 14)) == 0) return 2;
825     if ((value & (0xffffffff << 21)) == 0) return 3;
826     if ((value & (0xffffffff << 28)) == 0) return 4;
827     return 5;
828   }
829 
830   /** Encode and write a varint. */
writeRawVarint64(long value)831   public void writeRawVarint64(long value) throws IOException {
832     while (true) {
833       if ((value & ~0x7FL) == 0) {
834         writeRawByte((int)value);
835         return;
836       } else {
837         writeRawByte(((int)value & 0x7F) | 0x80);
838         value >>>= 7;
839       }
840     }
841   }
842 
843   /** Compute the number of bytes that would be needed to encode a varint. */
computeRawVarint64Size(final long value)844   public static int computeRawVarint64Size(final long value) {
845     if ((value & (0xffffffffffffffffL <<  7)) == 0) return 1;
846     if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
847     if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
848     if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
849     if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
850     if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
851     if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
852     if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
853     if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
854     return 10;
855   }
856 
857   /** Write a little-endian 32-bit integer. */
writeRawLittleEndian32(final int value)858   public void writeRawLittleEndian32(final int value) throws IOException {
859     writeRawByte((value      ) & 0xFF);
860     writeRawByte((value >>  8) & 0xFF);
861     writeRawByte((value >> 16) & 0xFF);
862     writeRawByte((value >> 24) & 0xFF);
863   }
864 
865   public static final int LITTLE_ENDIAN_32_SIZE = 4;
866 
867   /** Write a little-endian 64-bit integer. */
writeRawLittleEndian64(final long value)868   public void writeRawLittleEndian64(final long value) throws IOException {
869     writeRawByte((int)(value      ) & 0xFF);
870     writeRawByte((int)(value >>  8) & 0xFF);
871     writeRawByte((int)(value >> 16) & 0xFF);
872     writeRawByte((int)(value >> 24) & 0xFF);
873     writeRawByte((int)(value >> 32) & 0xFF);
874     writeRawByte((int)(value >> 40) & 0xFF);
875     writeRawByte((int)(value >> 48) & 0xFF);
876     writeRawByte((int)(value >> 56) & 0xFF);
877   }
878 
879   public static final int LITTLE_ENDIAN_64_SIZE = 8;
880 
881   /**
882    * Encode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
883    * into values that can be efficiently encoded with varint.  (Otherwise,
884    * negative values must be sign-extended to 64 bits to be varint encoded,
885    * thus always taking 10 bytes on the wire.)
886    *
887    * @param n A signed 32-bit integer.
888    * @return An unsigned 32-bit integer, stored in a signed int because
889    *         Java has no explicit unsigned support.
890    */
encodeZigZag32(final int n)891   public static int encodeZigZag32(final int n) {
892     // Note:  the right-shift must be arithmetic
893     return (n << 1) ^ (n >> 31);
894   }
895 
896   /**
897    * Encode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
898    * into values that can be efficiently encoded with varint.  (Otherwise,
899    * negative values must be sign-extended to 64 bits to be varint encoded,
900    * thus always taking 10 bytes on the wire.)
901    *
902    * @param n A signed 64-bit integer.
903    * @return An unsigned 64-bit integer, stored in a signed int because
904    *         Java has no explicit unsigned support.
905    */
encodeZigZag64(final long n)906   public static long encodeZigZag64(final long n) {
907     // Note:  the right-shift must be arithmetic
908     return (n << 1) ^ (n >> 63);
909   }
910 }
911