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