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