CodedOutputStreamMicro.java revision ede38fe9b9f93888e6e41afc7abb09525f44da95
1cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// Protocol Buffers - Google's data interchange format 2cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// Copyright 2008 Google Inc. All rights reserved. 3cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// http://code.google.com/p/protobuf/ 4cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// 5cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// Redistribution and use in source and binary forms, with or without 6cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// modification, are permitted provided that the following conditions are 7cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// met: 8cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// 9cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com// * Redistributions of source code must retain the above copyright 108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// notice, this list of conditions and the following disclaimer. 118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// * Redistributions in binary form must reproduce the above 128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// copyright notice, this list of conditions and the following disclaimer 138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// in the documentation and/or other materials provided with the 148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// distribution. 158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// * Neither the name of Google Inc. nor the names of its 168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// contributors may be used to endorse or promote products derived from 178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// this software without specific prior written permission. 188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// 198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.compackage com.google.protobuf.micro; 328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comimport java.io.OutputStream; 348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comimport java.io.IOException; 358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comimport java.io.UnsupportedEncodingException; 368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com/** 388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Encodes and writes protocol message fields. 398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * 408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * <p>This class contains two kinds of methods: methods that write specific 418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * protocol message constructs and field types (e.g. {@link #writeTag} and 428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@link #writeInt32}) and methods that write low-level values (e.g. 438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are 448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * writing encoded protocol messages, you should use the former methods, but if 458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * you are writing some other format of your own design, use the latter. 468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * 478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * <p>This class is totally unsynchronized. 488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * 498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * @author kneton@google.com Kenton Varda 508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.compublic final class CodedOutputStreamMicro { 528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com private final byte[] buffer; 538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com private final int limit; 548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com private int position; 558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com private final OutputStream output; 578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * The buffer size used in {@link #newInstance(OutputStream)}. 608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static final int DEFAULT_BUFFER_SIZE = 4096; 628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com private CodedOutputStreamMicro(final byte[] buffer, final int offset, 648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final int length) { 658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com output = null; 668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com this.buffer = buffer; 678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com position = offset; 688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com limit = offset + length; 698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com private CodedOutputStreamMicro(final OutputStream output, final byte[] buffer) { 728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com this.output = output; 738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com this.buffer = buffer; 748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com position = 0; 758cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com limit = buffer.length; 768cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 778cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 788cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 798cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Create a new {@code CodedOutputStream} wrapping the given 808cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code OutputStream}. 818cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 828cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static CodedOutputStreamMicro newInstance(final OutputStream output) { 838cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return newInstance(output, DEFAULT_BUFFER_SIZE); 848cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 858cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 868cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 878cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Create a new {@code CodedOutputStream} wrapping the given 888cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code OutputStream} with a given buffer size. 898cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 908cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static CodedOutputStreamMicro newInstance(final OutputStream output, 918cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final int bufferSize) { 928cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return new CodedOutputStreamMicro(output, new byte[bufferSize]); 938cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 948cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 958cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 968cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Create a new {@code CodedOutputStream} that writes directly to the given 978cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * byte array. If more bytes are written than fit in the array, 988cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@link OutOfSpaceException} will be thrown. Writing directly to a flat 998cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * array is faster than writing to an {@code OutputStream}. 1008cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 1018cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static CodedOutputStreamMicro newInstance(final byte[] flatArray) { 1028cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return newInstance(flatArray, 0, flatArray.length); 1038cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1048cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1058cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 1068cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Create a new {@code CodedOutputStream} that writes directly to the given 1078cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * byte array slice. If more bytes are written than fit in the slice, 1088cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@link OutOfSpaceException} will be thrown. Writing directly to a flat 1098cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * array is faster than writing to an {@code OutputStream}. 1108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 1118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static CodedOutputStreamMicro newInstance(final byte[] flatArray, 1128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final int offset, 1138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final int length) { 1148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return new CodedOutputStreamMicro(flatArray, offset, length); 1158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com // ----------------------------------------------------------------- 1188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code double} field, including tag, to the stream. */ 1208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeDouble(final int fieldNumber, final double value) 1218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64); 1238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeDoubleNoTag(value); 1248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code float} field, including tag, to the stream. */ 1278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeFloat(final int fieldNumber, final float value) 1288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32); 1308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeFloatNoTag(value); 1318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code uint64} field, including tag, to the stream. */ 1348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeUInt64(final int fieldNumber, final long value) 1358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); 1378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeUInt64NoTag(value); 1388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code int64} field, including tag, to the stream. */ 1418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeInt64(final int fieldNumber, final long value) 1428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); 1448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeInt64NoTag(value); 1458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code int32} field, including tag, to the stream. */ 1488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeInt32(final int fieldNumber, final int value) 1498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); 1518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeInt32NoTag(value); 1528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code fixed64} field, including tag, to the stream. */ 1558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeFixed64(final int fieldNumber, final long value) 1568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64); 1588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeFixed64NoTag(value); 1598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code fixed32} field, including tag, to the stream. */ 1628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeFixed32(final int fieldNumber, final int value) 1638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32); 1658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeFixed32NoTag(value); 1668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code bool} field, including tag, to the stream. */ 1698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeBool(final int fieldNumber, final boolean value) 1708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); 1728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeBoolNoTag(value); 1738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1758cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code string} field, including tag, to the stream. */ 1768cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeString(final int fieldNumber, final String value) 1778cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1788cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); 1798cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeStringNoTag(value); 1808cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1818cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1828cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code StringUtf8Micro} field, including tag, to the stream. */ 1838cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeStringUtf8(final int fieldNumber, final StringUtf8Micro value) 1848cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1858cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); 1868cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeStringUtf8NoTag(value); 1878cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1888cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1898cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code group} field, including tag, to the stream. */ 1908cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeGroup(final int fieldNumber, final MessageMicro value) 1918cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 1928cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_START_GROUP); 1938cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeGroupNoTag(value); 1948cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_END_GROUP); 1958cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 1968cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 1978cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an embedded message field, including tag, to the stream. */ 1988cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeMessage(final int fieldNumber, final MessageMicro value) 1998cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 2008cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); 2018cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeMessageNoTag(value); 2028cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2038cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2048cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code bytes} field, including tag, to the stream. */ 2058cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeBytes(final int fieldNumber, final ByteStringMicro value) 2068cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 2078cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED); 2088cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeBytesNoTag(value); 2098cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code uint32} field, including tag, to the stream. */ 2128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeUInt32(final int fieldNumber, final int value) 2138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 2148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); 2158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeUInt32NoTag(value); 2168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 2198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Write an enum field, including tag, to the stream. Caller is responsible 2208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * for converting the enum value to its numeric value. 2218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 2228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeEnum(final int fieldNumber, final int value) 2238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 2248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); 2258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeEnumNoTag(value); 2268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code sfixed32} field, including tag, to the stream. */ 2298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeSFixed32(final int fieldNumber, final int value) 2308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 2318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32); 2328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeSFixed32NoTag(value); 2338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code sfixed64} field, including tag, to the stream. */ 2368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeSFixed64(final int fieldNumber, final long value) 2378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 2388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64); 2398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeSFixed64NoTag(value); 2408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code sint32} field, including tag, to the stream. */ 2438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeSInt32(final int fieldNumber, final int value) 2448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 2458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); 2468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeSInt32NoTag(value); 2478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code sint64} field, including tag, to the stream. */ 2508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeSInt64(final int fieldNumber, final long value) 2518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com throws IOException { 2528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT); 2538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeSInt64NoTag(value); 2548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 2578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Write a MessageSet extension field to the stream. For historical reasons, 2588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * the wire format differs from normal fields. 2598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 2608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// public void writeMessageSetExtension(final int fieldNumber, 2618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// final MessageMicro value) 2628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// throws IOException { 2638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP); 2648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber); 2658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value); 2668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP); 2678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// } 2688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 2708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Write an unparsed MessageSet extension field to the stream. For 2718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * historical reasons, the wire format differs from normal fields. 2728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 2738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// public void writeRawMessageSetExtension(final int fieldNumber, 2748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// final ByteStringMicro value) 2758cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// throws IOException { 2768cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP); 2778cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber); 2788cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value); 2798cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP); 2808cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com// } 2818cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2828cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com // ----------------------------------------------------------------- 2838cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2848cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code double} field to the stream. */ 2858cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeDoubleNoTag(final double value) throws IOException { 2868cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawLittleEndian64(Double.doubleToLongBits(value)); 2878cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2888cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2898cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code float} field to the stream. */ 2908cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeFloatNoTag(final float value) throws IOException { 2918cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawLittleEndian32(Float.floatToIntBits(value)); 2928cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2938cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2948cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code uint64} field to the stream. */ 2958cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeUInt64NoTag(final long value) throws IOException { 2968cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint64(value); 2978cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 2988cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 2998cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code int64} field to the stream. */ 3008cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeInt64NoTag(final long value) throws IOException { 3018cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint64(value); 3028cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3038cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3048cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code int32} field to the stream. */ 3058cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeInt32NoTag(final int value) throws IOException { 3068cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com if (value >= 0) { 3078cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint32(value); 3088cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } else { 3098cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com // Must sign-extend. 3108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint64(value); 3118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code fixed64} field to the stream. */ 3158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeFixed64NoTag(final long value) throws IOException { 3168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawLittleEndian64(value); 3178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code fixed32} field to the stream. */ 3208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeFixed32NoTag(final int value) throws IOException { 3218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawLittleEndian32(value); 3228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code bool} field to the stream. */ 3258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeBoolNoTag(final boolean value) throws IOException { 3268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawByte(value ? 1 : 0); 3278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code string} field to the stream. */ 3308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeStringNoTag(final String value) throws IOException { 3318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com // Unfortunately there does not appear to be any way to tell Java to encode 3328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com // UTF-8 directly into our buffer, so we have to let it create its own byte 3338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com // array and then copy. 3348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final byte[] bytes = value.getBytes("UTF-8"); 3358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint32(bytes.length); 3368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawBytes(bytes); 3378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code StringUtf8Micro} field to the stream. */ 3408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeStringUtf8NoTag(final StringUtf8Micro value) throws IOException { 3418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final byte[] bytes = value.getBytes(); 3428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint32(bytes.length); 3438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawBytes(bytes); 3448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code group} field to the stream. */ 3478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeGroupNoTag(final MessageMicro value) throws IOException { 3488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com value.writeTo(this); 3498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an embedded message field to the stream. */ 3528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeMessageNoTag(final MessageMicro value) throws IOException { 3538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint32(value.getCachedSize()); 3548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com value.writeTo(this); 3558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code bytes} field to the stream. */ 3588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeBytesNoTag(final ByteStringMicro value) throws IOException { 3598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final byte[] bytes = value.toByteArray(); 3608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint32(bytes.length); 3618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawBytes(bytes); 3628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write a {@code uint32} field to the stream. */ 3658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeUInt32NoTag(final int value) throws IOException { 3668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint32(value); 3678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 3708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Write an enum field to the stream. Caller is responsible 3718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * for converting the enum value to its numeric value. 3728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 3738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeEnumNoTag(final int value) throws IOException { 3748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint32(value); 3758cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3768cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3778cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code sfixed32} field to the stream. */ 3788cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeSFixed32NoTag(final int value) throws IOException { 3798cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawLittleEndian32(value); 3808cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3818cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3828cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code sfixed64} field to the stream. */ 3838cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeSFixed64NoTag(final long value) throws IOException { 3848cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawLittleEndian64(value); 3858cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3868cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3878cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code sint32} field to the stream. */ 3888cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeSInt32NoTag(final int value) throws IOException { 3898cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint32(encodeZigZag32(value)); 3908cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3918cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3928cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** Write an {@code sint64} field to the stream. */ 3938cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public void writeSInt64NoTag(final long value) throws IOException { 3948cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com writeRawVarint64(encodeZigZag64(value)); 3958cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 3968cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3978cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com // ================================================================= 3988cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 3998cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4008cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 4018cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code double} field, including tag. 4028cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4038cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeDoubleSize(final int fieldNumber, 4048cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final double value) { 4058cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value); 4068cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4078cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4088cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4098cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 4108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code float} field, including tag. 4118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeFloatSize(final int fieldNumber, final float value) { 4138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value); 4148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 4188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code uint64} field, including tag. 4198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeUInt64Size(final int fieldNumber, final long value) { 4218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value); 4228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode an 4268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code int64} field, including tag. 4278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeInt64Size(final int fieldNumber, final long value) { 4298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value); 4308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode an 4348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code int32} field, including tag. 4358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeInt32Size(final int fieldNumber, final int value) { 4378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value); 4388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 4428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code fixed64} field, including tag. 4438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeFixed64Size(final int fieldNumber, 4458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final long value) { 4468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value); 4478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 4518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code fixed32} field, including tag. 4528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeFixed32Size(final int fieldNumber, 4548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final int value) { 4558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value); 4568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 4608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code bool} field, including tag. 4618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeBoolSize(final int fieldNumber, 4638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final boolean value) { 4648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value); 4658cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4668cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4678cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4688cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 4698cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code string} field, including tag. 4708cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4718cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeStringSize(final int fieldNumber, 4728cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final String value) { 4738cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeStringSizeNoTag(value); 4748cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4758cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4768cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4778cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 4788cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code StringUtf8Micro} field, including tag. 4798cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4808cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeStringUtf8Size(final int fieldNumber, 4818cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final StringUtf8Micro value) { 4828cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeStringUtf8SizeNoTag(value); 4838cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4848cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4858cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4868cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 4878cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code group} field, including tag. 4888cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4898cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeGroupSize(final int fieldNumber, 4908cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final MessageMicro value) { 4918cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value); 4928cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 4938cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 4948cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 4958cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode an 4968cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * embedded message field, including tag. 4978cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 4988cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeMessageSize(final int fieldNumber, 4998cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final MessageMicro value) { 5008cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value); 5018cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 5028cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 5038cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 5048cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 5058cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code bytes} field, including tag. 5068cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 5078cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeBytesSize(final int fieldNumber, 5088cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com final ByteStringMicro value) { 5098cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value); 5108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 5118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 5128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 5138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode a 5148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * {@code uint32} field, including tag. 5158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 5168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeUInt32Size(final int fieldNumber, final int value) { 5178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value); 5188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 5198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 5208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com /** 5218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Compute the number of bytes that would be needed to encode an 5228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * enum field, including tag. Caller is responsible for converting the 5238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * enum value to its numeric value. 5248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 5258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com public static int computeEnumSize(final int fieldNumber, final int value) { 5268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value); 5278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 5288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 529cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com /** 530 * Compute the number of bytes that would be needed to encode an 531 * {@code sfixed32} field, including tag. 532 */ 533 public static int computeSFixed32Size(final int fieldNumber, 534 final int value) { 535 return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value); 536 } 537 538 /** 539 * Compute the number of bytes that would be needed to encode an 540 * {@code sfixed64} field, including tag. 541 */ 542 public static int computeSFixed64Size(final int fieldNumber, 543 final long value) { 544 return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value); 545 } 546 547 /** 548 * Compute the number of bytes that would be needed to encode an 549 * {@code sint32} field, including tag. 550 */ 551 public static int computeSInt32Size(final int fieldNumber, final int value) { 552 return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value); 553 } 554 555 /** 556 * Compute the number of bytes that would be needed to encode an 557 * {@code sint64} field, including tag. 558 */ 559 public static int computeSInt64Size(final int fieldNumber, final long value) { 560 return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value); 561 } 562 563 /** 564 * Compute the number of bytes that would be needed to encode a 565 * MessageSet extension to the stream. For historical reasons, 566 * the wire format differs from normal fields. 567 */ 568// public static int computeMessageSetExtensionSize( 569// final int fieldNumber, final MessageMicro value) { 570// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 + 571// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) + 572// computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value); 573// } 574 575 /** 576 * Compute the number of bytes that would be needed to encode an 577 * unparsed MessageSet extension field to the stream. For 578 * historical reasons, the wire format differs from normal fields. 579 */ 580// public static int computeRawMessageSetExtensionSize( 581// final int fieldNumber, final ByteStringMicro value) { 582// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 + 583// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) + 584// computeBytesSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value); 585// } 586 587 // ----------------------------------------------------------------- 588 589 /** 590 * Compute the number of bytes that would be needed to encode a 591 * {@code double} field, including tag. 592 */ 593 public static int computeDoubleSizeNoTag(final double value) { 594 return LITTLE_ENDIAN_64_SIZE; 595 } 596 597 /** 598 * Compute the number of bytes that would be needed to encode a 599 * {@code float} field, including tag. 600 */ 601 public static int computeFloatSizeNoTag(final float value) { 602 return LITTLE_ENDIAN_32_SIZE; 603 } 604 605 /** 606 * Compute the number of bytes that would be needed to encode a 607 * {@code uint64} field, including tag. 608 */ 609 public static int computeUInt64SizeNoTag(final long value) { 610 return computeRawVarint64Size(value); 611 } 612 613 /** 614 * Compute the number of bytes that would be needed to encode an 615 * {@code int64} field, including tag. 616 */ 617 public static int computeInt64SizeNoTag(final long value) { 618 return computeRawVarint64Size(value); 619 } 620 621 /** 622 * Compute the number of bytes that would be needed to encode an 623 * {@code int32} field, including tag. 624 */ 625 public static int computeInt32SizeNoTag(final int value) { 626 if (value >= 0) { 627 return computeRawVarint32Size(value); 628 } else { 629 // Must sign-extend. 630 return 10; 631 } 632 } 633 634 /** 635 * Compute the number of bytes that would be needed to encode a 636 * {@code fixed64} field. 637 */ 638 public static int computeFixed64SizeNoTag(final long value) { 639 return LITTLE_ENDIAN_64_SIZE; 640 } 641 642 /** 643 * Compute the number of bytes that would be needed to encode a 644 * {@code fixed32} field. 645 */ 646 public static int computeFixed32SizeNoTag(final int value) { 647 return LITTLE_ENDIAN_32_SIZE; 648 } 649 650 /** 651 * Compute the number of bytes that would be needed to encode a 652 * {@code bool} field. 653 */ 654 public static int computeBoolSizeNoTag(final boolean value) { 655 return 1; 656 } 657 658 /** 659 * Compute the number of bytes that would be needed to encode a 660 * {@code string} field. 661 */ 662 public static int computeStringSizeNoTag(final String value) { 663 try { 664 final byte[] bytes = value.getBytes("UTF-8"); 665 return computeRawVarint32Size(bytes.length) + 666 bytes.length; 667 } catch (UnsupportedEncodingException e) { 668 throw new RuntimeException("UTF-8 not supported."); 669 } 670 } 671 672 /** 673 * Compute the number of bytes that would be needed to encode a 674 * {@code StringUtf8Micro} field. 675 */ 676 public static int computeStringUtf8SizeNoTag(final StringUtf8Micro value) { 677 final byte[] bytes = value.getBytes(); 678 return computeRawVarint32Size(bytes.length) + 679 bytes.length; 680 } 681 682 /** 683 * Compute the number of bytes that would be needed to encode a 684 * {@code group} field. 685 */ 686 public static int computeGroupSizeNoTag(final MessageMicro value) { 687 return value.getCachedSize(); 688 } 689 690 /** 691 * Compute the number of bytes that would be needed to encode an embedded 692 * message field. 693 */ 694 public static int computeMessageSizeNoTag(final MessageMicro value) { 695 final int size = value.getCachedSize(); 696 return computeRawVarint32Size(size) + size; 697 } 698 699 /** 700 * Compute the number of bytes that would be needed to encode a 701 * {@code bytes} field. 702 */ 703 public static int computeBytesSizeNoTag(final ByteStringMicro value) { 704 return computeRawVarint32Size(value.size()) + 705 value.size(); 706 } 707 708 /** 709 * Compute the number of bytes that would be needed to encode a 710 * {@code uint32} field. 711 */ 712 public static int computeUInt32SizeNoTag(final int value) { 713 return computeRawVarint32Size(value); 714 } 715 716 /** 717 * Compute the number of bytes that would be needed to encode an enum field. 718 * Caller is responsible for converting the enum value to its numeric value. 719 */ 720 public static int computeEnumSizeNoTag(final int value) { 721 return computeRawVarint32Size(value); 722 } 723 724 /** 725 * Compute the number of bytes that would be needed to encode an 726 * {@code sfixed32} field. 727 */ 728 public static int computeSFixed32SizeNoTag(final int value) { 729 return LITTLE_ENDIAN_32_SIZE; 730 } 731 732 /** 733 * Compute the number of bytes that would be needed to encode an 734 * {@code sfixed64} field. 735 */ 736 public static int computeSFixed64SizeNoTag(final long value) { 737 return LITTLE_ENDIAN_64_SIZE; 738 } 739 740 /** 741 * Compute the number of bytes that would be needed to encode an 742 * {@code sint32} field. 743 */ 744 public static int computeSInt32SizeNoTag(final int value) { 745 return computeRawVarint32Size(encodeZigZag32(value)); 746 } 747 748 /** 749 * Compute the number of bytes that would be needed to encode an 750 * {@code sint64} field. 751 */ 752 public static int computeSInt64SizeNoTag(final long value) { 753 return computeRawVarint64Size(encodeZigZag64(value)); 754 } 755 756 // ================================================================= 757 758 /** 759 * Internal helper that writes the current buffer to the output. The 760 * buffer position is reset to its initial value when this returns. 761 */ 762 private void refreshBuffer() throws IOException { 763 if (output == null) { 764 // We're writing to a single buffer. 765 throw new OutOfSpaceException(); 766 } 767 768 // Since we have an output stream, this is our buffer 769 // and buffer offset == 0 770 output.write(buffer, 0, position); 771 position = 0; 772 } 773 774 /** 775 * Flushes the stream and forces any buffered bytes to be written. This 776 * does not flush the underlying OutputStream. 777 */ 778 public void flush() throws IOException { 779 if (output != null) { 780 refreshBuffer(); 781 } 782 } 783 784 /** 785 * If writing to a flat array, return the space left in the array. 786 * Otherwise, throws {@code UnsupportedOperationException}. 787 */ 788 public int spaceLeft() { 789 if (output == null) { 790 return limit - position; 791 } else { 792 throw new UnsupportedOperationException( 793 "spaceLeft() can only be called on CodedOutputStreams that are " + 794 "writing to a flat array."); 795 } 796 } 797 798 /** 799 * Verifies that {@link #spaceLeft()} returns zero. It's common to create 800 * a byte array that is exactly big enough to hold a message, then write to 801 * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()} 802 * after writing verifies that the message was actually as big as expected, 803 * which can help catch bugs. 804 */ 805 public void checkNoSpaceLeft() { 806 if (spaceLeft() != 0) { 807 throw new IllegalStateException( 808 "Did not write as much data as expected."); 809 } 810 } 811 812 /** 813 * If you create a CodedOutputStream around a simple flat array, you must 814 * not attempt to write more bytes than the array has space. Otherwise, 815 * this exception will be thrown. 816 */ 817 public static class OutOfSpaceException extends IOException { 818 private static final long serialVersionUID = -6947486886997889499L; 819 820 OutOfSpaceException() { 821 super("CodedOutputStream was writing to a flat byte array and ran " + 822 "out of space."); 823 } 824 } 825 826 /** Write a single byte. */ 827 public void writeRawByte(final byte value) throws IOException { 828 if (position == limit) { 829 refreshBuffer(); 830 } 831 832 buffer[position++] = value; 833 } 834 835 /** Write a single byte, represented by an integer value. */ 836 public void writeRawByte(final int value) throws IOException { 837 writeRawByte((byte) value); 838 } 839 840 /** Write an array of bytes. */ 841 public void writeRawBytes(final byte[] value) throws IOException { 842 writeRawBytes(value, 0, value.length); 843 } 844 845 /** Write part of an array of bytes. */ 846 public void writeRawBytes(final byte[] value, int offset, int length) 847 throws IOException { 848 if (limit - position >= length) { 849 // We have room in the current buffer. 850 System.arraycopy(value, offset, buffer, position, length); 851 position += length; 852 } else { 853 // Write extends past current buffer. Fill the rest of this buffer and 854 // flush. 855 final int bytesWritten = limit - position; 856 System.arraycopy(value, offset, buffer, position, bytesWritten); 857 offset += bytesWritten; 858 length -= bytesWritten; 859 position = limit; 860 refreshBuffer(); 861 862 // Now deal with the rest. 863 // Since we have an output stream, this is our buffer 864 // and buffer offset == 0 865 if (length <= limit) { 866 // Fits in new buffer. 867 System.arraycopy(value, offset, buffer, 0, length); 868 position = length; 869 } else { 870 // Write is very big. Let's do it all at once. 871 output.write(value, offset, length); 872 } 873 } 874 } 875 876 /** Encode and write a tag. */ 877 public void writeTag(final int fieldNumber, final int wireType) 878 throws IOException { 879 writeRawVarint32(WireFormatMicro.makeTag(fieldNumber, wireType)); 880 } 881 882 /** Compute the number of bytes that would be needed to encode a tag. */ 883 public static int computeTagSize(final int fieldNumber) { 884 return computeRawVarint32Size(WireFormatMicro.makeTag(fieldNumber, 0)); 885 } 886 887 /** 888 * Encode and write a varint. {@code value} is treated as 889 * unsigned, so it won't be sign-extended if negative. 890 */ 891 public void writeRawVarint32(int value) throws IOException { 892 while (true) { 893 if ((value & ~0x7F) == 0) { 894 writeRawByte(value); 895 return; 896 } else { 897 writeRawByte((value & 0x7F) | 0x80); 898 value >>>= 7; 899 } 900 } 901 } 902 903 /** 904 * Compute the number of bytes that would be needed to encode a varint. 905 * {@code value} is treated as unsigned, so it won't be sign-extended if 906 * negative. 907 */ 908 public static int computeRawVarint32Size(final int value) { 909 if ((value & (0xffffffff << 7)) == 0) return 1; 910 if ((value & (0xffffffff << 14)) == 0) return 2; 911 if ((value & (0xffffffff << 21)) == 0) return 3; 912 if ((value & (0xffffffff << 28)) == 0) return 4; 913 return 5; 914 } 915 916 /** Encode and write a varint. */ 917 public void writeRawVarint64(long value) throws IOException { 918 while (true) { 919 if ((value & ~0x7FL) == 0) { 920 writeRawByte((int)value); 921 return; 922 } else { 923 writeRawByte(((int)value & 0x7F) | 0x80); 924 value >>>= 7; 925 } 926 } 927 } 928 929 /** Compute the number of bytes that would be needed to encode a varint. */ 930 public static int computeRawVarint64Size(final long value) { 931 if ((value & (0xffffffffffffffffL << 7)) == 0) return 1; 932 if ((value & (0xffffffffffffffffL << 14)) == 0) return 2; 933 if ((value & (0xffffffffffffffffL << 21)) == 0) return 3; 934 if ((value & (0xffffffffffffffffL << 28)) == 0) return 4; 935 if ((value & (0xffffffffffffffffL << 35)) == 0) return 5; 936 if ((value & (0xffffffffffffffffL << 42)) == 0) return 6; 937 if ((value & (0xffffffffffffffffL << 49)) == 0) return 7; 938 if ((value & (0xffffffffffffffffL << 56)) == 0) return 8; 939 if ((value & (0xffffffffffffffffL << 63)) == 0) return 9; 940 return 10; 941 } 942 943 /** Write a little-endian 32-bit integer. */ 944 public void writeRawLittleEndian32(final int value) throws IOException { 945 writeRawByte((value ) & 0xFF); 946 writeRawByte((value >> 8) & 0xFF); 947 writeRawByte((value >> 16) & 0xFF); 948 writeRawByte((value >> 24) & 0xFF); 949 } 950 951 public static final int LITTLE_ENDIAN_32_SIZE = 4; 952 953 /** Write a little-endian 64-bit integer. */ 954 public void writeRawLittleEndian64(final long value) throws IOException { 955 writeRawByte((int)(value ) & 0xFF); 956 writeRawByte((int)(value >> 8) & 0xFF); 957 writeRawByte((int)(value >> 16) & 0xFF); 958 writeRawByte((int)(value >> 24) & 0xFF); 959 writeRawByte((int)(value >> 32) & 0xFF); 960 writeRawByte((int)(value >> 40) & 0xFF); 961 writeRawByte((int)(value >> 48) & 0xFF); 962 writeRawByte((int)(value >> 56) & 0xFF); 963 } 964 965 public static final int LITTLE_ENDIAN_64_SIZE = 8; 966 967 /** 968 * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers 969 * into values that can be efficiently encoded with varint. (Otherwise, 970 * negative values must be sign-extended to 64 bits to be varint encoded, 971 * thus always taking 10 bytes on the wire.) 972 * 973 * @param n A signed 32-bit integer. 974 * @return An unsigned 32-bit integer, stored in a signed int because 975 * Java has no explicit unsigned support. 976 */ 977 public static int encodeZigZag32(final int n) { 978 // Note: the right-shift must be arithmetic 979 return (n << 1) ^ (n >> 31); 980 } 981 982 /** 983 * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers 984 * into values that can be efficiently encoded with varint. (Otherwise, 985 * negative values must be sign-extended to 64 bits to be varint encoded, 986 * thus always taking 10 bytes on the wire.) 987 * 988 * @param n A signed 64-bit integer. 989 * @return An unsigned 64-bit integer, stored in a signed int because 990 * Java has no explicit unsigned support. 991 */ 992 public static long encodeZigZag64(final long n) { 993 // Note: the right-shift must be arithmetic 994 return (n << 1) ^ (n >> 63); 995 } 996} 997