1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 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.IOException; 34 import java.io.OutputStream; 35 import java.io.UnsupportedEncodingException; 36 import java.nio.ByteBuffer; 37 38 /** 39 * Encodes and writes protocol message fields. 40 * 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. 47 * 48 * <p>This class is totally unsynchronized. 49 * 50 * @author kneton@google.com Kenton Varda 51 */ 52 public final class CodedOutputStream { 53 private final byte[] buffer; 54 private final int limit; 55 private int position; 56 private int totalBytesWritten = 0; 57 58 private final OutputStream output; 59 60 /** 61 * The buffer size used in {@link #newInstance(OutputStream)}. 62 */ 63 public static final int DEFAULT_BUFFER_SIZE = 4096; 64 65 /** 66 * Returns the buffer size to efficiently write dataLength bytes to this 67 * CodedOutputStream. Used by AbstractMessageLite. 68 * 69 * @return the buffer size to efficiently write dataLength bytes to this 70 * CodedOutputStream. 71 */ computePreferredBufferSize(int dataLength)72 static int computePreferredBufferSize(int dataLength) { 73 if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE; 74 return dataLength; 75 } 76 CodedOutputStream(final byte[] buffer, final int offset, final int length)77 private CodedOutputStream(final byte[] buffer, final int offset, 78 final int length) { 79 output = null; 80 this.buffer = buffer; 81 position = offset; 82 limit = offset + length; 83 } 84 CodedOutputStream(final OutputStream output, final byte[] buffer)85 private CodedOutputStream(final OutputStream output, final byte[] buffer) { 86 this.output = output; 87 this.buffer = buffer; 88 position = 0; 89 limit = buffer.length; 90 } 91 92 /** 93 * Create a new {@code CodedOutputStream} wrapping the given 94 * {@code OutputStream}. 95 */ newInstance(final OutputStream output)96 public static CodedOutputStream newInstance(final OutputStream output) { 97 return newInstance(output, DEFAULT_BUFFER_SIZE); 98 } 99 100 /** 101 * Create a new {@code CodedOutputStream} wrapping the given 102 * {@code OutputStream} with a given buffer size. 103 */ newInstance(final OutputStream output, final int bufferSize)104 public static CodedOutputStream newInstance(final OutputStream output, 105 final int bufferSize) { 106 return new CodedOutputStream(output, new byte[bufferSize]); 107 } 108 109 /** 110 * Create a new {@code CodedOutputStream} that writes directly to the given 111 * byte array. If more bytes are written than fit in the array, 112 * {@link OutOfSpaceException} will be thrown. Writing directly to a flat 113 * array is faster than writing to an {@code OutputStream}. See also 114 * {@link ByteString#newCodedBuilder}. 115 */ newInstance(final byte[] flatArray)116 public static CodedOutputStream newInstance(final byte[] flatArray) { 117 return newInstance(flatArray, 0, flatArray.length); 118 } 119 120 /** 121 * Create a new {@code CodedOutputStream} that writes directly to the given 122 * byte array slice. If more bytes are written than fit in the slice, 123 * {@link OutOfSpaceException} will be thrown. Writing directly to a flat 124 * array is faster than writing to an {@code OutputStream}. See also 125 * {@link ByteString#newCodedBuilder}. 126 */ newInstance(final byte[] flatArray, final int offset, final int length)127 public static CodedOutputStream newInstance(final byte[] flatArray, 128 final int offset, 129 final int length) { 130 return new CodedOutputStream(flatArray, offset, length); 131 } 132 133 /** 134 * Create a new {@code CodedOutputStream} that writes to the given ByteBuffer. 135 */ newInstance(ByteBuffer byteBuffer)136 public static CodedOutputStream newInstance(ByteBuffer byteBuffer) { 137 return newInstance(byteBuffer, DEFAULT_BUFFER_SIZE); 138 } 139 140 /** 141 * Create a new {@code CodedOutputStream} that writes to the given ByteBuffer. 142 */ newInstance(ByteBuffer byteBuffer, int bufferSize)143 public static CodedOutputStream newInstance(ByteBuffer byteBuffer, 144 int bufferSize) { 145 return newInstance(new ByteBufferOutputStream(byteBuffer), bufferSize); 146 } 147 148 private static class ByteBufferOutputStream extends OutputStream { 149 private final ByteBuffer byteBuffer; ByteBufferOutputStream(ByteBuffer byteBuffer)150 public ByteBufferOutputStream(ByteBuffer byteBuffer) { 151 this.byteBuffer = byteBuffer; 152 } 153 154 @Override write(int b)155 public void write(int b) throws IOException { 156 byteBuffer.put((byte) b); 157 } 158 159 @Override write(byte[] data, int offset, int length)160 public void write(byte[] data, int offset, int length) throws IOException { 161 byteBuffer.put(data, offset, length); 162 } 163 } 164 165 // ----------------------------------------------------------------- 166 167 /** Write a {@code double} field, including tag, to the stream. */ writeDouble(final int fieldNumber, final double value)168 public void writeDouble(final int fieldNumber, final double value) 169 throws IOException { 170 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64); 171 writeDoubleNoTag(value); 172 } 173 174 /** Write a {@code float} field, including tag, to the stream. */ writeFloat(final int fieldNumber, final float value)175 public void writeFloat(final int fieldNumber, final float value) 176 throws IOException { 177 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32); 178 writeFloatNoTag(value); 179 } 180 181 /** Write a {@code uint64} field, including tag, to the stream. */ writeUInt64(final int fieldNumber, final long value)182 public void writeUInt64(final int fieldNumber, final long value) 183 throws IOException { 184 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); 185 writeUInt64NoTag(value); 186 } 187 188 /** Write an {@code int64} field, including tag, to the stream. */ writeInt64(final int fieldNumber, final long value)189 public void writeInt64(final int fieldNumber, final long value) 190 throws IOException { 191 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); 192 writeInt64NoTag(value); 193 } 194 195 /** Write an {@code int32} field, including tag, to the stream. */ writeInt32(final int fieldNumber, final int value)196 public void writeInt32(final int fieldNumber, final int value) 197 throws IOException { 198 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); 199 writeInt32NoTag(value); 200 } 201 202 /** Write a {@code fixed64} field, including tag, to the stream. */ writeFixed64(final int fieldNumber, final long value)203 public void writeFixed64(final int fieldNumber, final long value) 204 throws IOException { 205 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64); 206 writeFixed64NoTag(value); 207 } 208 209 /** Write a {@code fixed32} field, including tag, to the stream. */ writeFixed32(final int fieldNumber, final int value)210 public void writeFixed32(final int fieldNumber, final int value) 211 throws IOException { 212 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32); 213 writeFixed32NoTag(value); 214 } 215 216 /** Write a {@code bool} field, including tag, to the stream. */ writeBool(final int fieldNumber, final boolean value)217 public void writeBool(final int fieldNumber, final boolean value) 218 throws IOException { 219 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); 220 writeBoolNoTag(value); 221 } 222 223 /** Write a {@code string} field, including tag, to the stream. */ writeString(final int fieldNumber, final String value)224 public void writeString(final int fieldNumber, final String value) 225 throws IOException { 226 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED); 227 writeStringNoTag(value); 228 } 229 230 /** Write a {@code group} field, including tag, to the stream. */ writeGroup(final int fieldNumber, final MessageLite value)231 public void writeGroup(final int fieldNumber, final MessageLite value) 232 throws IOException { 233 writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP); 234 writeGroupNoTag(value); 235 writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP); 236 } 237 238 239 /** 240 * Write a group represented by an {@link UnknownFieldSet}. 241 * 242 * @deprecated UnknownFieldSet now implements MessageLite, so you can just 243 * call {@link #writeGroup}. 244 */ 245 @Deprecated writeUnknownGroup(final int fieldNumber, final MessageLite value)246 public void writeUnknownGroup(final int fieldNumber, 247 final MessageLite value) 248 throws IOException { 249 writeGroup(fieldNumber, value); 250 } 251 252 /** Write an embedded message field, including tag, to the stream. */ writeMessage(final int fieldNumber, final MessageLite value)253 public void writeMessage(final int fieldNumber, final MessageLite value) 254 throws IOException { 255 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED); 256 writeMessageNoTag(value); 257 } 258 259 260 /** Write a {@code bytes} field, including tag, to the stream. */ writeBytes(final int fieldNumber, final ByteString value)261 public void writeBytes(final int fieldNumber, final ByteString value) 262 throws IOException { 263 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED); 264 writeBytesNoTag(value); 265 } 266 267 /** Write a {@code bytes} field, including tag, to the stream. */ writeByteArray(final int fieldNumber, final byte[] value)268 public void writeByteArray(final int fieldNumber, final byte[] value) 269 throws IOException { 270 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED); 271 writeByteArrayNoTag(value); 272 } 273 274 /** Write a {@code bytes} field, including tag, to the stream. */ writeByteArray(final int fieldNumber, final byte[] value, final int offset, final int length)275 public void writeByteArray(final int fieldNumber, 276 final byte[] value, 277 final int offset, 278 final int length) 279 throws IOException { 280 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED); 281 writeByteArrayNoTag(value, offset, length); 282 } 283 284 /** 285 * Write a {@code bytes} field, including tag, to the stream. 286 * This method will write all content of the ByteBuffer regardless of the 287 * current position and limit (i.e., the number of bytes to be written is 288 * value.capacity(), not value.remaining()). Furthermore, this method doesn't 289 * alter the state of the passed-in ByteBuffer. Its position, limit, mark, 290 * etc. will remain unchanged. If you only want to write the remaining bytes 291 * of a ByteBuffer, you can call 292 * {@code writeByteBuffer(fieldNumber, byteBuffer.slice())}. 293 */ writeByteBuffer(final int fieldNumber, final ByteBuffer value)294 public void writeByteBuffer(final int fieldNumber, final ByteBuffer value) 295 throws IOException { 296 writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED); 297 writeByteBufferNoTag(value); 298 } 299 300 /** Write a {@code uint32} field, including tag, to the stream. */ writeUInt32(final int fieldNumber, final int value)301 public void writeUInt32(final int fieldNumber, final int value) 302 throws IOException { 303 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); 304 writeUInt32NoTag(value); 305 } 306 307 /** 308 * Write an enum field, including tag, to the stream. Caller is responsible 309 * for converting the enum value to its numeric value. 310 */ writeEnum(final int fieldNumber, final int value)311 public void writeEnum(final int fieldNumber, final int value) 312 throws IOException { 313 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); 314 writeEnumNoTag(value); 315 } 316 317 /** Write an {@code sfixed32} field, including tag, to the stream. */ writeSFixed32(final int fieldNumber, final int value)318 public void writeSFixed32(final int fieldNumber, final int value) 319 throws IOException { 320 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32); 321 writeSFixed32NoTag(value); 322 } 323 324 /** Write an {@code sfixed64} field, including tag, to the stream. */ writeSFixed64(final int fieldNumber, final long value)325 public void writeSFixed64(final int fieldNumber, final long value) 326 throws IOException { 327 writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64); 328 writeSFixed64NoTag(value); 329 } 330 331 /** Write an {@code sint32} field, including tag, to the stream. */ writeSInt32(final int fieldNumber, final int value)332 public void writeSInt32(final int fieldNumber, final int value) 333 throws IOException { 334 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); 335 writeSInt32NoTag(value); 336 } 337 338 /** Write an {@code sint64} field, including tag, to the stream. */ writeSInt64(final int fieldNumber, final long value)339 public void writeSInt64(final int fieldNumber, final long value) 340 throws IOException { 341 writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT); 342 writeSInt64NoTag(value); 343 } 344 345 /** 346 * Write a MessageSet extension field to the stream. For historical reasons, 347 * the wire format differs from normal fields. 348 */ writeMessageSetExtension(final int fieldNumber, final MessageLite value)349 public void writeMessageSetExtension(final int fieldNumber, 350 final MessageLite value) 351 throws IOException { 352 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP); 353 writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber); 354 writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value); 355 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP); 356 } 357 358 /** 359 * Write an unparsed MessageSet extension field to the stream. For 360 * historical reasons, the wire format differs from normal fields. 361 */ writeRawMessageSetExtension(final int fieldNumber, final ByteString value)362 public void writeRawMessageSetExtension(final int fieldNumber, 363 final ByteString value) 364 throws IOException { 365 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP); 366 writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber); 367 writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value); 368 writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP); 369 } 370 371 // ----------------------------------------------------------------- 372 373 /** Write a {@code double} field to the stream. */ writeDoubleNoTag(final double value)374 public void writeDoubleNoTag(final double value) throws IOException { 375 writeRawLittleEndian64(Double.doubleToRawLongBits(value)); 376 } 377 378 /** Write a {@code float} field to the stream. */ writeFloatNoTag(final float value)379 public void writeFloatNoTag(final float value) throws IOException { 380 writeRawLittleEndian32(Float.floatToRawIntBits(value)); 381 } 382 383 /** Write a {@code uint64} field to the stream. */ writeUInt64NoTag(final long value)384 public void writeUInt64NoTag(final long value) throws IOException { 385 writeRawVarint64(value); 386 } 387 388 /** Write an {@code int64} field to the stream. */ writeInt64NoTag(final long value)389 public void writeInt64NoTag(final long value) throws IOException { 390 writeRawVarint64(value); 391 } 392 393 /** Write an {@code int32} field to the stream. */ writeInt32NoTag(final int value)394 public void writeInt32NoTag(final int value) throws IOException { 395 if (value >= 0) { 396 writeRawVarint32(value); 397 } else { 398 // Must sign-extend. 399 writeRawVarint64(value); 400 } 401 } 402 403 /** Write a {@code fixed64} field to the stream. */ writeFixed64NoTag(final long value)404 public void writeFixed64NoTag(final long value) throws IOException { 405 writeRawLittleEndian64(value); 406 } 407 408 /** Write a {@code fixed32} field to the stream. */ writeFixed32NoTag(final int value)409 public void writeFixed32NoTag(final int value) throws IOException { 410 writeRawLittleEndian32(value); 411 } 412 413 /** Write a {@code bool} field to the stream. */ writeBoolNoTag(final boolean value)414 public void writeBoolNoTag(final boolean value) throws IOException { 415 writeRawByte(value ? 1 : 0); 416 } 417 418 /** Write a {@code string} field to the stream. */ writeStringNoTag(final String value)419 public void writeStringNoTag(final String value) throws IOException { 420 // Unfortunately there does not appear to be any way to tell Java to encode 421 // UTF-8 directly into our buffer, so we have to let it create its own byte 422 // array and then copy. 423 final byte[] bytes = value.getBytes("UTF-8"); 424 writeRawVarint32(bytes.length); 425 writeRawBytes(bytes); 426 } 427 428 /** Write a {@code group} field to the stream. */ writeGroupNoTag(final MessageLite value)429 public void writeGroupNoTag(final MessageLite value) throws IOException { 430 value.writeTo(this); 431 } 432 433 434 /** 435 * Write a group represented by an {@link UnknownFieldSet}. 436 * 437 * @deprecated UnknownFieldSet now implements MessageLite, so you can just 438 * call {@link #writeGroupNoTag}. 439 */ 440 @Deprecated writeUnknownGroupNoTag(final MessageLite value)441 public void writeUnknownGroupNoTag(final MessageLite value) 442 throws IOException { 443 writeGroupNoTag(value); 444 } 445 446 /** Write an embedded message field to the stream. */ writeMessageNoTag(final MessageLite value)447 public void writeMessageNoTag(final MessageLite value) throws IOException { 448 writeRawVarint32(value.getSerializedSize()); 449 value.writeTo(this); 450 } 451 452 453 /** Write a {@code bytes} field to the stream. */ writeBytesNoTag(final ByteString value)454 public void writeBytesNoTag(final ByteString value) throws IOException { 455 writeRawVarint32(value.size()); 456 writeRawBytes(value); 457 } 458 459 /** Write a {@code bytes} field to the stream. */ writeByteArrayNoTag(final byte[] value)460 public void writeByteArrayNoTag(final byte[] value) throws IOException { 461 writeRawVarint32(value.length); 462 writeRawBytes(value); 463 } 464 465 /** Write a {@code bytes} field to the stream. */ writeByteArrayNoTag(final byte[] value, final int offset, final int length)466 public void writeByteArrayNoTag(final byte[] value, 467 final int offset, 468 final int length) throws IOException { 469 writeRawVarint32(length); 470 writeRawBytes(value, offset, length); 471 } 472 473 /** 474 * Write a {@code bytes} field to the stream. This method will write all 475 * content of the ByteBuffer regardless of the current position and limit 476 * (i.e., the number of bytes to be written is value.capacity(), not 477 * value.remaining()). Furthermore, this method doesn't alter the state of 478 * the passed-in ByteBuffer. Its position, limit, mark, etc. will remain 479 * unchanged. If you only want to write the remaining bytes of a ByteBuffer, 480 * you can call {@code writeByteBufferNoTag(byteBuffer.slice())}. 481 */ writeByteBufferNoTag(final ByteBuffer value)482 public void writeByteBufferNoTag(final ByteBuffer value) throws IOException { 483 writeRawVarint32(value.capacity()); 484 writeRawBytes(value); 485 } 486 487 /** Write a {@code uint32} field to the stream. */ writeUInt32NoTag(final int value)488 public void writeUInt32NoTag(final int value) throws IOException { 489 writeRawVarint32(value); 490 } 491 492 /** 493 * Write an enum field to the stream. Caller is responsible 494 * for converting the enum value to its numeric value. 495 */ writeEnumNoTag(final int value)496 public void writeEnumNoTag(final int value) throws IOException { 497 writeInt32NoTag(value); 498 } 499 500 /** Write an {@code sfixed32} field to the stream. */ writeSFixed32NoTag(final int value)501 public void writeSFixed32NoTag(final int value) throws IOException { 502 writeRawLittleEndian32(value); 503 } 504 505 /** Write an {@code sfixed64} field to the stream. */ writeSFixed64NoTag(final long value)506 public void writeSFixed64NoTag(final long value) throws IOException { 507 writeRawLittleEndian64(value); 508 } 509 510 /** Write an {@code sint32} field to the stream. */ writeSInt32NoTag(final int value)511 public void writeSInt32NoTag(final int value) throws IOException { 512 writeRawVarint32(encodeZigZag32(value)); 513 } 514 515 /** Write an {@code sint64} field to the stream. */ writeSInt64NoTag(final long value)516 public void writeSInt64NoTag(final long value) throws IOException { 517 writeRawVarint64(encodeZigZag64(value)); 518 } 519 520 // ================================================================= 521 522 /** 523 * Compute the number of bytes that would be needed to encode a 524 * {@code double} field, including tag. 525 */ computeDoubleSize(final int fieldNumber, final double value)526 public static int computeDoubleSize(final int fieldNumber, 527 final double value) { 528 return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value); 529 } 530 531 /** 532 * Compute the number of bytes that would be needed to encode a 533 * {@code float} field, including tag. 534 */ computeFloatSize(final int fieldNumber, final float value)535 public static int computeFloatSize(final int fieldNumber, final float value) { 536 return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value); 537 } 538 539 /** 540 * Compute the number of bytes that would be needed to encode a 541 * {@code uint64} field, including tag. 542 */ computeUInt64Size(final int fieldNumber, final long value)543 public static int computeUInt64Size(final int fieldNumber, final long value) { 544 return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value); 545 } 546 547 /** 548 * Compute the number of bytes that would be needed to encode an 549 * {@code int64} field, including tag. 550 */ computeInt64Size(final int fieldNumber, final long value)551 public static int computeInt64Size(final int fieldNumber, final long value) { 552 return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value); 553 } 554 555 /** 556 * Compute the number of bytes that would be needed to encode an 557 * {@code int32} field, including tag. 558 */ computeInt32Size(final int fieldNumber, final int value)559 public static int computeInt32Size(final int fieldNumber, final int value) { 560 return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value); 561 } 562 563 /** 564 * Compute the number of bytes that would be needed to encode a 565 * {@code fixed64} field, including tag. 566 */ computeFixed64Size(final int fieldNumber, final long value)567 public static int computeFixed64Size(final int fieldNumber, 568 final long value) { 569 return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value); 570 } 571 572 /** 573 * Compute the number of bytes that would be needed to encode a 574 * {@code fixed32} field, including tag. 575 */ computeFixed32Size(final int fieldNumber, final int value)576 public static int computeFixed32Size(final int fieldNumber, 577 final int value) { 578 return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value); 579 } 580 581 /** 582 * Compute the number of bytes that would be needed to encode a 583 * {@code bool} field, including tag. 584 */ computeBoolSize(final int fieldNumber, final boolean value)585 public static int computeBoolSize(final int fieldNumber, 586 final boolean value) { 587 return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value); 588 } 589 590 /** 591 * Compute the number of bytes that would be needed to encode a 592 * {@code string} field, including tag. 593 */ computeStringSize(final int fieldNumber, final String value)594 public static int computeStringSize(final int fieldNumber, 595 final String value) { 596 return computeTagSize(fieldNumber) + computeStringSizeNoTag(value); 597 } 598 599 /** 600 * Compute the number of bytes that would be needed to encode a 601 * {@code group} field, including tag. 602 */ computeGroupSize(final int fieldNumber, final MessageLite value)603 public static int computeGroupSize(final int fieldNumber, 604 final MessageLite value) { 605 return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value); 606 } 607 608 /** 609 * Compute the number of bytes that would be needed to encode a 610 * {@code group} field represented by an {@code UnknownFieldSet}, including 611 * tag. 612 * 613 * @deprecated UnknownFieldSet now implements MessageLite, so you can just 614 * call {@link #computeGroupSize}. 615 */ 616 @Deprecated computeUnknownGroupSize(final int fieldNumber, final MessageLite value)617 public static int computeUnknownGroupSize(final int fieldNumber, 618 final MessageLite value) { 619 return computeGroupSize(fieldNumber, value); 620 } 621 622 /** 623 * Compute the number of bytes that would be needed to encode an 624 * embedded message field, including tag. 625 */ computeMessageSize(final int fieldNumber, final MessageLite value)626 public static int computeMessageSize(final int fieldNumber, 627 final MessageLite value) { 628 return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value); 629 } 630 631 /** 632 * Compute the number of bytes that would be needed to encode a 633 * {@code bytes} field, including tag. 634 */ computeBytesSize(final int fieldNumber, final ByteString value)635 public static int computeBytesSize(final int fieldNumber, 636 final ByteString value) { 637 return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value); 638 } 639 640 /** 641 * Compute the number of bytes that would be needed to encode a 642 * {@code bytes} field, including tag. 643 */ computeByteArraySize(final int fieldNumber, final byte[] value)644 public static int computeByteArraySize(final int fieldNumber, 645 final byte[] value) { 646 return computeTagSize(fieldNumber) + computeByteArraySizeNoTag(value); 647 } 648 649 /** 650 * Compute the number of bytes that would be needed to encode a 651 * {@code bytes} field, including tag. 652 */ computeByteBufferSize(final int fieldNumber, final ByteBuffer value)653 public static int computeByteBufferSize(final int fieldNumber, 654 final ByteBuffer value) { 655 return computeTagSize(fieldNumber) + computeByteBufferSizeNoTag(value); 656 } 657 658 /** 659 * Compute the number of bytes that would be needed to encode an 660 * embedded message in lazy field, including tag. 661 */ computeLazyFieldSize(final int fieldNumber, final LazyFieldLite value)662 public static int computeLazyFieldSize(final int fieldNumber, 663 final LazyFieldLite value) { 664 return computeTagSize(fieldNumber) + computeLazyFieldSizeNoTag(value); 665 } 666 667 /** 668 * Compute the number of bytes that would be needed to encode a 669 * {@code uint32} field, including tag. 670 */ computeUInt32Size(final int fieldNumber, final int value)671 public static int computeUInt32Size(final int fieldNumber, final int value) { 672 return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value); 673 } 674 675 /** 676 * Compute the number of bytes that would be needed to encode an 677 * enum field, including tag. Caller is responsible for converting the 678 * enum value to its numeric value. 679 */ computeEnumSize(final int fieldNumber, final int value)680 public static int computeEnumSize(final int fieldNumber, final int value) { 681 return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value); 682 } 683 684 /** 685 * Compute the number of bytes that would be needed to encode an 686 * {@code sfixed32} field, including tag. 687 */ computeSFixed32Size(final int fieldNumber, final int value)688 public static int computeSFixed32Size(final int fieldNumber, 689 final int value) { 690 return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value); 691 } 692 693 /** 694 * Compute the number of bytes that would be needed to encode an 695 * {@code sfixed64} field, including tag. 696 */ computeSFixed64Size(final int fieldNumber, final long value)697 public static int computeSFixed64Size(final int fieldNumber, 698 final long value) { 699 return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value); 700 } 701 702 /** 703 * Compute the number of bytes that would be needed to encode an 704 * {@code sint32} field, including tag. 705 */ computeSInt32Size(final int fieldNumber, final int value)706 public static int computeSInt32Size(final int fieldNumber, final int value) { 707 return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value); 708 } 709 710 /** 711 * Compute the number of bytes that would be needed to encode an 712 * {@code sint64} field, including tag. 713 */ computeSInt64Size(final int fieldNumber, final long value)714 public static int computeSInt64Size(final int fieldNumber, final long value) { 715 return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value); 716 } 717 718 /** 719 * Compute the number of bytes that would be needed to encode a 720 * MessageSet extension to the stream. For historical reasons, 721 * the wire format differs from normal fields. 722 */ computeMessageSetExtensionSize( final int fieldNumber, final MessageLite value)723 public static int computeMessageSetExtensionSize( 724 final int fieldNumber, final MessageLite value) { 725 return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 + 726 computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) + 727 computeMessageSize(WireFormat.MESSAGE_SET_MESSAGE, value); 728 } 729 730 /** 731 * Compute the number of bytes that would be needed to encode an 732 * unparsed MessageSet extension field to the stream. For 733 * historical reasons, the wire format differs from normal fields. 734 */ computeRawMessageSetExtensionSize( final int fieldNumber, final ByteString value)735 public static int computeRawMessageSetExtensionSize( 736 final int fieldNumber, final ByteString value) { 737 return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 + 738 computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) + 739 computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value); 740 } 741 742 /** 743 * Compute the number of bytes that would be needed to encode an 744 * lazily parsed MessageSet extension field to the stream. For 745 * historical reasons, the wire format differs from normal fields. 746 */ computeLazyFieldMessageSetExtensionSize( final int fieldNumber, final LazyFieldLite value)747 public static int computeLazyFieldMessageSetExtensionSize( 748 final int fieldNumber, final LazyFieldLite value) { 749 return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 + 750 computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) + 751 computeLazyFieldSize(WireFormat.MESSAGE_SET_MESSAGE, value); 752 } 753 754 // ----------------------------------------------------------------- 755 756 /** 757 * Compute the number of bytes that would be needed to encode a 758 * {@code double} field, including tag. 759 */ computeDoubleSizeNoTag(final double value)760 public static int computeDoubleSizeNoTag(final double value) { 761 return LITTLE_ENDIAN_64_SIZE; 762 } 763 764 /** 765 * Compute the number of bytes that would be needed to encode a 766 * {@code float} field, including tag. 767 */ computeFloatSizeNoTag(final float value)768 public static int computeFloatSizeNoTag(final float value) { 769 return LITTLE_ENDIAN_32_SIZE; 770 } 771 772 /** 773 * Compute the number of bytes that would be needed to encode a 774 * {@code uint64} field, including tag. 775 */ computeUInt64SizeNoTag(final long value)776 public static int computeUInt64SizeNoTag(final long value) { 777 return computeRawVarint64Size(value); 778 } 779 780 /** 781 * Compute the number of bytes that would be needed to encode an 782 * {@code int64} field, including tag. 783 */ computeInt64SizeNoTag(final long value)784 public static int computeInt64SizeNoTag(final long value) { 785 return computeRawVarint64Size(value); 786 } 787 788 /** 789 * Compute the number of bytes that would be needed to encode an 790 * {@code int32} field, including tag. 791 */ computeInt32SizeNoTag(final int value)792 public static int computeInt32SizeNoTag(final int value) { 793 if (value >= 0) { 794 return computeRawVarint32Size(value); 795 } else { 796 // Must sign-extend. 797 return 10; 798 } 799 } 800 801 /** 802 * Compute the number of bytes that would be needed to encode a 803 * {@code fixed64} field. 804 */ computeFixed64SizeNoTag(final long value)805 public static int computeFixed64SizeNoTag(final long value) { 806 return LITTLE_ENDIAN_64_SIZE; 807 } 808 809 /** 810 * Compute the number of bytes that would be needed to encode a 811 * {@code fixed32} field. 812 */ computeFixed32SizeNoTag(final int value)813 public static int computeFixed32SizeNoTag(final int value) { 814 return LITTLE_ENDIAN_32_SIZE; 815 } 816 817 /** 818 * Compute the number of bytes that would be needed to encode a 819 * {@code bool} field. 820 */ computeBoolSizeNoTag(final boolean value)821 public static int computeBoolSizeNoTag(final boolean value) { 822 return 1; 823 } 824 825 /** 826 * Compute the number of bytes that would be needed to encode a 827 * {@code string} field. 828 */ computeStringSizeNoTag(final String value)829 public static int computeStringSizeNoTag(final String value) { 830 try { 831 final byte[] bytes = value.getBytes("UTF-8"); 832 return computeRawVarint32Size(bytes.length) + 833 bytes.length; 834 } catch (UnsupportedEncodingException e) { 835 throw new RuntimeException("UTF-8 not supported.", e); 836 } 837 } 838 839 /** 840 * Compute the number of bytes that would be needed to encode a 841 * {@code group} field. 842 */ computeGroupSizeNoTag(final MessageLite value)843 public static int computeGroupSizeNoTag(final MessageLite value) { 844 return value.getSerializedSize(); 845 } 846 847 /** 848 * Compute the number of bytes that would be needed to encode a 849 * {@code group} field represented by an {@code UnknownFieldSet}, including 850 * tag. 851 * 852 * @deprecated UnknownFieldSet now implements MessageLite, so you can just 853 * call {@link #computeUnknownGroupSizeNoTag}. 854 */ 855 @Deprecated computeUnknownGroupSizeNoTag(final MessageLite value)856 public static int computeUnknownGroupSizeNoTag(final MessageLite value) { 857 return computeGroupSizeNoTag(value); 858 } 859 860 /** 861 * Compute the number of bytes that would be needed to encode an embedded 862 * message field. 863 */ computeMessageSizeNoTag(final MessageLite value)864 public static int computeMessageSizeNoTag(final MessageLite value) { 865 final int size = value.getSerializedSize(); 866 return computeRawVarint32Size(size) + size; 867 } 868 869 /** 870 * Compute the number of bytes that would be needed to encode an embedded 871 * message stored in lazy field. 872 */ computeLazyFieldSizeNoTag(final LazyFieldLite value)873 public static int computeLazyFieldSizeNoTag(final LazyFieldLite value) { 874 final int size = value.getSerializedSize(); 875 return computeRawVarint32Size(size) + size; 876 } 877 878 /** 879 * Compute the number of bytes that would be needed to encode a 880 * {@code bytes} field. 881 */ computeBytesSizeNoTag(final ByteString value)882 public static int computeBytesSizeNoTag(final ByteString value) { 883 return computeRawVarint32Size(value.size()) + 884 value.size(); 885 } 886 887 /** 888 * Compute the number of bytes that would be needed to encode a 889 * {@code bytes} field. 890 */ computeByteArraySizeNoTag(final byte[] value)891 public static int computeByteArraySizeNoTag(final byte[] value) { 892 return computeRawVarint32Size(value.length) + value.length; 893 } 894 895 /** 896 * Compute the number of bytes that would be needed to encode a 897 * {@code bytes} field. 898 */ computeByteBufferSizeNoTag(final ByteBuffer value)899 public static int computeByteBufferSizeNoTag(final ByteBuffer value) { 900 return computeRawVarint32Size(value.capacity()) + value.capacity(); 901 } 902 903 /** 904 * Compute the number of bytes that would be needed to encode a 905 * {@code uint32} field. 906 */ computeUInt32SizeNoTag(final int value)907 public static int computeUInt32SizeNoTag(final int value) { 908 return computeRawVarint32Size(value); 909 } 910 911 /** 912 * Compute the number of bytes that would be needed to encode an enum field. 913 * Caller is responsible for converting the enum value to its numeric value. 914 */ computeEnumSizeNoTag(final int value)915 public static int computeEnumSizeNoTag(final int value) { 916 return computeInt32SizeNoTag(value); 917 } 918 919 /** 920 * Compute the number of bytes that would be needed to encode an 921 * {@code sfixed32} field. 922 */ computeSFixed32SizeNoTag(final int value)923 public static int computeSFixed32SizeNoTag(final int value) { 924 return LITTLE_ENDIAN_32_SIZE; 925 } 926 927 /** 928 * Compute the number of bytes that would be needed to encode an 929 * {@code sfixed64} field. 930 */ computeSFixed64SizeNoTag(final long value)931 public static int computeSFixed64SizeNoTag(final long value) { 932 return LITTLE_ENDIAN_64_SIZE; 933 } 934 935 /** 936 * Compute the number of bytes that would be needed to encode an 937 * {@code sint32} field. 938 */ computeSInt32SizeNoTag(final int value)939 public static int computeSInt32SizeNoTag(final int value) { 940 return computeRawVarint32Size(encodeZigZag32(value)); 941 } 942 943 /** 944 * Compute the number of bytes that would be needed to encode an 945 * {@code sint64} field. 946 */ computeSInt64SizeNoTag(final long value)947 public static int computeSInt64SizeNoTag(final long value) { 948 return computeRawVarint64Size(encodeZigZag64(value)); 949 } 950 951 // ================================================================= 952 953 /** 954 * Internal helper that writes the current buffer to the output. The 955 * buffer position is reset to its initial value when this returns. 956 */ refreshBuffer()957 private void refreshBuffer() throws IOException { 958 if (output == null) { 959 // We're writing to a single buffer. 960 throw new OutOfSpaceException(); 961 } 962 963 // Since we have an output stream, this is our buffer 964 // and buffer offset == 0 965 output.write(buffer, 0, position); 966 position = 0; 967 } 968 969 /** 970 * Flushes the stream and forces any buffered bytes to be written. This 971 * does not flush the underlying OutputStream. 972 */ flush()973 public void flush() throws IOException { 974 if (output != null) { 975 refreshBuffer(); 976 } 977 } 978 979 /** 980 * If writing to a flat array, return the space left in the array. 981 * Otherwise, throws {@code UnsupportedOperationException}. 982 */ spaceLeft()983 public int spaceLeft() { 984 if (output == null) { 985 return limit - position; 986 } else { 987 throw new UnsupportedOperationException( 988 "spaceLeft() can only be called on CodedOutputStreams that are " + 989 "writing to a flat array."); 990 } 991 } 992 993 /** 994 * Verifies that {@link #spaceLeft()} returns zero. It's common to create 995 * a byte array that is exactly big enough to hold a message, then write to 996 * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()} 997 * after writing verifies that the message was actually as big as expected, 998 * which can help catch bugs. 999 */ checkNoSpaceLeft()1000 public void checkNoSpaceLeft() { 1001 if (spaceLeft() != 0) { 1002 throw new IllegalStateException( 1003 "Did not write as much data as expected."); 1004 } 1005 } 1006 1007 /** 1008 * If you create a CodedOutputStream around a simple flat array, you must 1009 * not attempt to write more bytes than the array has space. Otherwise, 1010 * this exception will be thrown. 1011 */ 1012 public static class OutOfSpaceException extends IOException { 1013 private static final long serialVersionUID = -6947486886997889499L; 1014 OutOfSpaceException()1015 OutOfSpaceException() { 1016 super("CodedOutputStream was writing to a flat byte array and ran " + 1017 "out of space."); 1018 } 1019 } 1020 1021 /** 1022 * Get the total number of bytes successfully written to this stream. The 1023 * returned value is not guaranteed to be accurate if exceptions have been 1024 * found in the middle of writing. 1025 */ getTotalBytesWritten()1026 public int getTotalBytesWritten() { 1027 return totalBytesWritten; 1028 } 1029 1030 /** Write a single byte. */ writeRawByte(final byte value)1031 public void writeRawByte(final byte value) throws IOException { 1032 if (position == limit) { 1033 refreshBuffer(); 1034 } 1035 1036 buffer[position++] = value; 1037 ++totalBytesWritten; 1038 } 1039 1040 /** Write a single byte, represented by an integer value. */ writeRawByte(final int value)1041 public void writeRawByte(final int value) throws IOException { 1042 writeRawByte((byte) value); 1043 } 1044 1045 /** Write a byte string. */ writeRawBytes(final ByteString value)1046 public void writeRawBytes(final ByteString value) throws IOException { 1047 writeRawBytes(value, 0, value.size()); 1048 } 1049 1050 /** Write an array of bytes. */ writeRawBytes(final byte[] value)1051 public void writeRawBytes(final byte[] value) throws IOException { 1052 writeRawBytes(value, 0, value.length); 1053 } 1054 1055 /** 1056 * Write a ByteBuffer. This method will write all content of the ByteBuffer 1057 * regardless of the current position and limit (i.e., the number of bytes 1058 * to be written is value.capacity(), not value.remaining()). Furthermore, 1059 * this method doesn't alter the state of the passed-in ByteBuffer. Its 1060 * position, limit, mark, etc. will remain unchanged. If you only want to 1061 * write the remaining bytes of a ByteBuffer, you can call 1062 * {@code writeRawBytes(byteBuffer.slice())}. 1063 */ writeRawBytes(final ByteBuffer value)1064 public void writeRawBytes(final ByteBuffer value) throws IOException { 1065 if (value.hasArray()) { 1066 writeRawBytes(value.array(), value.arrayOffset(), value.capacity()); 1067 } else { 1068 ByteBuffer duplicated = value.duplicate(); 1069 duplicated.clear(); 1070 writeRawBytesInternal(duplicated); 1071 } 1072 } 1073 1074 /** Write a ByteBuffer that isn't backed by an array. */ writeRawBytesInternal(final ByteBuffer value)1075 private void writeRawBytesInternal(final ByteBuffer value) 1076 throws IOException { 1077 int length = value.remaining(); 1078 if (limit - position >= length) { 1079 // We have room in the current buffer. 1080 value.get(buffer, position, length); 1081 position += length; 1082 totalBytesWritten += length; 1083 } else { 1084 // Write extends past current buffer. Fill the rest of this buffer and 1085 // flush. 1086 final int bytesWritten = limit - position; 1087 value.get(buffer, position, bytesWritten); 1088 length -= bytesWritten; 1089 position = limit; 1090 totalBytesWritten += bytesWritten; 1091 refreshBuffer(); 1092 1093 // Now deal with the rest. 1094 // Since we have an output stream, this is our buffer 1095 // and buffer offset == 0 1096 while (length > limit) { 1097 // Copy data into the buffer before writing it to OutputStream. 1098 // TODO(xiaofeng): Introduce ZeroCopyOutputStream to avoid this copy. 1099 value.get(buffer, 0, limit); 1100 output.write(buffer, 0, limit); 1101 length -= limit; 1102 totalBytesWritten += limit; 1103 } 1104 value.get(buffer, 0, length); 1105 position = length; 1106 totalBytesWritten += length; 1107 } 1108 } 1109 1110 /** Write part of an array of bytes. */ writeRawBytes(final byte[] value, int offset, int length)1111 public void writeRawBytes(final byte[] value, int offset, int length) 1112 throws IOException { 1113 if (limit - position >= length) { 1114 // We have room in the current buffer. 1115 System.arraycopy(value, offset, buffer, position, length); 1116 position += length; 1117 totalBytesWritten += length; 1118 } else { 1119 // Write extends past current buffer. Fill the rest of this buffer and 1120 // flush. 1121 final int bytesWritten = limit - position; 1122 System.arraycopy(value, offset, buffer, position, bytesWritten); 1123 offset += bytesWritten; 1124 length -= bytesWritten; 1125 position = limit; 1126 totalBytesWritten += bytesWritten; 1127 refreshBuffer(); 1128 1129 // Now deal with the rest. 1130 // Since we have an output stream, this is our buffer 1131 // and buffer offset == 0 1132 if (length <= limit) { 1133 // Fits in new buffer. 1134 System.arraycopy(value, offset, buffer, 0, length); 1135 position = length; 1136 } else { 1137 // Write is very big. Let's do it all at once. 1138 output.write(value, offset, length); 1139 } 1140 totalBytesWritten += length; 1141 } 1142 } 1143 1144 /** Write part of a byte string. */ writeRawBytes(final ByteString value, int offset, int length)1145 public void writeRawBytes(final ByteString value, int offset, int length) 1146 throws IOException { 1147 if (limit - position >= length) { 1148 // We have room in the current buffer. 1149 value.copyTo(buffer, offset, position, length); 1150 position += length; 1151 totalBytesWritten += length; 1152 } else { 1153 // Write extends past current buffer. Fill the rest of this buffer and 1154 // flush. 1155 final int bytesWritten = limit - position; 1156 value.copyTo(buffer, offset, position, bytesWritten); 1157 offset += bytesWritten; 1158 length -= bytesWritten; 1159 position = limit; 1160 totalBytesWritten += bytesWritten; 1161 refreshBuffer(); 1162 1163 // Now deal with the rest. 1164 // Since we have an output stream, this is our buffer 1165 // and buffer offset == 0 1166 if (length <= limit) { 1167 // Fits in new buffer. 1168 value.copyTo(buffer, offset, 0, length); 1169 position = length; 1170 } else { 1171 value.writeTo(output, offset, length); 1172 } 1173 totalBytesWritten += length; 1174 } 1175 } 1176 1177 /** Encode and write a tag. */ writeTag(final int fieldNumber, final int wireType)1178 public void writeTag(final int fieldNumber, final int wireType) 1179 throws IOException { 1180 writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType)); 1181 } 1182 1183 /** Compute the number of bytes that would be needed to encode a tag. */ computeTagSize(final int fieldNumber)1184 public static int computeTagSize(final int fieldNumber) { 1185 return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0)); 1186 } 1187 1188 /** 1189 * Encode and write a varint. {@code value} is treated as 1190 * unsigned, so it won't be sign-extended if negative. 1191 */ writeRawVarint32(int value)1192 public void writeRawVarint32(int value) throws IOException { 1193 while (true) { 1194 if ((value & ~0x7F) == 0) { 1195 writeRawByte(value); 1196 return; 1197 } else { 1198 writeRawByte((value & 0x7F) | 0x80); 1199 value >>>= 7; 1200 } 1201 } 1202 } 1203 1204 /** 1205 * Compute the number of bytes that would be needed to encode a varint. 1206 * {@code value} is treated as unsigned, so it won't be sign-extended if 1207 * negative. 1208 */ computeRawVarint32Size(final int value)1209 public static int computeRawVarint32Size(final int value) { 1210 if ((value & (0xffffffff << 7)) == 0) return 1; 1211 if ((value & (0xffffffff << 14)) == 0) return 2; 1212 if ((value & (0xffffffff << 21)) == 0) return 3; 1213 if ((value & (0xffffffff << 28)) == 0) return 4; 1214 return 5; 1215 } 1216 1217 /** Encode and write a varint. */ writeRawVarint64(long value)1218 public void writeRawVarint64(long value) throws IOException { 1219 while (true) { 1220 if ((value & ~0x7FL) == 0) { 1221 writeRawByte((int)value); 1222 return; 1223 } else { 1224 writeRawByte(((int)value & 0x7F) | 0x80); 1225 value >>>= 7; 1226 } 1227 } 1228 } 1229 1230 /** Compute the number of bytes that would be needed to encode a varint. */ computeRawVarint64Size(final long value)1231 public static int computeRawVarint64Size(final long value) { 1232 if ((value & (0xffffffffffffffffL << 7)) == 0) return 1; 1233 if ((value & (0xffffffffffffffffL << 14)) == 0) return 2; 1234 if ((value & (0xffffffffffffffffL << 21)) == 0) return 3; 1235 if ((value & (0xffffffffffffffffL << 28)) == 0) return 4; 1236 if ((value & (0xffffffffffffffffL << 35)) == 0) return 5; 1237 if ((value & (0xffffffffffffffffL << 42)) == 0) return 6; 1238 if ((value & (0xffffffffffffffffL << 49)) == 0) return 7; 1239 if ((value & (0xffffffffffffffffL << 56)) == 0) return 8; 1240 if ((value & (0xffffffffffffffffL << 63)) == 0) return 9; 1241 return 10; 1242 } 1243 1244 /** Write a little-endian 32-bit integer. */ writeRawLittleEndian32(final int value)1245 public void writeRawLittleEndian32(final int value) throws IOException { 1246 writeRawByte((value ) & 0xFF); 1247 writeRawByte((value >> 8) & 0xFF); 1248 writeRawByte((value >> 16) & 0xFF); 1249 writeRawByte((value >> 24) & 0xFF); 1250 } 1251 1252 public static final int LITTLE_ENDIAN_32_SIZE = 4; 1253 1254 /** Write a little-endian 64-bit integer. */ writeRawLittleEndian64(final long value)1255 public void writeRawLittleEndian64(final long value) throws IOException { 1256 writeRawByte((int)(value ) & 0xFF); 1257 writeRawByte((int)(value >> 8) & 0xFF); 1258 writeRawByte((int)(value >> 16) & 0xFF); 1259 writeRawByte((int)(value >> 24) & 0xFF); 1260 writeRawByte((int)(value >> 32) & 0xFF); 1261 writeRawByte((int)(value >> 40) & 0xFF); 1262 writeRawByte((int)(value >> 48) & 0xFF); 1263 writeRawByte((int)(value >> 56) & 0xFF); 1264 } 1265 1266 public static final int LITTLE_ENDIAN_64_SIZE = 8; 1267 1268 /** 1269 * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers 1270 * into values that can be efficiently encoded with varint. (Otherwise, 1271 * negative values must be sign-extended to 64 bits to be varint encoded, 1272 * thus always taking 10 bytes on the wire.) 1273 * 1274 * @param n A signed 32-bit integer. 1275 * @return An unsigned 32-bit integer, stored in a signed int because 1276 * Java has no explicit unsigned support. 1277 */ encodeZigZag32(final int n)1278 public static int encodeZigZag32(final int n) { 1279 // Note: the right-shift must be arithmetic 1280 return (n << 1) ^ (n >> 31); 1281 } 1282 1283 /** 1284 * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers 1285 * into values that can be efficiently encoded with varint. (Otherwise, 1286 * negative values must be sign-extended to 64 bits to be varint encoded, 1287 * thus always taking 10 bytes on the wire.) 1288 * 1289 * @param n A signed 64-bit integer. 1290 * @return An unsigned 64-bit integer, stored in a signed int because 1291 * Java has no explicit unsigned support. 1292 */ encodeZigZag64(final long n)1293 public static long encodeZigZag64(final long n) { 1294 // Note: the right-shift must be arithmetic 1295 return (n << 1) ^ (n >> 63); 1296 } 1297 } 1298