1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 package com.google.protobuf;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.OutputStream;
36 import java.io.UnsupportedEncodingException;
39 * Encodes and writes protocol message fields.
41 * <p>This class contains two kinds of methods: methods that write specific
42 * protocol message constructs and field types (e.g. {@link #writeTag} and
43 * {@link #writeInt32}) and methods that write low-level values (e.g.
44 * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are
45 * writing encoded protocol messages, you should use the former methods, but if
46 * you are writing some other format of your own design, use the latter.
48 * <p>This class is totally unsynchronized.
50 * @author kneton@google.com Kenton Varda
52 public final class CodedOutputStream {
53 private final byte[] buffer;
54 private final int limit;
57 private final OutputStream output;
60 * The buffer size used in {@link #newInstance(OutputStream)}.
62 public static final int DEFAULT_BUFFER_SIZE = 4096;
65 * Returns the buffer size to efficiently write dataLength bytes to this
66 * CodedOutputStream. Used by AbstractMessageLite.
68 * @return the buffer size to efficiently write dataLength bytes to this
71 static int computePreferredBufferSize(int dataLength) {
72 if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE;
76 private CodedOutputStream(final byte[] buffer, final int offset,
81 limit = offset + length;
84 private CodedOutputStream(final OutputStream output, final byte[] buffer) {
88 limit = buffer.length;
92 * Create a new {@code CodedOutputStream} wrapping the given
93 * {@code OutputStream}.
95 public static CodedOutputStream newInstance(final OutputStream output) {
96 return newInstance(output, DEFAULT_BUFFER_SIZE);
100 * Create a new {@code CodedOutputStream} wrapping the given
101 * {@code OutputStream} with a given buffer size.
103 public static CodedOutputStream newInstance(final OutputStream output,
104 final int bufferSize) {
105 return new CodedOutputStream(output, new byte[bufferSize]);
109 * Create a new {@code CodedOutputStream} that writes directly to the given
110 * byte array. If more bytes are written than fit in the array,
111 * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
112 * array is faster than writing to an {@code OutputStream}. See also
113 * {@link ByteString#newCodedBuilder}.
115 public static CodedOutputStream newInstance(final byte[] flatArray) {
116 return newInstance(flatArray, 0, flatArray.length);
120 * Create a new {@code CodedOutputStream} that writes directly to the given
121 * byte array slice. If more bytes are written than fit in the slice,
122 * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
123 * array is faster than writing to an {@code OutputStream}. See also
124 * {@link ByteString#newCodedBuilder}.
126 public static CodedOutputStream newInstance(final byte[] flatArray,
129 return new CodedOutputStream(flatArray, offset, length);
132 // -----------------------------------------------------------------
134 /** Write a {@code double} field, including tag, to the stream. */
135 public void writeDouble(final int fieldNumber, final double value)
137 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
138 writeDoubleNoTag(value);
141 /** Write a {@code float} field, including tag, to the stream. */
142 public void writeFloat(final int fieldNumber, final float value)
144 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
145 writeFloatNoTag(value);
148 /** Write a {@code uint64} field, including tag, to the stream. */
149 public void writeUInt64(final int fieldNumber, final long value)
151 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
152 writeUInt64NoTag(value);
155 /** Write an {@code int64} field, including tag, to the stream. */
156 public void writeInt64(final int fieldNumber, final long value)
158 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
159 writeInt64NoTag(value);
162 /** Write an {@code int32} field, including tag, to the stream. */
163 public void writeInt32(final int fieldNumber, final int value)
165 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
166 writeInt32NoTag(value);
169 /** Write a {@code fixed64} field, including tag, to the stream. */
170 public void writeFixed64(final int fieldNumber, final long value)
172 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
173 writeFixed64NoTag(value);
176 /** Write a {@code fixed32} field, including tag, to the stream. */
177 public void writeFixed32(final int fieldNumber, final int value)
179 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
180 writeFixed32NoTag(value);
183 /** Write a {@code bool} field, including tag, to the stream. */
184 public void writeBool(final int fieldNumber, final boolean value)
186 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
187 writeBoolNoTag(value);
190 /** Write a {@code string} field, including tag, to the stream. */
191 public void writeString(final int fieldNumber, final String value)
193 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
194 writeStringNoTag(value);
197 /** Write a {@code group} field, including tag, to the stream. */
198 public void writeGroup(final int fieldNumber, final MessageLite value)
200 writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
201 writeGroupNoTag(value);
202 writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
206 * Write a group represented by an {@link UnknownFieldSet}.
208 * @deprecated UnknownFieldSet now implements MessageLite, so you can just
209 * call {@link #writeGroup}.
212 public void writeUnknownGroup(final int fieldNumber,
213 final MessageLite value)
215 writeGroup(fieldNumber, value);
218 /** Write an embedded message field, including tag, to the stream. */
219 public void writeMessage(final int fieldNumber, final MessageLite value)
221 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
222 writeMessageNoTag(value);
225 /** Write a {@code bytes} field, including tag, to the stream. */
226 public void writeBytes(final int fieldNumber, final ByteString value)
228 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
229 writeBytesNoTag(value);
232 /** Write a {@code uint32} field, including tag, to the stream. */
233 public void writeUInt32(final int fieldNumber, final int value)
235 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
236 writeUInt32NoTag(value);
240 * Write an enum field, including tag, to the stream. Caller is responsible
241 * for converting the enum value to its numeric value.
243 public void writeEnum(final int fieldNumber, final int value)
245 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
246 writeEnumNoTag(value);
249 /** Write an {@code sfixed32} field, including tag, to the stream. */
250 public void writeSFixed32(final int fieldNumber, final int value)
252 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
253 writeSFixed32NoTag(value);
256 /** Write an {@code sfixed64} field, including tag, to the stream. */
257 public void writeSFixed64(final int fieldNumber, final long value)
259 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
260 writeSFixed64NoTag(value);
263 /** Write an {@code sint32} field, including tag, to the stream. */
264 public void writeSInt32(final int fieldNumber, final int value)
266 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
267 writeSInt32NoTag(value);
270 /** Write an {@code sint64} field, including tag, to the stream. */
271 public void writeSInt64(final int fieldNumber, final long value)
273 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
274 writeSInt64NoTag(value);
278 * Write a MessageSet extension field to the stream. For historical reasons,
279 * the wire format differs from normal fields.
281 public void writeMessageSetExtension(final int fieldNumber,
282 final MessageLite value)
284 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
285 writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
286 writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
287 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
291 * Write an unparsed MessageSet extension field to the stream. For
292 * historical reasons, the wire format differs from normal fields.
294 public void writeRawMessageSetExtension(final int fieldNumber,
295 final ByteString value)
297 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
298 writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
299 writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
300 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
303 // -----------------------------------------------------------------
305 /** Write a {@code double} field to the stream. */
306 public void writeDoubleNoTag(final double value) throws IOException {
307 writeRawLittleEndian64(Double.doubleToRawLongBits(value));
310 /** Write a {@code float} field to the stream. */
311 public void writeFloatNoTag(final float value) throws IOException {
312 writeRawLittleEndian32(Float.floatToRawIntBits(value));
315 /** Write a {@code uint64} field to the stream. */
316 public void writeUInt64NoTag(final long value) throws IOException {
317 writeRawVarint64(value);
320 /** Write an {@code int64} field to the stream. */
321 public void writeInt64NoTag(final long value) throws IOException {
322 writeRawVarint64(value);
325 /** Write an {@code int32} field to the stream. */
326 public void writeInt32NoTag(final int value) throws IOException {
328 writeRawVarint32(value);
331 writeRawVarint64(value);
335 /** Write a {@code fixed64} field to the stream. */
336 public void writeFixed64NoTag(final long value) throws IOException {
337 writeRawLittleEndian64(value);
340 /** Write a {@code fixed32} field to the stream. */
341 public void writeFixed32NoTag(final int value) throws IOException {
342 writeRawLittleEndian32(value);
345 /** Write a {@code bool} field to the stream. */
346 public void writeBoolNoTag(final boolean value) throws IOException {
347 writeRawByte(value ? 1 : 0);
350 /** Write a {@code string} field to the stream. */
351 public void writeStringNoTag(final String value) throws IOException {
352 // Unfortunately there does not appear to be any way to tell Java to encode
353 // UTF-8 directly into our buffer, so we have to let it create its own byte
354 // array and then copy.
355 final byte[] bytes = value.getBytes("UTF-8");
356 writeRawVarint32(bytes.length);
357 writeRawBytes(bytes);
360 /** Write a {@code group} field to the stream. */
361 public void writeGroupNoTag(final MessageLite value) throws IOException {
366 * Write a group represented by an {@link UnknownFieldSet}.
368 * @deprecated UnknownFieldSet now implements MessageLite, so you can just
369 * call {@link #writeGroupNoTag}.
372 public void writeUnknownGroupNoTag(final MessageLite value)
374 writeGroupNoTag(value);
377 /** Write an embedded message field to the stream. */
378 public void writeMessageNoTag(final MessageLite value) throws IOException {
379 writeRawVarint32(value.getSerializedSize());
383 /** Write a {@code bytes} field to the stream. */
384 public void writeBytesNoTag(final ByteString value) throws IOException {
385 writeRawVarint32(value.size());
386 writeRawBytes(value);
389 /** Write a {@code uint32} field to the stream. */
390 public void writeUInt32NoTag(final int value) throws IOException {
391 writeRawVarint32(value);
395 * Write an enum field to the stream. Caller is responsible
396 * for converting the enum value to its numeric value.
398 public void writeEnumNoTag(final int value) throws IOException {
399 writeInt32NoTag(value);
402 /** Write an {@code sfixed32} field to the stream. */
403 public void writeSFixed32NoTag(final int value) throws IOException {
404 writeRawLittleEndian32(value);
407 /** Write an {@code sfixed64} field to the stream. */
408 public void writeSFixed64NoTag(final long value) throws IOException {
409 writeRawLittleEndian64(value);
412 /** Write an {@code sint32} field to the stream. */
413 public void writeSInt32NoTag(final int value) throws IOException {
414 writeRawVarint32(encodeZigZag32(value));
417 /** Write an {@code sint64} field to the stream. */
418 public void writeSInt64NoTag(final long value) throws IOException {
419 writeRawVarint64(encodeZigZag64(value));
422 // =================================================================
425 * Compute the number of bytes that would be needed to encode a
426 * {@code double} field, including tag.
428 public static int computeDoubleSize(final int fieldNumber,
429 final double value) {
430 return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
434 * Compute the number of bytes that would be needed to encode a
435 * {@code float} field, including tag.
437 public static int computeFloatSize(final int fieldNumber, final float value) {
438 return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
442 * Compute the number of bytes that would be needed to encode a
443 * {@code uint64} field, including tag.
445 public static int computeUInt64Size(final int fieldNumber, final long value) {
446 return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
450 * Compute the number of bytes that would be needed to encode an
451 * {@code int64} field, including tag.
453 public static int computeInt64Size(final int fieldNumber, final long value) {
454 return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
458 * Compute the number of bytes that would be needed to encode an
459 * {@code int32} field, including tag.
461 public static int computeInt32Size(final int fieldNumber, final int value) {
462 return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
466 * Compute the number of bytes that would be needed to encode a
467 * {@code fixed64} field, including tag.
469 public static int computeFixed64Size(final int fieldNumber,
471 return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
475 * Compute the number of bytes that would be needed to encode a
476 * {@code fixed32} field, including tag.
478 public static int computeFixed32Size(final int fieldNumber,
480 return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
484 * Compute the number of bytes that would be needed to encode a
485 * {@code bool} field, including tag.
487 public static int computeBoolSize(final int fieldNumber,
488 final boolean value) {
489 return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
493 * Compute the number of bytes that would be needed to encode a
494 * {@code string} field, including tag.
496 public static int computeStringSize(final int fieldNumber,
497 final String value) {
498 return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
502 * Compute the number of bytes that would be needed to encode a
503 * {@code group} field, including tag.
505 public static int computeGroupSize(final int fieldNumber,
506 final MessageLite value) {
507 return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
511 * Compute the number of bytes that would be needed to encode a
512 * {@code group} field represented by an {@code UnknownFieldSet}, including
515 * @deprecated UnknownFieldSet now implements MessageLite, so you can just
516 * call {@link #computeGroupSize}.
519 public static int computeUnknownGroupSize(final int fieldNumber,
520 final MessageLite value) {
521 return computeGroupSize(fieldNumber, value);
525 * Compute the number of bytes that would be needed to encode an
526 * embedded message field, including tag.
528 public static int computeMessageSize(final int fieldNumber,
529 final MessageLite value) {
530 return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
534 * Compute the number of bytes that would be needed to encode a
535 * {@code bytes} field, including tag.
537 public static int computeBytesSize(final int fieldNumber,
538 final ByteString value) {
539 return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
543 * Compute the number of bytes that would be needed to encode an
544 * embedded message in lazy field, including tag.
546 public static int computeLazyFieldSize(final int fieldNumber,
547 final LazyField value) {
548 return computeTagSize(fieldNumber) + computeLazyFieldSizeNoTag(value);
552 * Compute the number of bytes that would be needed to encode a
553 * {@code uint32} field, including tag.
555 public static int computeUInt32Size(final int fieldNumber, final int value) {
556 return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
560 * Compute the number of bytes that would be needed to encode an
561 * enum field, including tag. Caller is responsible for converting the
562 * enum value to its numeric value.
564 public static int computeEnumSize(final int fieldNumber, final int value) {
565 return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
569 * Compute the number of bytes that would be needed to encode an
570 * {@code sfixed32} field, including tag.
572 public static int computeSFixed32Size(final int fieldNumber,
574 return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
578 * Compute the number of bytes that would be needed to encode an
579 * {@code sfixed64} field, including tag.
581 public static int computeSFixed64Size(final int fieldNumber,
583 return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
587 * Compute the number of bytes that would be needed to encode an
588 * {@code sint32} field, including tag.
590 public static int computeSInt32Size(final int fieldNumber, final int value) {
591 return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
595 * Compute the number of bytes that would be needed to encode an
596 * {@code sint64} field, including tag.
598 public static int computeSInt64Size(final int fieldNumber, final long value) {
599 return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
603 * Compute the number of bytes that would be needed to encode a
604 * MessageSet extension to the stream. For historical reasons,
605 * the wire format differs from normal fields.
607 public static int computeMessageSetExtensionSize(
608 final int fieldNumber, final MessageLite value) {
609 return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
610 computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
611 computeMessageSize(WireFormat.MESSAGE_SET_MESSAGE, value);
615 * Compute the number of bytes that would be needed to encode an
616 * unparsed MessageSet extension field to the stream. For
617 * historical reasons, the wire format differs from normal fields.
619 public static int computeRawMessageSetExtensionSize(
620 final int fieldNumber, final ByteString value) {
621 return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
622 computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
623 computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value);
627 * Compute the number of bytes that would be needed to encode an
628 * lazily parsed MessageSet extension field to the stream. For
629 * historical reasons, the wire format differs from normal fields.
631 public static int computeLazyFieldMessageSetExtensionSize(
632 final int fieldNumber, final LazyField value) {
633 return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
634 computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
635 computeLazyFieldSize(WireFormat.MESSAGE_SET_MESSAGE, value);
638 // -----------------------------------------------------------------
641 * Compute the number of bytes that would be needed to encode a
642 * {@code double} field, including tag.
644 public static int computeDoubleSizeNoTag(final double value) {
645 return LITTLE_ENDIAN_64_SIZE;
649 * Compute the number of bytes that would be needed to encode a
650 * {@code float} field, including tag.
652 public static int computeFloatSizeNoTag(final float value) {
653 return LITTLE_ENDIAN_32_SIZE;
657 * Compute the number of bytes that would be needed to encode a
658 * {@code uint64} field, including tag.
660 public static int computeUInt64SizeNoTag(final long value) {
661 return computeRawVarint64Size(value);
665 * Compute the number of bytes that would be needed to encode an
666 * {@code int64} field, including tag.
668 public static int computeInt64SizeNoTag(final long value) {
669 return computeRawVarint64Size(value);
673 * Compute the number of bytes that would be needed to encode an
674 * {@code int32} field, including tag.
676 public static int computeInt32SizeNoTag(final int value) {
678 return computeRawVarint32Size(value);
686 * Compute the number of bytes that would be needed to encode a
687 * {@code fixed64} field.
689 public static int computeFixed64SizeNoTag(final long value) {
690 return LITTLE_ENDIAN_64_SIZE;
694 * Compute the number of bytes that would be needed to encode a
695 * {@code fixed32} field.
697 public static int computeFixed32SizeNoTag(final int value) {
698 return LITTLE_ENDIAN_32_SIZE;
702 * Compute the number of bytes that would be needed to encode a
703 * {@code bool} field.
705 public static int computeBoolSizeNoTag(final boolean value) {
710 * Compute the number of bytes that would be needed to encode a
711 * {@code string} field.
713 public static int computeStringSizeNoTag(final String value) {
715 final byte[] bytes = value.getBytes("UTF-8");
716 return computeRawVarint32Size(bytes.length) +
718 } catch (UnsupportedEncodingException e) {
719 throw new RuntimeException("UTF-8 not supported.", e);
724 * Compute the number of bytes that would be needed to encode a
725 * {@code group} field.
727 public static int computeGroupSizeNoTag(final MessageLite value) {
728 return value.getSerializedSize();
732 * Compute the number of bytes that would be needed to encode a
733 * {@code group} field represented by an {@code UnknownFieldSet}, including
736 * @deprecated UnknownFieldSet now implements MessageLite, so you can just
737 * call {@link #computeUnknownGroupSizeNoTag}.
740 public static int computeUnknownGroupSizeNoTag(final MessageLite value) {
741 return computeGroupSizeNoTag(value);
745 * Compute the number of bytes that would be needed to encode an embedded
748 public static int computeMessageSizeNoTag(final MessageLite value) {
749 final int size = value.getSerializedSize();
750 return computeRawVarint32Size(size) + size;
754 * Compute the number of bytes that would be needed to encode an embedded
755 * message stored in lazy field.
757 public static int computeLazyFieldSizeNoTag(final LazyField value) {
758 final int size = value.getSerializedSize();
759 return computeRawVarint32Size(size) + size;
763 * Compute the number of bytes that would be needed to encode a
764 * {@code bytes} field.
766 public static int computeBytesSizeNoTag(final ByteString value) {
767 return computeRawVarint32Size(value.size()) +
772 * Compute the number of bytes that would be needed to encode a
773 * {@code uint32} field.
775 public static int computeUInt32SizeNoTag(final int value) {
776 return computeRawVarint32Size(value);
780 * Compute the number of bytes that would be needed to encode an enum field.
781 * Caller is responsible for converting the enum value to its numeric value.
783 public static int computeEnumSizeNoTag(final int value) {
784 return computeInt32SizeNoTag(value);
788 * Compute the number of bytes that would be needed to encode an
789 * {@code sfixed32} field.
791 public static int computeSFixed32SizeNoTag(final int value) {
792 return LITTLE_ENDIAN_32_SIZE;
796 * Compute the number of bytes that would be needed to encode an
797 * {@code sfixed64} field.
799 public static int computeSFixed64SizeNoTag(final long value) {
800 return LITTLE_ENDIAN_64_SIZE;
804 * Compute the number of bytes that would be needed to encode an
805 * {@code sint32} field.
807 public static int computeSInt32SizeNoTag(final int value) {
808 return computeRawVarint32Size(encodeZigZag32(value));
812 * Compute the number of bytes that would be needed to encode an
813 * {@code sint64} field.
815 public static int computeSInt64SizeNoTag(final long value) {
816 return computeRawVarint64Size(encodeZigZag64(value));
819 // =================================================================
822 * Internal helper that writes the current buffer to the output. The
823 * buffer position is reset to its initial value when this returns.
825 private void refreshBuffer() throws IOException {
826 if (output == null) {
827 // We're writing to a single buffer.
828 throw new OutOfSpaceException();
831 // Since we have an output stream, this is our buffer
832 // and buffer offset == 0
833 output.write(buffer, 0, position);
838 * Flushes the stream and forces any buffered bytes to be written. This
839 * does not flush the underlying OutputStream.
841 public void flush() throws IOException {
842 if (output != null) {
848 * If writing to a flat array, return the space left in the array.
849 * Otherwise, throws {@code UnsupportedOperationException}.
851 public int spaceLeft() {
852 if (output == null) {
853 return limit - position;
855 throw new UnsupportedOperationException(
856 "spaceLeft() can only be called on CodedOutputStreams that are " +
857 "writing to a flat array.");
862 * Verifies that {@link #spaceLeft()} returns zero. It's common to create
863 * a byte array that is exactly big enough to hold a message, then write to
864 * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()}
865 * after writing verifies that the message was actually as big as expected,
866 * which can help catch bugs.
868 public void checkNoSpaceLeft() {
869 if (spaceLeft() != 0) {
870 throw new IllegalStateException(
871 "Did not write as much data as expected.");
876 * If you create a CodedOutputStream around a simple flat array, you must
877 * not attempt to write more bytes than the array has space. Otherwise,
878 * this exception will be thrown.
880 public static class OutOfSpaceException extends IOException {
881 private static final long serialVersionUID = -6947486886997889499L;
883 OutOfSpaceException() {
884 super("CodedOutputStream was writing to a flat byte array and ran " +
889 /** Write a single byte. */
890 public void writeRawByte(final byte value) throws IOException {
891 if (position == limit) {
895 buffer[position++] = value;
898 /** Write a single byte, represented by an integer value. */
899 public void writeRawByte(final int value) throws IOException {
900 writeRawByte((byte) value);
903 /** Write a byte string. */
904 public void writeRawBytes(final ByteString value) throws IOException {
905 writeRawBytes(value, 0, value.size());
908 /** Write an array of bytes. */
909 public void writeRawBytes(final byte[] value) throws IOException {
910 writeRawBytes(value, 0, value.length);
913 /** Write part of an array of bytes. */
914 public void writeRawBytes(final byte[] value, int offset, int length)
916 if (limit - position >= length) {
917 // We have room in the current buffer.
918 System.arraycopy(value, offset, buffer, position, length);
921 // Write extends past current buffer. Fill the rest of this buffer and
923 final int bytesWritten = limit - position;
924 System.arraycopy(value, offset, buffer, position, bytesWritten);
925 offset += bytesWritten;
926 length -= bytesWritten;
930 // Now deal with the rest.
931 // Since we have an output stream, this is our buffer
932 // and buffer offset == 0
933 if (length <= limit) {
934 // Fits in new buffer.
935 System.arraycopy(value, offset, buffer, 0, length);
938 // Write is very big. Let's do it all at once.
939 output.write(value, offset, length);
944 /** Write part of a byte string. */
945 public void writeRawBytes(final ByteString value, int offset, int length)
947 if (limit - position >= length) {
948 // We have room in the current buffer.
949 value.copyTo(buffer, offset, position, length);
952 // Write extends past current buffer. Fill the rest of this buffer and
954 final int bytesWritten = limit - position;
955 value.copyTo(buffer, offset, position, bytesWritten);
956 offset += bytesWritten;
957 length -= bytesWritten;
961 // Now deal with the rest.
962 // Since we have an output stream, this is our buffer
963 // and buffer offset == 0
964 if (length <= limit) {
965 // Fits in new buffer.
966 value.copyTo(buffer, offset, 0, length);
969 // Write is very big, but we can't do it all at once without allocating
970 // an a copy of the byte array since ByteString does not give us access
971 // to the underlying bytes. Use the InputStream interface on the
972 // ByteString and our buffer to copy between the two.
973 InputStream inputStreamFrom = value.newInput();
974 if (offset != inputStreamFrom.skip(offset)) {
975 throw new IllegalStateException("Skip failed? Should never happen.");
977 // Use the buffer as the temporary buffer to avoid allocating memory.
979 int bytesToRead = Math.min(length, limit);
980 int bytesRead = inputStreamFrom.read(buffer, 0, bytesToRead);
981 if (bytesRead != bytesToRead) {
982 throw new IllegalStateException("Read failed? Should never happen");
984 output.write(buffer, 0, bytesRead);
991 /** Encode and write a tag. */
992 public void writeTag(final int fieldNumber, final int wireType)
994 writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType));
997 /** Compute the number of bytes that would be needed to encode a tag. */
998 public static int computeTagSize(final int fieldNumber) {
999 return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0));
1003 * Encode and write a varint. {@code value} is treated as
1004 * unsigned, so it won't be sign-extended if negative.
1006 public void writeRawVarint32(int value) throws IOException {
1008 if ((value & ~0x7F) == 0) {
1009 writeRawByte(value);
1012 writeRawByte((value & 0x7F) | 0x80);
1019 * Compute the number of bytes that would be needed to encode a varint.
1020 * {@code value} is treated as unsigned, so it won't be sign-extended if
1023 public static int computeRawVarint32Size(final int value) {
1024 if ((value & (0xffffffff << 7)) == 0) return 1;
1025 if ((value & (0xffffffff << 14)) == 0) return 2;
1026 if ((value & (0xffffffff << 21)) == 0) return 3;
1027 if ((value & (0xffffffff << 28)) == 0) return 4;
1031 /** Encode and write a varint. */
1032 public void writeRawVarint64(long value) throws IOException {
1034 if ((value & ~0x7FL) == 0) {
1035 writeRawByte((int)value);
1038 writeRawByte(((int)value & 0x7F) | 0x80);
1044 /** Compute the number of bytes that would be needed to encode a varint. */
1045 public static int computeRawVarint64Size(final long value) {
1046 if ((value & (0xffffffffffffffffL << 7)) == 0) return 1;
1047 if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
1048 if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
1049 if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
1050 if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
1051 if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
1052 if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
1053 if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
1054 if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
1058 /** Write a little-endian 32-bit integer. */
1059 public void writeRawLittleEndian32(final int value) throws IOException {
1060 writeRawByte((value ) & 0xFF);
1061 writeRawByte((value >> 8) & 0xFF);
1062 writeRawByte((value >> 16) & 0xFF);
1063 writeRawByte((value >> 24) & 0xFF);
1066 public static final int LITTLE_ENDIAN_32_SIZE = 4;
1068 /** Write a little-endian 64-bit integer. */
1069 public void writeRawLittleEndian64(final long value) throws IOException {
1070 writeRawByte((int)(value ) & 0xFF);
1071 writeRawByte((int)(value >> 8) & 0xFF);
1072 writeRawByte((int)(value >> 16) & 0xFF);
1073 writeRawByte((int)(value >> 24) & 0xFF);
1074 writeRawByte((int)(value >> 32) & 0xFF);
1075 writeRawByte((int)(value >> 40) & 0xFF);
1076 writeRawByte((int)(value >> 48) & 0xFF);
1077 writeRawByte((int)(value >> 56) & 0xFF);
1080 public static final int LITTLE_ENDIAN_64_SIZE = 8;
1083 * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
1084 * into values that can be efficiently encoded with varint. (Otherwise,
1085 * negative values must be sign-extended to 64 bits to be varint encoded,
1086 * thus always taking 10 bytes on the wire.)
1088 * @param n A signed 32-bit integer.
1089 * @return An unsigned 32-bit integer, stored in a signed int because
1090 * Java has no explicit unsigned support.
1092 public static int encodeZigZag32(final int n) {
1093 // Note: the right-shift must be arithmetic
1094 return (n << 1) ^ (n >> 31);
1098 * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
1099 * into values that can be efficiently encoded with varint. (Otherwise,
1100 * negative values must be sign-extended to 64 bits to be varint encoded,
1101 * thus always taking 10 bytes on the wire.)
1103 * @param n A signed 64-bit integer.
1104 * @return An unsigned 64-bit integer, stored in a signed int because
1105 * Java has no explicit unsigned support.
1107 public static long encodeZigZag64(final long n) {
1108 // Note: the right-shift must be arithmetic
1109 return (n << 1) ^ (n >> 63);