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
31package com.google.protobuf.nano;
32
33import java.io.IOException;
34import 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 */
50public final class CodedOutputByteBufferNano {
51  private final byte[] buffer;
52  private final int limit;
53  private int position;
54
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   */
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   */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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 uint32} field, including tag, to the stream. */
172  public void writeUInt32(final int fieldNumber, final int value)
173                          throws IOException {
174    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
175    writeUInt32NoTag(value);
176  }
177
178  /**
179   * Write an enum field, including tag, to the stream.  Caller is responsible
180   * for converting the enum value to its numeric value.
181   */
182  public void writeEnum(final int fieldNumber, final int value)
183                        throws IOException {
184    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
185    writeEnumNoTag(value);
186  }
187
188  /** Write an {@code sfixed32} field, including tag, to the stream. */
189  public void writeSFixed32(final int fieldNumber, final int value)
190                            throws IOException {
191    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
192    writeSFixed32NoTag(value);
193  }
194
195  /** Write an {@code sfixed64} field, including tag, to the stream. */
196  public void writeSFixed64(final int fieldNumber, final long value)
197                            throws IOException {
198    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
199    writeSFixed64NoTag(value);
200  }
201
202  /** Write an {@code sint32} field, including tag, to the stream. */
203  public void writeSInt32(final int fieldNumber, final int value)
204                          throws IOException {
205    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
206    writeSInt32NoTag(value);
207  }
208
209  /** Write an {@code sint64} field, including tag, to the stream. */
210  public void writeSInt64(final int fieldNumber, final long value)
211                          throws IOException {
212    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
213    writeSInt64NoTag(value);
214  }
215
216  /**
217   * Write a MessageSet extension field to the stream.  For historical reasons,
218   * the wire format differs from normal fields.
219   */
220//  public void writeMessageSetExtension(final int fieldNumber,
221//                                       final MessageMicro value)
222//                                       throws IOException {
223//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
224//    writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
225//    writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
226//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
227//  }
228
229  /**
230   * Write an unparsed MessageSet extension field to the stream.  For
231   * historical reasons, the wire format differs from normal fields.
232   */
233//  public void writeRawMessageSetExtension(final int fieldNumber,
234//                                          final ByteStringMicro value)
235//                                          throws IOException {
236//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
237//    writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
238//    writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
239//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
240//  }
241
242  // -----------------------------------------------------------------
243
244  /** Write a {@code double} field to the stream. */
245  public void writeDoubleNoTag(final double value) throws IOException {
246    writeRawLittleEndian64(Double.doubleToLongBits(value));
247  }
248
249  /** Write a {@code float} field to the stream. */
250  public void writeFloatNoTag(final float value) throws IOException {
251    writeRawLittleEndian32(Float.floatToIntBits(value));
252  }
253
254  /** Write a {@code uint64} field to the stream. */
255  public void writeUInt64NoTag(final long value) throws IOException {
256    writeRawVarint64(value);
257  }
258
259  /** Write an {@code int64} field to the stream. */
260  public void writeInt64NoTag(final long value) throws IOException {
261    writeRawVarint64(value);
262  }
263
264  /** Write an {@code int32} field to the stream. */
265  public void writeInt32NoTag(final int value) throws IOException {
266    if (value >= 0) {
267      writeRawVarint32(value);
268    } else {
269      // Must sign-extend.
270      writeRawVarint64(value);
271    }
272  }
273
274  /** Write a {@code fixed64} field to the stream. */
275  public void writeFixed64NoTag(final long value) throws IOException {
276    writeRawLittleEndian64(value);
277  }
278
279  /** Write a {@code fixed32} field to the stream. */
280  public void writeFixed32NoTag(final int value) throws IOException {
281    writeRawLittleEndian32(value);
282  }
283
284  /** Write a {@code bool} field to the stream. */
285  public void writeBoolNoTag(final boolean value) throws IOException {
286    writeRawByte(value ? 1 : 0);
287  }
288
289  /** Write a {@code string} field to the stream. */
290  public void writeStringNoTag(final String value) throws IOException {
291    // Unfortunately there does not appear to be any way to tell Java to encode
292    // UTF-8 directly into our buffer, so we have to let it create its own byte
293    // array and then copy.
294    final byte[] bytes = value.getBytes("UTF-8");
295    writeRawVarint32(bytes.length);
296    writeRawBytes(bytes);
297  }
298
299  /** Write a {@code group} field to the stream. */
300  public void writeGroupNoTag(final MessageNano value) throws IOException {
301    value.writeTo(this);
302  }
303
304  /** Write an embedded message field to the stream. */
305  public void writeMessageNoTag(final MessageNano value) throws IOException {
306    writeRawVarint32(value.getCachedSize());
307    value.writeTo(this);
308  }
309
310  /** Write a {@code bytes} field to the stream. */
311  public void writeBytesNoTag(final byte[] value) throws IOException {
312    writeRawVarint32(value.length);
313    writeRawBytes(value);
314  }
315
316  /** Write a {@code uint32} field to the stream. */
317  public void writeUInt32NoTag(final int value) throws IOException {
318    writeRawVarint32(value);
319  }
320
321  /**
322   * Write an enum field to the stream.  Caller is responsible
323   * for converting the enum value to its numeric value.
324   */
325  public void writeEnumNoTag(final int value) throws IOException {
326    writeRawVarint32(value);
327  }
328
329  /** Write an {@code sfixed32} field to the stream. */
330  public void writeSFixed32NoTag(final int value) throws IOException {
331    writeRawLittleEndian32(value);
332  }
333
334  /** Write an {@code sfixed64} field to the stream. */
335  public void writeSFixed64NoTag(final long value) throws IOException {
336    writeRawLittleEndian64(value);
337  }
338
339  /** Write an {@code sint32} field to the stream. */
340  public void writeSInt32NoTag(final int value) throws IOException {
341    writeRawVarint32(encodeZigZag32(value));
342  }
343
344  /** Write an {@code sint64} field to the stream. */
345  public void writeSInt64NoTag(final long value) throws IOException {
346    writeRawVarint64(encodeZigZag64(value));
347  }
348
349  // =================================================================
350
351  /**
352   * Compute the number of bytes that would be needed to encode a
353   * {@code double} field, including tag.
354   */
355  public static int computeDoubleSize(final int fieldNumber,
356                                      final double value) {
357    return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
358  }
359
360  /**
361   * Compute the number of bytes that would be needed to encode a
362   * {@code float} field, including tag.
363   */
364  public static int computeFloatSize(final int fieldNumber, final float value) {
365    return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
366  }
367
368  /**
369   * Compute the number of bytes that would be needed to encode a
370   * {@code uint64} field, including tag.
371   */
372  public static int computeUInt64Size(final int fieldNumber, final long value) {
373    return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
374  }
375
376  /**
377   * Compute the number of bytes that would be needed to encode an
378   * {@code int64} field, including tag.
379   */
380  public static int computeInt64Size(final int fieldNumber, final long value) {
381    return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
382  }
383
384  /**
385   * Compute the number of bytes that would be needed to encode an
386   * {@code int32} field, including tag.
387   */
388  public static int computeInt32Size(final int fieldNumber, final int value) {
389    return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
390  }
391
392  /**
393   * Compute the number of bytes that would be needed to encode a
394   * {@code fixed64} field, including tag.
395   */
396  public static int computeFixed64Size(final int fieldNumber,
397                                       final long value) {
398    return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
399  }
400
401  /**
402   * Compute the number of bytes that would be needed to encode a
403   * {@code fixed32} field, including tag.
404   */
405  public static int computeFixed32Size(final int fieldNumber,
406                                       final int value) {
407    return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
408  }
409
410  /**
411   * Compute the number of bytes that would be needed to encode a
412   * {@code bool} field, including tag.
413   */
414  public static int computeBoolSize(final int fieldNumber,
415                                    final boolean value) {
416    return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
417  }
418
419  /**
420   * Compute the number of bytes that would be needed to encode a
421   * {@code string} field, including tag.
422   */
423  public static int computeStringSize(final int fieldNumber,
424                                      final String value) {
425    return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
426  }
427
428  /**
429   * Compute the number of bytes that would be needed to encode a
430   * {@code group} field, including tag.
431   */
432  public static int computeGroupSize(final int fieldNumber,
433                                     final MessageNano value) {
434    return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
435  }
436
437  /**
438   * Compute the number of bytes that would be needed to encode an
439   * embedded message field, including tag.
440   */
441  public static int computeMessageSize(final int fieldNumber,
442                                       final MessageNano value) {
443    return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
444  }
445
446  /**
447   * Compute the number of bytes that would be needed to encode a
448   * {@code bytes} field, including tag.
449   */
450  public static int computeBytesSize(final int fieldNumber,
451                                     final byte[] value) {
452    return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
453  }
454
455  /**
456   * Compute the number of bytes that would be needed to encode a
457   * {@code uint32} field, including tag.
458   */
459  public static int computeUInt32Size(final int fieldNumber, final int value) {
460    return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
461  }
462
463  /**
464   * Compute the number of bytes that would be needed to encode an
465   * enum field, including tag.  Caller is responsible for converting the
466   * enum value to its numeric value.
467   */
468  public static int computeEnumSize(final int fieldNumber, final int value) {
469    return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
470  }
471
472  /**
473   * Compute the number of bytes that would be needed to encode an
474   * {@code sfixed32} field, including tag.
475   */
476  public static int computeSFixed32Size(final int fieldNumber,
477                                        final int value) {
478    return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
479  }
480
481  /**
482   * Compute the number of bytes that would be needed to encode an
483   * {@code sfixed64} field, including tag.
484   */
485  public static int computeSFixed64Size(final int fieldNumber,
486                                        final long value) {
487    return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
488  }
489
490  /**
491   * Compute the number of bytes that would be needed to encode an
492   * {@code sint32} field, including tag.
493   */
494  public static int computeSInt32Size(final int fieldNumber, final int value) {
495    return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
496  }
497
498  /**
499   * Compute the number of bytes that would be needed to encode an
500   * {@code sint64} field, including tag.
501   */
502  public static int computeSInt64Size(final int fieldNumber, final long value) {
503    return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
504  }
505
506  /**
507   * Compute the number of bytes that would be needed to encode a
508   * MessageSet extension to the stream.  For historical reasons,
509   * the wire format differs from normal fields.
510   */
511//  public static int computeMessageSetExtensionSize(
512//      final int fieldNumber, final MessageMicro value) {
513//    return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
514//           computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
515//           computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
516//  }
517
518  /**
519   * Compute the number of bytes that would be needed to encode an
520   * unparsed MessageSet extension field to the stream.  For
521   * historical reasons, the wire format differs from normal fields.
522   */
523//  public static int computeRawMessageSetExtensionSize(
524//      final int fieldNumber, final ByteStringMicro value) {
525//    return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
526//           computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
527//           computeBytesSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
528//  }
529
530  // -----------------------------------------------------------------
531
532  /**
533   * Compute the number of bytes that would be needed to encode a
534   * {@code double} field, including tag.
535   */
536  public static int computeDoubleSizeNoTag(final double value) {
537    return LITTLE_ENDIAN_64_SIZE;
538  }
539
540  /**
541   * Compute the number of bytes that would be needed to encode a
542   * {@code float} field, including tag.
543   */
544  public static int computeFloatSizeNoTag(final float value) {
545    return LITTLE_ENDIAN_32_SIZE;
546  }
547
548  /**
549   * Compute the number of bytes that would be needed to encode a
550   * {@code uint64} field, including tag.
551   */
552  public static int computeUInt64SizeNoTag(final long value) {
553    return computeRawVarint64Size(value);
554  }
555
556  /**
557   * Compute the number of bytes that would be needed to encode an
558   * {@code int64} field, including tag.
559   */
560  public static int computeInt64SizeNoTag(final long value) {
561    return computeRawVarint64Size(value);
562  }
563
564  /**
565   * Compute the number of bytes that would be needed to encode an
566   * {@code int32} field, including tag.
567   */
568  public static int computeInt32SizeNoTag(final int value) {
569    if (value >= 0) {
570      return computeRawVarint32Size(value);
571    } else {
572      // Must sign-extend.
573      return 10;
574    }
575  }
576
577  /**
578   * Compute the number of bytes that would be needed to encode a
579   * {@code fixed64} field.
580   */
581  public static int computeFixed64SizeNoTag(final long value) {
582    return LITTLE_ENDIAN_64_SIZE;
583  }
584
585  /**
586   * Compute the number of bytes that would be needed to encode a
587   * {@code fixed32} field.
588   */
589  public static int computeFixed32SizeNoTag(final int value) {
590    return LITTLE_ENDIAN_32_SIZE;
591  }
592
593  /**
594   * Compute the number of bytes that would be needed to encode a
595   * {@code bool} field.
596   */
597  public static int computeBoolSizeNoTag(final boolean value) {
598    return 1;
599  }
600
601  /**
602   * Compute the number of bytes that would be needed to encode a
603   * {@code string} field.
604   */
605  public static int computeStringSizeNoTag(final String value) {
606    try {
607      final byte[] bytes = value.getBytes("UTF-8");
608      return computeRawVarint32Size(bytes.length) +
609             bytes.length;
610    } catch (UnsupportedEncodingException e) {
611      throw new RuntimeException("UTF-8 not supported.");
612    }
613  }
614
615  /**
616   * Compute the number of bytes that would be needed to encode a
617   * {@code group} field.
618   */
619  public static int computeGroupSizeNoTag(final MessageNano value) {
620    return value.getSerializedSize();
621  }
622
623  /**
624   * Compute the number of bytes that would be needed to encode an embedded
625   * message field.
626   */
627  public static int computeMessageSizeNoTag(final MessageNano value) {
628    final int size = value.getSerializedSize();
629    return computeRawVarint32Size(size) + size;
630  }
631
632  /**
633   * Compute the number of bytes that would be needed to encode a
634   * {@code bytes} field.
635   */
636  public static int computeBytesSizeNoTag(final byte[] value) {
637    return computeRawVarint32Size(value.length) + value.length;
638  }
639
640  /**
641   * Compute the number of bytes that would be needed to encode a
642   * {@code uint32} field.
643   */
644  public static int computeUInt32SizeNoTag(final int value) {
645    return computeRawVarint32Size(value);
646  }
647
648  /**
649   * Compute the number of bytes that would be needed to encode an enum field.
650   * Caller is responsible for converting the enum value to its numeric value.
651   */
652  public static int computeEnumSizeNoTag(final int value) {
653    return computeRawVarint32Size(value);
654  }
655
656  /**
657   * Compute the number of bytes that would be needed to encode an
658   * {@code sfixed32} field.
659   */
660  public static int computeSFixed32SizeNoTag(final int value) {
661    return LITTLE_ENDIAN_32_SIZE;
662  }
663
664  /**
665   * Compute the number of bytes that would be needed to encode an
666   * {@code sfixed64} field.
667   */
668  public static int computeSFixed64SizeNoTag(final long value) {
669    return LITTLE_ENDIAN_64_SIZE;
670  }
671
672  /**
673   * Compute the number of bytes that would be needed to encode an
674   * {@code sint32} field.
675   */
676  public static int computeSInt32SizeNoTag(final int value) {
677    return computeRawVarint32Size(encodeZigZag32(value));
678  }
679
680  /**
681   * Compute the number of bytes that would be needed to encode an
682   * {@code sint64} field.
683   */
684  public static int computeSInt64SizeNoTag(final long value) {
685    return computeRawVarint64Size(encodeZigZag64(value));
686  }
687
688  // =================================================================
689
690  /**
691   * If writing to a flat array, return the space left in the array.
692   * Otherwise, throws {@code UnsupportedOperationException}.
693   */
694  public int spaceLeft() {
695    return limit - position;
696  }
697
698  /**
699   * Verifies that {@link #spaceLeft()} returns zero.  It's common to create
700   * a byte array that is exactly big enough to hold a message, then write to
701   * it with a {@code CodedOutputStream}.  Calling {@code checkNoSpaceLeft()}
702   * after writing verifies that the message was actually as big as expected,
703   * which can help catch bugs.
704   */
705  public void checkNoSpaceLeft() {
706    if (spaceLeft() != 0) {
707      throw new IllegalStateException(
708        "Did not write as much data as expected.");
709    }
710  }
711
712  /**
713   * If you create a CodedOutputStream around a simple flat array, you must
714   * not attempt to write more bytes than the array has space.  Otherwise,
715   * this exception will be thrown.
716   */
717  public static class OutOfSpaceException extends IOException {
718    private static final long serialVersionUID = -6947486886997889499L;
719
720    OutOfSpaceException(int position, int limit) {
721      super("CodedOutputStream was writing to a flat byte array and ran " +
722            "out of space (pos " + position + " limit " + limit + ").");
723    }
724  }
725
726  /** Write a single byte. */
727  public void writeRawByte(final byte value) throws IOException {
728    if (position == limit) {
729      // We're writing to a single buffer.
730      throw new OutOfSpaceException(position, limit);
731    }
732
733    buffer[position++] = value;
734  }
735
736  /** Write a single byte, represented by an integer value. */
737  public void writeRawByte(final int value) throws IOException {
738    writeRawByte((byte) value);
739  }
740
741  /** Write an array of bytes. */
742  public void writeRawBytes(final byte[] value) throws IOException {
743    writeRawBytes(value, 0, value.length);
744  }
745
746  /** Write part of an array of bytes. */
747  public void writeRawBytes(final byte[] value, int offset, int length)
748                            throws IOException {
749    if (limit - position >= length) {
750      // We have room in the current buffer.
751      System.arraycopy(value, offset, buffer, position, length);
752      position += length;
753    } else {
754      // We're writing to a single buffer.
755      throw new OutOfSpaceException(position, limit);
756    }
757  }
758
759  /** Encode and write a tag. */
760  public void writeTag(final int fieldNumber, final int wireType)
761                       throws IOException {
762    writeRawVarint32(WireFormatNano.makeTag(fieldNumber, wireType));
763  }
764
765  /** Compute the number of bytes that would be needed to encode a tag. */
766  public static int computeTagSize(final int fieldNumber) {
767    return computeRawVarint32Size(WireFormatNano.makeTag(fieldNumber, 0));
768  }
769
770  /**
771   * Encode and write a varint.  {@code value} is treated as
772   * unsigned, so it won't be sign-extended if negative.
773   */
774  public void writeRawVarint32(int value) throws IOException {
775    while (true) {
776      if ((value & ~0x7F) == 0) {
777        writeRawByte(value);
778        return;
779      } else {
780        writeRawByte((value & 0x7F) | 0x80);
781        value >>>= 7;
782      }
783    }
784  }
785
786  /**
787   * Compute the number of bytes that would be needed to encode a varint.
788   * {@code value} is treated as unsigned, so it won't be sign-extended if
789   * negative.
790   */
791  public static int computeRawVarint32Size(final int value) {
792    if ((value & (0xffffffff <<  7)) == 0) return 1;
793    if ((value & (0xffffffff << 14)) == 0) return 2;
794    if ((value & (0xffffffff << 21)) == 0) return 3;
795    if ((value & (0xffffffff << 28)) == 0) return 4;
796    return 5;
797  }
798
799  /** Encode and write a varint. */
800  public void writeRawVarint64(long value) throws IOException {
801    while (true) {
802      if ((value & ~0x7FL) == 0) {
803        writeRawByte((int)value);
804        return;
805      } else {
806        writeRawByte(((int)value & 0x7F) | 0x80);
807        value >>>= 7;
808      }
809    }
810  }
811
812  /** Compute the number of bytes that would be needed to encode a varint. */
813  public static int computeRawVarint64Size(final long value) {
814    if ((value & (0xffffffffffffffffL <<  7)) == 0) return 1;
815    if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
816    if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
817    if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
818    if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
819    if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
820    if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
821    if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
822    if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
823    return 10;
824  }
825
826  /** Write a little-endian 32-bit integer. */
827  public void writeRawLittleEndian32(final int value) throws IOException {
828    writeRawByte((value      ) & 0xFF);
829    writeRawByte((value >>  8) & 0xFF);
830    writeRawByte((value >> 16) & 0xFF);
831    writeRawByte((value >> 24) & 0xFF);
832  }
833
834  public static final int LITTLE_ENDIAN_32_SIZE = 4;
835
836  /** Write a little-endian 64-bit integer. */
837  public void writeRawLittleEndian64(final long value) throws IOException {
838    writeRawByte((int)(value      ) & 0xFF);
839    writeRawByte((int)(value >>  8) & 0xFF);
840    writeRawByte((int)(value >> 16) & 0xFF);
841    writeRawByte((int)(value >> 24) & 0xFF);
842    writeRawByte((int)(value >> 32) & 0xFF);
843    writeRawByte((int)(value >> 40) & 0xFF);
844    writeRawByte((int)(value >> 48) & 0xFF);
845    writeRawByte((int)(value >> 56) & 0xFF);
846  }
847
848  public static final int LITTLE_ENDIAN_64_SIZE = 8;
849
850  /**
851   * Encode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
852   * into values that can be efficiently encoded with varint.  (Otherwise,
853   * negative values must be sign-extended to 64 bits to be varint encoded,
854   * thus always taking 10 bytes on the wire.)
855   *
856   * @param n A signed 32-bit integer.
857   * @return An unsigned 32-bit integer, stored in a signed int because
858   *         Java has no explicit unsigned support.
859   */
860  public static int encodeZigZag32(final int n) {
861    // Note:  the right-shift must be arithmetic
862    return (n << 1) ^ (n >> 31);
863  }
864
865  /**
866   * Encode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
867   * into values that can be efficiently encoded with varint.  (Otherwise,
868   * negative values must be sign-extended to 64 bits to be varint encoded,
869   * thus always taking 10 bytes on the wire.)
870   *
871   * @param n A signed 64-bit integer.
872   * @return An unsigned 64-bit integer, stored in a signed int because
873   *         Java has no explicit unsigned support.
874   */
875  public static long encodeZigZag64(final long n) {
876    // Note:  the right-shift must be arithmetic
877    return (n << 1) ^ (n >> 63);
878  }
879}
880