1// Protocol Buffers - Google's data interchange format 2// Copyright 2013 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 31package com.google.protobuf.nano; 32 33import java.io.IOException; 34import java.io.UnsupportedEncodingException; 35 36/** 37 * Encodes and writes protocol message fields. 38 * 39 * <p>This class contains two kinds of methods: methods that write specific 40 * protocol message constructs and field types (e.g. {@link #writeTag} and 41 * {@link #writeInt32}) and methods that write low-level values (e.g. 42 * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are 43 * writing encoded protocol messages, you should use the former methods, but if 44 * you are writing some other format of your own design, use the latter. 45 * 46 * <p>This class is totally unsynchronized. 47 * 48 * @author kneton@google.com Kenton Varda 49 */ 50public final class CodedOutputByteBufferNano { 51 private final byte[] buffer; 52 private final int limit; 53 private int position; 54 55 private CodedOutputByteBufferNano(final byte[] buffer, final int offset, 56 final int length) { 57 this.buffer = buffer; 58 position = offset; 59 limit = offset + length; 60 } 61 62 /** 63 * Create a new {@code CodedOutputStream} that writes directly to the given 64 * byte array. If more bytes are written than fit in the array, 65 * {@link OutOfSpaceException} will be thrown. Writing directly to a flat 66 * array is faster than writing to an {@code OutputStream}. 67 */ 68 public static CodedOutputByteBufferNano newInstance(final byte[] flatArray) { 69 return newInstance(flatArray, 0, flatArray.length); 70 } 71 72 /** 73 * Create a new {@code CodedOutputStream} that writes directly to the given 74 * byte array slice. If more bytes are written than fit in the slice, 75 * {@link OutOfSpaceException} will be thrown. Writing directly to a flat 76 * array is faster than writing to an {@code OutputStream}. 77 */ 78 public static CodedOutputByteBufferNano newInstance(final byte[] flatArray, 79 final int offset, 80 final int length) { 81 return new CodedOutputByteBufferNano(flatArray, offset, length); 82 } 83 84 // ----------------------------------------------------------------- 85 86 /** Write a {@code double} field, including tag, to the stream. */ 87 public void writeDouble(final int fieldNumber, final double value) 88 throws IOException { 89 writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64); 90 writeDoubleNoTag(value); 91 } 92 93 /** Write a {@code float} field, including tag, to the stream. */ 94 public void writeFloat(final int fieldNumber, final float value) 95 throws IOException { 96 writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32); 97 writeFloatNoTag(value); 98 } 99 100 /** Write a {@code uint64} field, including tag, to the stream. */ 101 public void writeUInt64(final int fieldNumber, final long value) 102 throws IOException { 103 writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT); 104 writeUInt64NoTag(value); 105 } 106 107 /** Write an {@code int64} field, including tag, to the stream. */ 108 public void writeInt64(final int fieldNumber, final long value) 109 throws IOException { 110 writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT); 111 writeInt64NoTag(value); 112 } 113 114 /** Write an {@code int32} field, including tag, to the stream. */ 115 public void writeInt32(final int fieldNumber, final int value) 116 throws IOException { 117 writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT); 118 writeInt32NoTag(value); 119 } 120 121 /** Write a {@code fixed64} field, including tag, to the stream. */ 122 public void writeFixed64(final int fieldNumber, final long value) 123 throws IOException { 124 writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64); 125 writeFixed64NoTag(value); 126 } 127 128 /** Write a {@code fixed32} field, including tag, to the stream. */ 129 public void writeFixed32(final int fieldNumber, final int value) 130 throws IOException { 131 writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32); 132 writeFixed32NoTag(value); 133 } 134 135 /** Write a {@code bool} field, including tag, to the stream. */ 136 public void writeBool(final int fieldNumber, final boolean value) 137 throws IOException { 138 writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT); 139 writeBoolNoTag(value); 140 } 141 142 /** Write a {@code string} field, including tag, to the stream. */ 143 public void writeString(final int fieldNumber, final String value) 144 throws IOException { 145 writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED); 146 writeStringNoTag(value); 147 } 148 149 /** Write a {@code group} field, including tag, to the stream. */ 150 public void writeGroup(final int fieldNumber, final MessageNano value) 151 throws IOException { 152 writeTag(fieldNumber, WireFormatNano.WIRETYPE_START_GROUP); 153 writeGroupNoTag(value); 154 writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP); 155 } 156 157 /** Write an embedded message field, including tag, to the stream. */ 158 public void writeMessage(final int fieldNumber, final MessageNano value) 159 throws IOException { 160 writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED); 161 writeMessageNoTag(value); 162 } 163 164 /** Write a {@code bytes} field, including tag, to the stream. */ 165 public void writeBytes(final int fieldNumber, final byte[] value) 166 throws IOException { 167 writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED); 168 writeBytesNoTag(value); 169 } 170 171 /** Write a {@code uint32} field, including tag, to the stream. */ 172 public void writeUInt32(final int fieldNumber, final int value) 173 throws IOException { 174 writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT); 175 writeUInt32NoTag(value); 176 } 177 178 /** 179 * Write an enum field, including tag, to the stream. Caller is responsible 180 * for converting the enum value to its numeric value. 181 */ 182 public void writeEnum(final int fieldNumber, final int value) 183 throws IOException { 184 writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT); 185 writeEnumNoTag(value); 186 } 187 188 /** Write an {@code sfixed32} field, including tag, to the stream. */ 189 public void writeSFixed32(final int fieldNumber, final int value) 190 throws IOException { 191 writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32); 192 writeSFixed32NoTag(value); 193 } 194 195 /** Write an {@code sfixed64} field, including tag, to the stream. */ 196 public void writeSFixed64(final int fieldNumber, final long value) 197 throws IOException { 198 writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64); 199 writeSFixed64NoTag(value); 200 } 201 202 /** Write an {@code sint32} field, including tag, to the stream. */ 203 public void writeSInt32(final int fieldNumber, final int value) 204 throws IOException { 205 writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT); 206 writeSInt32NoTag(value); 207 } 208 209 /** Write an {@code sint64} field, including tag, to the stream. */ 210 public void writeSInt64(final int fieldNumber, final long value) 211 throws IOException { 212 writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT); 213 writeSInt64NoTag(value); 214 } 215 216 /** 217 * Write a MessageSet extension field to the stream. For historical reasons, 218 * the wire format differs from normal fields. 219 */ 220// public void writeMessageSetExtension(final int fieldNumber, 221// final MessageMicro value) 222// throws IOException { 223// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP); 224// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber); 225// writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value); 226// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP); 227// } 228 229 /** 230 * Write an unparsed MessageSet extension field to the stream. For 231 * historical reasons, the wire format differs from normal fields. 232 */ 233// public void writeRawMessageSetExtension(final int fieldNumber, 234// final ByteStringMicro value) 235// throws IOException { 236// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP); 237// writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber); 238// writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value); 239// writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP); 240// } 241 242 // ----------------------------------------------------------------- 243 244 /** Write a {@code double} field to the stream. */ 245 public void writeDoubleNoTag(final double value) throws IOException { 246 writeRawLittleEndian64(Double.doubleToLongBits(value)); 247 } 248 249 /** Write a {@code float} field to the stream. */ 250 public void writeFloatNoTag(final float value) throws IOException { 251 writeRawLittleEndian32(Float.floatToIntBits(value)); 252 } 253 254 /** Write a {@code uint64} field to the stream. */ 255 public void writeUInt64NoTag(final long value) throws IOException { 256 writeRawVarint64(value); 257 } 258 259 /** Write an {@code int64} field to the stream. */ 260 public void writeInt64NoTag(final long value) throws IOException { 261 writeRawVarint64(value); 262 } 263 264 /** Write an {@code int32} field to the stream. */ 265 public void writeInt32NoTag(final int value) throws IOException { 266 if (value >= 0) { 267 writeRawVarint32(value); 268 } else { 269 // Must sign-extend. 270 writeRawVarint64(value); 271 } 272 } 273 274 /** Write a {@code fixed64} field to the stream. */ 275 public void writeFixed64NoTag(final long value) throws IOException { 276 writeRawLittleEndian64(value); 277 } 278 279 /** Write a {@code fixed32} field to the stream. */ 280 public void writeFixed32NoTag(final int value) throws IOException { 281 writeRawLittleEndian32(value); 282 } 283 284 /** Write a {@code bool} field to the stream. */ 285 public void writeBoolNoTag(final boolean value) throws IOException { 286 writeRawByte(value ? 1 : 0); 287 } 288 289 /** Write a {@code string} field to the stream. */ 290 public void writeStringNoTag(final String value) throws IOException { 291 // Unfortunately there does not appear to be any way to tell Java to encode 292 // UTF-8 directly into our buffer, so we have to let it create its own byte 293 // array and then copy. 294 final byte[] bytes = value.getBytes("UTF-8"); 295 writeRawVarint32(bytes.length); 296 writeRawBytes(bytes); 297 } 298 299 /** Write a {@code group} field to the stream. */ 300 public void writeGroupNoTag(final MessageNano value) throws IOException { 301 value.writeTo(this); 302 } 303 304 /** Write an embedded message field to the stream. */ 305 public void writeMessageNoTag(final MessageNano value) throws IOException { 306 writeRawVarint32(value.getCachedSize()); 307 value.writeTo(this); 308 } 309 310 /** Write a {@code bytes} field to the stream. */ 311 public void writeBytesNoTag(final byte[] value) throws IOException { 312 writeRawVarint32(value.length); 313 writeRawBytes(value); 314 } 315 316 /** Write a {@code uint32} field to the stream. */ 317 public void writeUInt32NoTag(final int value) throws IOException { 318 writeRawVarint32(value); 319 } 320 321 /** 322 * Write an enum field to the stream. Caller is responsible 323 * for converting the enum value to its numeric value. 324 */ 325 public void writeEnumNoTag(final int value) throws IOException { 326 writeRawVarint32(value); 327 } 328 329 /** Write an {@code sfixed32} field to the stream. */ 330 public void writeSFixed32NoTag(final int value) throws IOException { 331 writeRawLittleEndian32(value); 332 } 333 334 /** Write an {@code sfixed64} field to the stream. */ 335 public void writeSFixed64NoTag(final long value) throws IOException { 336 writeRawLittleEndian64(value); 337 } 338 339 /** Write an {@code sint32} field to the stream. */ 340 public void writeSInt32NoTag(final int value) throws IOException { 341 writeRawVarint32(encodeZigZag32(value)); 342 } 343 344 /** Write an {@code sint64} field to the stream. */ 345 public void writeSInt64NoTag(final long value) throws IOException { 346 writeRawVarint64(encodeZigZag64(value)); 347 } 348 349 // ================================================================= 350 351 /** 352 * Compute the number of bytes that would be needed to encode a 353 * {@code double} field, including tag. 354 */ 355 public static int computeDoubleSize(final int fieldNumber, 356 final double value) { 357 return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value); 358 } 359 360 /** 361 * Compute the number of bytes that would be needed to encode a 362 * {@code float} field, including tag. 363 */ 364 public static int computeFloatSize(final int fieldNumber, final float value) { 365 return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value); 366 } 367 368 /** 369 * Compute the number of bytes that would be needed to encode a 370 * {@code uint64} field, including tag. 371 */ 372 public static int computeUInt64Size(final int fieldNumber, final long value) { 373 return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value); 374 } 375 376 /** 377 * Compute the number of bytes that would be needed to encode an 378 * {@code int64} field, including tag. 379 */ 380 public static int computeInt64Size(final int fieldNumber, final long value) { 381 return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value); 382 } 383 384 /** 385 * Compute the number of bytes that would be needed to encode an 386 * {@code int32} field, including tag. 387 */ 388 public static int computeInt32Size(final int fieldNumber, final int value) { 389 return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value); 390 } 391 392 /** 393 * Compute the number of bytes that would be needed to encode a 394 * {@code fixed64} field, including tag. 395 */ 396 public static int computeFixed64Size(final int fieldNumber, 397 final long value) { 398 return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value); 399 } 400 401 /** 402 * Compute the number of bytes that would be needed to encode a 403 * {@code fixed32} field, including tag. 404 */ 405 public static int computeFixed32Size(final int fieldNumber, 406 final int value) { 407 return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value); 408 } 409 410 /** 411 * Compute the number of bytes that would be needed to encode a 412 * {@code bool} field, including tag. 413 */ 414 public static int computeBoolSize(final int fieldNumber, 415 final boolean value) { 416 return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value); 417 } 418 419 /** 420 * Compute the number of bytes that would be needed to encode a 421 * {@code string} field, including tag. 422 */ 423 public static int computeStringSize(final int fieldNumber, 424 final String value) { 425 return computeTagSize(fieldNumber) + computeStringSizeNoTag(value); 426 } 427 428 /** 429 * Compute the number of bytes that would be needed to encode a 430 * {@code group} field, including tag. 431 */ 432 public static int computeGroupSize(final int fieldNumber, 433 final MessageNano value) { 434 return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value); 435 } 436 437 /** 438 * Compute the number of bytes that would be needed to encode an 439 * embedded message field, including tag. 440 */ 441 public static int computeMessageSize(final int fieldNumber, 442 final MessageNano value) { 443 return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value); 444 } 445 446 /** 447 * Compute the number of bytes that would be needed to encode a 448 * {@code bytes} field, including tag. 449 */ 450 public static int computeBytesSize(final int fieldNumber, 451 final byte[] value) { 452 return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value); 453 } 454 455 /** 456 * Compute the number of bytes that would be needed to encode a 457 * {@code uint32} field, including tag. 458 */ 459 public static int computeUInt32Size(final int fieldNumber, final int value) { 460 return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value); 461 } 462 463 /** 464 * Compute the number of bytes that would be needed to encode an 465 * enum field, including tag. Caller is responsible for converting the 466 * enum value to its numeric value. 467 */ 468 public static int computeEnumSize(final int fieldNumber, final int value) { 469 return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value); 470 } 471 472 /** 473 * Compute the number of bytes that would be needed to encode an 474 * {@code sfixed32} field, including tag. 475 */ 476 public static int computeSFixed32Size(final int fieldNumber, 477 final int value) { 478 return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value); 479 } 480 481 /** 482 * Compute the number of bytes that would be needed to encode an 483 * {@code sfixed64} field, including tag. 484 */ 485 public static int computeSFixed64Size(final int fieldNumber, 486 final long value) { 487 return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value); 488 } 489 490 /** 491 * Compute the number of bytes that would be needed to encode an 492 * {@code sint32} field, including tag. 493 */ 494 public static int computeSInt32Size(final int fieldNumber, final int value) { 495 return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value); 496 } 497 498 /** 499 * Compute the number of bytes that would be needed to encode an 500 * {@code sint64} field, including tag. 501 */ 502 public static int computeSInt64Size(final int fieldNumber, final long value) { 503 return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value); 504 } 505 506 /** 507 * Compute the number of bytes that would be needed to encode a 508 * MessageSet extension to the stream. For historical reasons, 509 * the wire format differs from normal fields. 510 */ 511// public static int computeMessageSetExtensionSize( 512// final int fieldNumber, final MessageMicro value) { 513// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 + 514// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) + 515// computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value); 516// } 517 518 /** 519 * Compute the number of bytes that would be needed to encode an 520 * unparsed MessageSet extension field to the stream. For 521 * historical reasons, the wire format differs from normal fields. 522 */ 523// public static int computeRawMessageSetExtensionSize( 524// final int fieldNumber, final ByteStringMicro value) { 525// return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 + 526// computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) + 527// computeBytesSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value); 528// } 529 530 // ----------------------------------------------------------------- 531 532 /** 533 * Compute the number of bytes that would be needed to encode a 534 * {@code double} field, including tag. 535 */ 536 public static int computeDoubleSizeNoTag(final double value) { 537 return LITTLE_ENDIAN_64_SIZE; 538 } 539 540 /** 541 * Compute the number of bytes that would be needed to encode a 542 * {@code float} field, including tag. 543 */ 544 public static int computeFloatSizeNoTag(final float value) { 545 return LITTLE_ENDIAN_32_SIZE; 546 } 547 548 /** 549 * Compute the number of bytes that would be needed to encode a 550 * {@code uint64} field, including tag. 551 */ 552 public static int computeUInt64SizeNoTag(final long value) { 553 return computeRawVarint64Size(value); 554 } 555 556 /** 557 * Compute the number of bytes that would be needed to encode an 558 * {@code int64} field, including tag. 559 */ 560 public static int computeInt64SizeNoTag(final long value) { 561 return computeRawVarint64Size(value); 562 } 563 564 /** 565 * Compute the number of bytes that would be needed to encode an 566 * {@code int32} field, including tag. 567 */ 568 public static int computeInt32SizeNoTag(final int value) { 569 if (value >= 0) { 570 return computeRawVarint32Size(value); 571 } else { 572 // Must sign-extend. 573 return 10; 574 } 575 } 576 577 /** 578 * Compute the number of bytes that would be needed to encode a 579 * {@code fixed64} field. 580 */ 581 public static int computeFixed64SizeNoTag(final long value) { 582 return LITTLE_ENDIAN_64_SIZE; 583 } 584 585 /** 586 * Compute the number of bytes that would be needed to encode a 587 * {@code fixed32} field. 588 */ 589 public static int computeFixed32SizeNoTag(final int value) { 590 return LITTLE_ENDIAN_32_SIZE; 591 } 592 593 /** 594 * Compute the number of bytes that would be needed to encode a 595 * {@code bool} field. 596 */ 597 public static int computeBoolSizeNoTag(final boolean value) { 598 return 1; 599 } 600 601 /** 602 * Compute the number of bytes that would be needed to encode a 603 * {@code string} field. 604 */ 605 public static int computeStringSizeNoTag(final String value) { 606 try { 607 final byte[] bytes = value.getBytes("UTF-8"); 608 return computeRawVarint32Size(bytes.length) + 609 bytes.length; 610 } catch (UnsupportedEncodingException e) { 611 throw new RuntimeException("UTF-8 not supported."); 612 } 613 } 614 615 /** 616 * Compute the number of bytes that would be needed to encode a 617 * {@code group} field. 618 */ 619 public static int computeGroupSizeNoTag(final MessageNano value) { 620 return value.getSerializedSize(); 621 } 622 623 /** 624 * Compute the number of bytes that would be needed to encode an embedded 625 * message field. 626 */ 627 public static int computeMessageSizeNoTag(final MessageNano value) { 628 final int size = value.getSerializedSize(); 629 return computeRawVarint32Size(size) + size; 630 } 631 632 /** 633 * Compute the number of bytes that would be needed to encode a 634 * {@code bytes} field. 635 */ 636 public static int computeBytesSizeNoTag(final byte[] value) { 637 return computeRawVarint32Size(value.length) + value.length; 638 } 639 640 /** 641 * Compute the number of bytes that would be needed to encode a 642 * {@code uint32} field. 643 */ 644 public static int computeUInt32SizeNoTag(final int value) { 645 return computeRawVarint32Size(value); 646 } 647 648 /** 649 * Compute the number of bytes that would be needed to encode an enum field. 650 * Caller is responsible for converting the enum value to its numeric value. 651 */ 652 public static int computeEnumSizeNoTag(final int value) { 653 return computeRawVarint32Size(value); 654 } 655 656 /** 657 * Compute the number of bytes that would be needed to encode an 658 * {@code sfixed32} field. 659 */ 660 public static int computeSFixed32SizeNoTag(final int value) { 661 return LITTLE_ENDIAN_32_SIZE; 662 } 663 664 /** 665 * Compute the number of bytes that would be needed to encode an 666 * {@code sfixed64} field. 667 */ 668 public static int computeSFixed64SizeNoTag(final long value) { 669 return LITTLE_ENDIAN_64_SIZE; 670 } 671 672 /** 673 * Compute the number of bytes that would be needed to encode an 674 * {@code sint32} field. 675 */ 676 public static int computeSInt32SizeNoTag(final int value) { 677 return computeRawVarint32Size(encodeZigZag32(value)); 678 } 679 680 /** 681 * Compute the number of bytes that would be needed to encode an 682 * {@code sint64} field. 683 */ 684 public static int computeSInt64SizeNoTag(final long value) { 685 return computeRawVarint64Size(encodeZigZag64(value)); 686 } 687 688 // ================================================================= 689 690 /** 691 * If writing to a flat array, return the space left in the array. 692 * Otherwise, throws {@code UnsupportedOperationException}. 693 */ 694 public int spaceLeft() { 695 return limit - position; 696 } 697 698 /** 699 * Verifies that {@link #spaceLeft()} returns zero. It's common to create 700 * a byte array that is exactly big enough to hold a message, then write to 701 * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()} 702 * after writing verifies that the message was actually as big as expected, 703 * which can help catch bugs. 704 */ 705 public void checkNoSpaceLeft() { 706 if (spaceLeft() != 0) { 707 throw new IllegalStateException( 708 "Did not write as much data as expected."); 709 } 710 } 711 712 /** 713 * If you create a CodedOutputStream around a simple flat array, you must 714 * not attempt to write more bytes than the array has space. Otherwise, 715 * this exception will be thrown. 716 */ 717 public static class OutOfSpaceException extends IOException { 718 private static final long serialVersionUID = -6947486886997889499L; 719 720 OutOfSpaceException(int position, int limit) { 721 super("CodedOutputStream was writing to a flat byte array and ran " + 722 "out of space (pos " + position + " limit " + limit + ")."); 723 } 724 } 725 726 /** Write a single byte. */ 727 public void writeRawByte(final byte value) throws IOException { 728 if (position == limit) { 729 // We're writing to a single buffer. 730 throw new OutOfSpaceException(position, limit); 731 } 732 733 buffer[position++] = value; 734 } 735 736 /** Write a single byte, represented by an integer value. */ 737 public void writeRawByte(final int value) throws IOException { 738 writeRawByte((byte) value); 739 } 740 741 /** Write an array of bytes. */ 742 public void writeRawBytes(final byte[] value) throws IOException { 743 writeRawBytes(value, 0, value.length); 744 } 745 746 /** Write part of an array of bytes. */ 747 public void writeRawBytes(final byte[] value, int offset, int length) 748 throws IOException { 749 if (limit - position >= length) { 750 // We have room in the current buffer. 751 System.arraycopy(value, offset, buffer, position, length); 752 position += length; 753 } else { 754 // We're writing to a single buffer. 755 throw new OutOfSpaceException(position, limit); 756 } 757 } 758 759 /** Encode and write a tag. */ 760 public void writeTag(final int fieldNumber, final int wireType) 761 throws IOException { 762 writeRawVarint32(WireFormatNano.makeTag(fieldNumber, wireType)); 763 } 764 765 /** Compute the number of bytes that would be needed to encode a tag. */ 766 public static int computeTagSize(final int fieldNumber) { 767 return computeRawVarint32Size(WireFormatNano.makeTag(fieldNumber, 0)); 768 } 769 770 /** 771 * Encode and write a varint. {@code value} is treated as 772 * unsigned, so it won't be sign-extended if negative. 773 */ 774 public void writeRawVarint32(int value) throws IOException { 775 while (true) { 776 if ((value & ~0x7F) == 0) { 777 writeRawByte(value); 778 return; 779 } else { 780 writeRawByte((value & 0x7F) | 0x80); 781 value >>>= 7; 782 } 783 } 784 } 785 786 /** 787 * Compute the number of bytes that would be needed to encode a varint. 788 * {@code value} is treated as unsigned, so it won't be sign-extended if 789 * negative. 790 */ 791 public static int computeRawVarint32Size(final int value) { 792 if ((value & (0xffffffff << 7)) == 0) return 1; 793 if ((value & (0xffffffff << 14)) == 0) return 2; 794 if ((value & (0xffffffff << 21)) == 0) return 3; 795 if ((value & (0xffffffff << 28)) == 0) return 4; 796 return 5; 797 } 798 799 /** Encode and write a varint. */ 800 public void writeRawVarint64(long value) throws IOException { 801 while (true) { 802 if ((value & ~0x7FL) == 0) { 803 writeRawByte((int)value); 804 return; 805 } else { 806 writeRawByte(((int)value & 0x7F) | 0x80); 807 value >>>= 7; 808 } 809 } 810 } 811 812 /** Compute the number of bytes that would be needed to encode a varint. */ 813 public static int computeRawVarint64Size(final long value) { 814 if ((value & (0xffffffffffffffffL << 7)) == 0) return 1; 815 if ((value & (0xffffffffffffffffL << 14)) == 0) return 2; 816 if ((value & (0xffffffffffffffffL << 21)) == 0) return 3; 817 if ((value & (0xffffffffffffffffL << 28)) == 0) return 4; 818 if ((value & (0xffffffffffffffffL << 35)) == 0) return 5; 819 if ((value & (0xffffffffffffffffL << 42)) == 0) return 6; 820 if ((value & (0xffffffffffffffffL << 49)) == 0) return 7; 821 if ((value & (0xffffffffffffffffL << 56)) == 0) return 8; 822 if ((value & (0xffffffffffffffffL << 63)) == 0) return 9; 823 return 10; 824 } 825 826 /** Write a little-endian 32-bit integer. */ 827 public void writeRawLittleEndian32(final int value) throws IOException { 828 writeRawByte((value ) & 0xFF); 829 writeRawByte((value >> 8) & 0xFF); 830 writeRawByte((value >> 16) & 0xFF); 831 writeRawByte((value >> 24) & 0xFF); 832 } 833 834 public static final int LITTLE_ENDIAN_32_SIZE = 4; 835 836 /** Write a little-endian 64-bit integer. */ 837 public void writeRawLittleEndian64(final long value) throws IOException { 838 writeRawByte((int)(value ) & 0xFF); 839 writeRawByte((int)(value >> 8) & 0xFF); 840 writeRawByte((int)(value >> 16) & 0xFF); 841 writeRawByte((int)(value >> 24) & 0xFF); 842 writeRawByte((int)(value >> 32) & 0xFF); 843 writeRawByte((int)(value >> 40) & 0xFF); 844 writeRawByte((int)(value >> 48) & 0xFF); 845 writeRawByte((int)(value >> 56) & 0xFF); 846 } 847 848 public static final int LITTLE_ENDIAN_64_SIZE = 8; 849 850 /** 851 * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers 852 * into values that can be efficiently encoded with varint. (Otherwise, 853 * negative values must be sign-extended to 64 bits to be varint encoded, 854 * thus always taking 10 bytes on the wire.) 855 * 856 * @param n A signed 32-bit integer. 857 * @return An unsigned 32-bit integer, stored in a signed int because 858 * Java has no explicit unsigned support. 859 */ 860 public static int encodeZigZag32(final int n) { 861 // Note: the right-shift must be arithmetic 862 return (n << 1) ^ (n >> 31); 863 } 864 865 /** 866 * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers 867 * into values that can be efficiently encoded with varint. (Otherwise, 868 * negative values must be sign-extended to 64 bits to be varint encoded, 869 * thus always taking 10 bytes on the wire.) 870 * 871 * @param n A signed 64-bit integer. 872 * @return An unsigned 64-bit integer, stored in a signed int because 873 * Java has no explicit unsigned support. 874 */ 875 public static long encodeZigZag64(final long n) { 876 // Note: the right-shift must be arithmetic 877 return (n << 1) ^ (n >> 63); 878 } 879} 880