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