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 static com.google.protobuf.WireFormat.FIXED32_SIZE; 34 import static com.google.protobuf.WireFormat.FIXED64_SIZE; 35 import static com.google.protobuf.WireFormat.WIRETYPE_END_GROUP; 36 import static com.google.protobuf.WireFormat.WIRETYPE_FIXED32; 37 import static com.google.protobuf.WireFormat.WIRETYPE_FIXED64; 38 import static com.google.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED; 39 import static com.google.protobuf.WireFormat.WIRETYPE_START_GROUP; 40 import static com.google.protobuf.WireFormat.WIRETYPE_VARINT; 41 42 import java.io.IOException; 43 import java.nio.ByteBuffer; 44 import java.util.List; 45 import java.util.Map; 46 47 /** 48 * A {@link Reader} that reads from a buffer containing a message serialized with the binary 49 * protocol. 50 */ 51 @ExperimentalApi 52 abstract class BinaryReader implements Reader { 53 private static final int FIXED32_MULTIPLE_MASK = FIXED32_SIZE - 1; 54 private static final int FIXED64_MULTIPLE_MASK = FIXED64_SIZE - 1; 55 56 /** 57 * Creates a new reader using the given {@code buffer} as input. 58 * 59 * @param buffer the input buffer. The buffer (including position, limit, etc.) will not be 60 * modified. To increment the buffer position after the read completes, use the value returned 61 * by {@link #getTotalBytesRead()}. 62 * @param bufferIsImmutable if {@code true} the reader assumes that the content of {@code buffer} 63 * will never change and any allocated {@link ByteString} instances will by directly wrap 64 * slices of {@code buffer}. 65 * @return the reader 66 */ newInstance(ByteBuffer buffer, boolean bufferIsImmutable)67 public static BinaryReader newInstance(ByteBuffer buffer, boolean bufferIsImmutable) { 68 if (buffer.hasArray()) { 69 // TODO(nathanmittler): Add support for unsafe operations. 70 return new SafeHeapReader(buffer, bufferIsImmutable); 71 } 72 // TODO(nathanmittler): Add support for direct buffers 73 throw new IllegalArgumentException("Direct buffers not yet supported"); 74 } 75 76 /** Only allow subclassing for inner classes. */ BinaryReader()77 private BinaryReader() {} 78 79 /** Returns the total number of bytes read so far from the input buffer. */ getTotalBytesRead()80 public abstract int getTotalBytesRead(); 81 82 @Override shouldDiscardUnknownFields()83 public boolean shouldDiscardUnknownFields() { 84 return false; 85 } 86 87 /** 88 * A {@link BinaryReader} implementation that operates on a heap {@link ByteBuffer}. Uses only 89 * safe operations on the underlying array. 90 */ 91 private static final class SafeHeapReader extends BinaryReader { 92 private final boolean bufferIsImmutable; 93 private final byte[] buffer; 94 private int pos; 95 private final int initialPos; 96 private int limit; 97 private int tag; 98 private int endGroupTag; 99 SafeHeapReader(ByteBuffer bytebuf, boolean bufferIsImmutable)100 public SafeHeapReader(ByteBuffer bytebuf, boolean bufferIsImmutable) { 101 this.bufferIsImmutable = bufferIsImmutable; 102 buffer = bytebuf.array(); 103 initialPos = pos = bytebuf.arrayOffset() + bytebuf.position(); 104 limit = bytebuf.arrayOffset() + bytebuf.limit(); 105 } 106 isAtEnd()107 private boolean isAtEnd() { 108 return pos == limit; 109 } 110 111 @Override getTotalBytesRead()112 public int getTotalBytesRead() { 113 return pos - initialPos; 114 } 115 116 @Override getFieldNumber()117 public int getFieldNumber() throws IOException { 118 if (isAtEnd()) { 119 return Reader.READ_DONE; 120 } 121 tag = readVarint32(); 122 if (tag == endGroupTag) { 123 return Reader.READ_DONE; 124 } 125 return WireFormat.getTagFieldNumber(tag); 126 } 127 128 @Override getTag()129 public int getTag() { 130 return tag; 131 } 132 133 @Override skipField()134 public boolean skipField() throws IOException { 135 if (isAtEnd() || tag == endGroupTag) { 136 return false; 137 } 138 139 switch (WireFormat.getTagWireType(tag)) { 140 case WIRETYPE_VARINT: 141 skipVarint(); 142 return true; 143 case WIRETYPE_FIXED64: 144 skipBytes(FIXED64_SIZE); 145 return true; 146 case WIRETYPE_LENGTH_DELIMITED: 147 skipBytes(readVarint32()); 148 return true; 149 case WIRETYPE_FIXED32: 150 skipBytes(FIXED32_SIZE); 151 return true; 152 case WIRETYPE_START_GROUP: 153 skipGroup(); 154 return true; 155 default: 156 throw InvalidProtocolBufferException.invalidWireType(); 157 } 158 } 159 160 @Override readDouble()161 public double readDouble() throws IOException { 162 requireWireType(WIRETYPE_FIXED64); 163 return Double.longBitsToDouble(readLittleEndian64()); 164 } 165 166 @Override readFloat()167 public float readFloat() throws IOException { 168 requireWireType(WIRETYPE_FIXED32); 169 return Float.intBitsToFloat(readLittleEndian32()); 170 } 171 172 @Override readUInt64()173 public long readUInt64() throws IOException { 174 requireWireType(WIRETYPE_VARINT); 175 return readVarint64(); 176 } 177 178 @Override readInt64()179 public long readInt64() throws IOException { 180 requireWireType(WIRETYPE_VARINT); 181 return readVarint64(); 182 } 183 184 @Override readInt32()185 public int readInt32() throws IOException { 186 requireWireType(WIRETYPE_VARINT); 187 return readVarint32(); 188 } 189 190 @Override readFixed64()191 public long readFixed64() throws IOException { 192 requireWireType(WIRETYPE_FIXED64); 193 return readLittleEndian64(); 194 } 195 196 @Override readFixed32()197 public int readFixed32() throws IOException { 198 requireWireType(WIRETYPE_FIXED32); 199 return readLittleEndian32(); 200 } 201 202 @Override readBool()203 public boolean readBool() throws IOException { 204 requireWireType(WIRETYPE_VARINT); 205 return readVarint32() != 0; 206 } 207 208 @Override readString()209 public String readString() throws IOException { 210 return readStringInternal(false); 211 } 212 213 @Override readStringRequireUtf8()214 public String readStringRequireUtf8() throws IOException { 215 return readStringInternal(true); 216 } 217 readStringInternal(boolean requireUtf8)218 public String readStringInternal(boolean requireUtf8) throws IOException { 219 requireWireType(WIRETYPE_LENGTH_DELIMITED); 220 final int size = readVarint32(); 221 if (size == 0) { 222 return ""; 223 } 224 225 requireBytes(size); 226 if (requireUtf8 && !Utf8.isValidUtf8(buffer, pos, pos + size)) { 227 throw InvalidProtocolBufferException.invalidUtf8(); 228 } 229 String result = new String(buffer, pos, size, Internal.UTF_8); 230 pos += size; 231 return result; 232 } 233 234 @Override readMessage(Class<T> clazz, ExtensionRegistryLite extensionRegistry)235 public <T> T readMessage(Class<T> clazz, ExtensionRegistryLite extensionRegistry) 236 throws IOException { 237 requireWireType(WIRETYPE_LENGTH_DELIMITED); 238 return readMessage(Protobuf.getInstance().schemaFor(clazz), extensionRegistry); 239 } 240 241 @Override readMessageBySchemaWithCheck( Schema<T> schema, ExtensionRegistryLite extensionRegistry)242 public <T> T readMessageBySchemaWithCheck( 243 Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException { 244 requireWireType(WIRETYPE_LENGTH_DELIMITED); 245 return readMessage(schema, extensionRegistry); 246 } 247 readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry)248 private <T> T readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry) 249 throws IOException { 250 T newInstance = schema.newInstance(); 251 mergeMessageField(newInstance, schema, extensionRegistry); 252 schema.makeImmutable(newInstance); 253 return newInstance; 254 } 255 256 @Override mergeMessageField( T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)257 public <T> void mergeMessageField( 258 T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException { 259 int size = readVarint32(); 260 requireBytes(size); 261 262 // Update the limit. 263 int prevLimit = limit; 264 int newLimit = pos + size; 265 limit = newLimit; 266 267 try { 268 schema.mergeFrom(target, this, extensionRegistry); 269 if (pos != newLimit) { 270 throw InvalidProtocolBufferException.parseFailure(); 271 } 272 } finally { 273 // Restore the limit. 274 limit = prevLimit; 275 } 276 } 277 278 @Override readGroup(Class<T> clazz, ExtensionRegistryLite extensionRegistry)279 public <T> T readGroup(Class<T> clazz, ExtensionRegistryLite extensionRegistry) 280 throws IOException { 281 requireWireType(WIRETYPE_START_GROUP); 282 return readGroup(Protobuf.getInstance().schemaFor(clazz), extensionRegistry); 283 } 284 285 @Override readGroupBySchemaWithCheck( Schema<T> schema, ExtensionRegistryLite extensionRegistry)286 public <T> T readGroupBySchemaWithCheck( 287 Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException { 288 requireWireType(WIRETYPE_START_GROUP); 289 return readGroup(schema, extensionRegistry); 290 } 291 readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry)292 private <T> T readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry) 293 throws IOException { 294 T newInstance = schema.newInstance(); 295 mergeGroupField(newInstance, schema, extensionRegistry); 296 schema.makeImmutable(newInstance); 297 return newInstance; 298 } 299 300 @Override mergeGroupField( T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)301 public <T> void mergeGroupField( 302 T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException { 303 int prevEndGroupTag = endGroupTag; 304 endGroupTag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WIRETYPE_END_GROUP); 305 306 try { 307 schema.mergeFrom(target, this, extensionRegistry); 308 if (tag != endGroupTag) { 309 throw InvalidProtocolBufferException.parseFailure(); 310 } 311 } finally { 312 // Restore the old end group tag. 313 endGroupTag = prevEndGroupTag; 314 } 315 } 316 317 @Override readBytes()318 public ByteString readBytes() throws IOException { 319 requireWireType(WIRETYPE_LENGTH_DELIMITED); 320 int size = readVarint32(); 321 if (size == 0) { 322 return ByteString.EMPTY; 323 } 324 325 requireBytes(size); 326 ByteString bytes = 327 bufferIsImmutable 328 ? ByteString.wrap(buffer, pos, size) 329 : ByteString.copyFrom(buffer, pos, size); 330 pos += size; 331 return bytes; 332 } 333 334 @Override readUInt32()335 public int readUInt32() throws IOException { 336 requireWireType(WIRETYPE_VARINT); 337 return readVarint32(); 338 } 339 340 @Override readEnum()341 public int readEnum() throws IOException { 342 requireWireType(WIRETYPE_VARINT); 343 return readVarint32(); 344 } 345 346 @Override readSFixed32()347 public int readSFixed32() throws IOException { 348 requireWireType(WIRETYPE_FIXED32); 349 return readLittleEndian32(); 350 } 351 352 @Override readSFixed64()353 public long readSFixed64() throws IOException { 354 requireWireType(WIRETYPE_FIXED64); 355 return readLittleEndian64(); 356 } 357 358 @Override readSInt32()359 public int readSInt32() throws IOException { 360 requireWireType(WIRETYPE_VARINT); 361 return CodedInputStream.decodeZigZag32(readVarint32()); 362 } 363 364 @Override readSInt64()365 public long readSInt64() throws IOException { 366 requireWireType(WIRETYPE_VARINT); 367 return CodedInputStream.decodeZigZag64(readVarint64()); 368 } 369 370 @Override readDoubleList(List<Double> target)371 public void readDoubleList(List<Double> target) throws IOException { 372 if (target instanceof DoubleArrayList) { 373 DoubleArrayList plist = (DoubleArrayList) target; 374 switch (WireFormat.getTagWireType(tag)) { 375 case WIRETYPE_LENGTH_DELIMITED: 376 final int bytes = readVarint32(); 377 verifyPackedFixed64Length(bytes); 378 final int fieldEndPos = pos + bytes; 379 while (pos < fieldEndPos) { 380 plist.addDouble(Double.longBitsToDouble(readLittleEndian64_NoCheck())); 381 } 382 break; 383 case WIRETYPE_FIXED64: 384 while (true) { 385 plist.addDouble(readDouble()); 386 387 if (isAtEnd()) { 388 return; 389 } 390 int prevPos = pos; 391 int nextTag = readVarint32(); 392 if (nextTag != tag) { 393 // We've reached the end of the repeated field. Rewind the buffer position to before 394 // the new tag. 395 pos = prevPos; 396 return; 397 } 398 } 399 default: 400 throw InvalidProtocolBufferException.invalidWireType(); 401 } 402 } else { 403 switch (WireFormat.getTagWireType(tag)) { 404 case WIRETYPE_LENGTH_DELIMITED: 405 final int bytes = readVarint32(); 406 verifyPackedFixed64Length(bytes); 407 final int fieldEndPos = pos + bytes; 408 while (pos < fieldEndPos) { 409 target.add(Double.longBitsToDouble(readLittleEndian64_NoCheck())); 410 } 411 break; 412 case WIRETYPE_FIXED64: 413 while (true) { 414 target.add(readDouble()); 415 416 if (isAtEnd()) { 417 return; 418 } 419 int prevPos = pos; 420 int nextTag = readVarint32(); 421 if (nextTag != tag) { 422 // We've reached the end of the repeated field. Rewind the buffer position to before 423 // the new tag. 424 pos = prevPos; 425 return; 426 } 427 } 428 default: 429 throw InvalidProtocolBufferException.invalidWireType(); 430 } 431 } 432 } 433 434 @Override readFloatList(List<Float> target)435 public void readFloatList(List<Float> target) throws IOException { 436 if (target instanceof FloatArrayList) { 437 FloatArrayList plist = (FloatArrayList) target; 438 switch (WireFormat.getTagWireType(tag)) { 439 case WIRETYPE_LENGTH_DELIMITED: 440 final int bytes = readVarint32(); 441 verifyPackedFixed32Length(bytes); 442 final int fieldEndPos = pos + bytes; 443 while (pos < fieldEndPos) { 444 plist.addFloat(Float.intBitsToFloat(readLittleEndian32_NoCheck())); 445 } 446 break; 447 case WIRETYPE_FIXED32: 448 while (true) { 449 plist.addFloat(readFloat()); 450 451 if (isAtEnd()) { 452 return; 453 } 454 int prevPos = pos; 455 int nextTag = readVarint32(); 456 if (nextTag != tag) { 457 // We've reached the end of the repeated field. Rewind the buffer position to before 458 // the new tag. 459 pos = prevPos; 460 return; 461 } 462 } 463 default: 464 throw InvalidProtocolBufferException.invalidWireType(); 465 } 466 } else { 467 switch (WireFormat.getTagWireType(tag)) { 468 case WIRETYPE_LENGTH_DELIMITED: 469 final int bytes = readVarint32(); 470 verifyPackedFixed32Length(bytes); 471 final int fieldEndPos = pos + bytes; 472 while (pos < fieldEndPos) { 473 target.add(Float.intBitsToFloat(readLittleEndian32_NoCheck())); 474 } 475 break; 476 case WIRETYPE_FIXED32: 477 while (true) { 478 target.add(readFloat()); 479 480 if (isAtEnd()) { 481 return; 482 } 483 int prevPos = pos; 484 int nextTag = readVarint32(); 485 if (nextTag != tag) { 486 // We've reached the end of the repeated field. Rewind the buffer position to before 487 // the new tag. 488 pos = prevPos; 489 return; 490 } 491 } 492 default: 493 throw InvalidProtocolBufferException.invalidWireType(); 494 } 495 } 496 } 497 498 @Override readUInt64List(List<Long> target)499 public void readUInt64List(List<Long> target) throws IOException { 500 if (target instanceof LongArrayList) { 501 LongArrayList plist = (LongArrayList) target; 502 switch (WireFormat.getTagWireType(tag)) { 503 case WIRETYPE_LENGTH_DELIMITED: 504 final int bytes = readVarint32(); 505 final int fieldEndPos = pos + bytes; 506 while (pos < fieldEndPos) { 507 plist.addLong(readVarint64()); 508 } 509 requirePosition(fieldEndPos); 510 break; 511 case WIRETYPE_VARINT: 512 while (true) { 513 plist.addLong(readUInt64()); 514 515 if (isAtEnd()) { 516 return; 517 } 518 int prevPos = pos; 519 int nextTag = readVarint32(); 520 if (nextTag != tag) { 521 // We've reached the end of the repeated field. Rewind the buffer position to before 522 // the new tag. 523 pos = prevPos; 524 return; 525 } 526 } 527 default: 528 throw InvalidProtocolBufferException.invalidWireType(); 529 } 530 } else { 531 switch (WireFormat.getTagWireType(tag)) { 532 case WIRETYPE_LENGTH_DELIMITED: 533 final int bytes = readVarint32(); 534 final int fieldEndPos = pos + bytes; 535 while (pos < fieldEndPos) { 536 target.add(readVarint64()); 537 } 538 requirePosition(fieldEndPos); 539 break; 540 case WIRETYPE_VARINT: 541 while (true) { 542 target.add(readUInt64()); 543 544 if (isAtEnd()) { 545 return; 546 } 547 int prevPos = pos; 548 int nextTag = readVarint32(); 549 if (nextTag != tag) { 550 // We've reached the end of the repeated field. Rewind the buffer position to before 551 // the new tag. 552 pos = prevPos; 553 return; 554 } 555 } 556 default: 557 throw InvalidProtocolBufferException.invalidWireType(); 558 } 559 } 560 } 561 562 @Override readInt64List(List<Long> target)563 public void readInt64List(List<Long> target) throws IOException { 564 if (target instanceof LongArrayList) { 565 LongArrayList plist = (LongArrayList) target; 566 switch (WireFormat.getTagWireType(tag)) { 567 case WIRETYPE_LENGTH_DELIMITED: 568 final int bytes = readVarint32(); 569 final int fieldEndPos = pos + bytes; 570 while (pos < fieldEndPos) { 571 plist.addLong(readVarint64()); 572 } 573 requirePosition(fieldEndPos); 574 break; 575 case WIRETYPE_VARINT: 576 while (true) { 577 plist.addLong(readInt64()); 578 579 if (isAtEnd()) { 580 return; 581 } 582 int prevPos = pos; 583 int nextTag = readVarint32(); 584 if (nextTag != tag) { 585 // We've reached the end of the repeated field. Rewind the buffer position to before 586 // the new tag. 587 pos = prevPos; 588 return; 589 } 590 } 591 default: 592 throw InvalidProtocolBufferException.invalidWireType(); 593 } 594 } else { 595 switch (WireFormat.getTagWireType(tag)) { 596 case WIRETYPE_LENGTH_DELIMITED: 597 final int bytes = readVarint32(); 598 final int fieldEndPos = pos + bytes; 599 while (pos < fieldEndPos) { 600 target.add(readVarint64()); 601 } 602 requirePosition(fieldEndPos); 603 break; 604 case WIRETYPE_VARINT: 605 while (true) { 606 target.add(readInt64()); 607 608 if (isAtEnd()) { 609 return; 610 } 611 int prevPos = pos; 612 int nextTag = readVarint32(); 613 if (nextTag != tag) { 614 // We've reached the end of the repeated field. Rewind the buffer position to before 615 // the new tag. 616 pos = prevPos; 617 return; 618 } 619 } 620 default: 621 throw InvalidProtocolBufferException.invalidWireType(); 622 } 623 } 624 } 625 626 @Override readInt32List(List<Integer> target)627 public void readInt32List(List<Integer> target) throws IOException { 628 if (target instanceof IntArrayList) { 629 IntArrayList plist = (IntArrayList) target; 630 switch (WireFormat.getTagWireType(tag)) { 631 case WIRETYPE_LENGTH_DELIMITED: 632 final int bytes = readVarint32(); 633 final int fieldEndPos = pos + bytes; 634 while (pos < fieldEndPos) { 635 plist.addInt(readVarint32()); 636 } 637 requirePosition(fieldEndPos); 638 break; 639 case WIRETYPE_VARINT: 640 while (true) { 641 plist.addInt(readInt32()); 642 643 if (isAtEnd()) { 644 return; 645 } 646 int prevPos = pos; 647 int nextTag = readVarint32(); 648 if (nextTag != tag) { 649 // We've reached the end of the repeated field. Rewind the buffer position to before 650 // the new tag. 651 pos = prevPos; 652 return; 653 } 654 } 655 default: 656 throw InvalidProtocolBufferException.invalidWireType(); 657 } 658 } else { 659 switch (WireFormat.getTagWireType(tag)) { 660 case WIRETYPE_LENGTH_DELIMITED: 661 final int bytes = readVarint32(); 662 final int fieldEndPos = pos + bytes; 663 while (pos < fieldEndPos) { 664 target.add(readVarint32()); 665 } 666 requirePosition(fieldEndPos); 667 break; 668 case WIRETYPE_VARINT: 669 while (true) { 670 target.add(readInt32()); 671 672 if (isAtEnd()) { 673 return; 674 } 675 int prevPos = pos; 676 int nextTag = readVarint32(); 677 if (nextTag != tag) { 678 // We've reached the end of the repeated field. Rewind the buffer position to before 679 // the new tag. 680 pos = prevPos; 681 return; 682 } 683 } 684 default: 685 throw InvalidProtocolBufferException.invalidWireType(); 686 } 687 } 688 } 689 690 @Override readFixed64List(List<Long> target)691 public void readFixed64List(List<Long> target) throws IOException { 692 if (target instanceof LongArrayList) { 693 LongArrayList plist = (LongArrayList) target; 694 switch (WireFormat.getTagWireType(tag)) { 695 case WIRETYPE_LENGTH_DELIMITED: 696 final int bytes = readVarint32(); 697 verifyPackedFixed64Length(bytes); 698 final int fieldEndPos = pos + bytes; 699 while (pos < fieldEndPos) { 700 plist.addLong(readLittleEndian64_NoCheck()); 701 } 702 break; 703 case WIRETYPE_FIXED64: 704 while (true) { 705 plist.addLong(readFixed64()); 706 707 if (isAtEnd()) { 708 return; 709 } 710 int prevPos = pos; 711 int nextTag = readVarint32(); 712 if (nextTag != tag) { 713 // We've reached the end of the repeated field. Rewind the buffer position to before 714 // the new tag. 715 pos = prevPos; 716 return; 717 } 718 } 719 default: 720 throw InvalidProtocolBufferException.invalidWireType(); 721 } 722 } else { 723 switch (WireFormat.getTagWireType(tag)) { 724 case WIRETYPE_LENGTH_DELIMITED: 725 final int bytes = readVarint32(); 726 verifyPackedFixed64Length(bytes); 727 final int fieldEndPos = pos + bytes; 728 while (pos < fieldEndPos) { 729 target.add(readLittleEndian64_NoCheck()); 730 } 731 break; 732 case WIRETYPE_FIXED64: 733 while (true) { 734 target.add(readFixed64()); 735 736 if (isAtEnd()) { 737 return; 738 } 739 int prevPos = pos; 740 int nextTag = readVarint32(); 741 if (nextTag != tag) { 742 // We've reached the end of the repeated field. Rewind the buffer position to before 743 // the new tag. 744 pos = prevPos; 745 return; 746 } 747 } 748 default: 749 throw InvalidProtocolBufferException.invalidWireType(); 750 } 751 } 752 } 753 754 @Override readFixed32List(List<Integer> target)755 public void readFixed32List(List<Integer> target) throws IOException { 756 if (target instanceof IntArrayList) { 757 IntArrayList plist = (IntArrayList) target; 758 switch (WireFormat.getTagWireType(tag)) { 759 case WIRETYPE_LENGTH_DELIMITED: 760 final int bytes = readVarint32(); 761 verifyPackedFixed32Length(bytes); 762 final int fieldEndPos = pos + bytes; 763 while (pos < fieldEndPos) { 764 plist.addInt(readLittleEndian32_NoCheck()); 765 } 766 break; 767 case WIRETYPE_FIXED32: 768 while (true) { 769 plist.addInt(readFixed32()); 770 771 if (isAtEnd()) { 772 return; 773 } 774 int prevPos = pos; 775 int nextTag = readVarint32(); 776 if (nextTag != tag) { 777 // We've reached the end of the repeated field. Rewind the buffer position to before 778 // the new tag. 779 pos = prevPos; 780 return; 781 } 782 } 783 default: 784 throw InvalidProtocolBufferException.invalidWireType(); 785 } 786 } else { 787 switch (WireFormat.getTagWireType(tag)) { 788 case WIRETYPE_LENGTH_DELIMITED: 789 final int bytes = readVarint32(); 790 verifyPackedFixed32Length(bytes); 791 final int fieldEndPos = pos + bytes; 792 while (pos < fieldEndPos) { 793 target.add(readLittleEndian32_NoCheck()); 794 } 795 break; 796 case WIRETYPE_FIXED32: 797 while (true) { 798 target.add(readFixed32()); 799 800 if (isAtEnd()) { 801 return; 802 } 803 int prevPos = pos; 804 int nextTag = readVarint32(); 805 if (nextTag != tag) { 806 // We've reached the end of the repeated field. Rewind the buffer position to before 807 // the new tag. 808 pos = prevPos; 809 return; 810 } 811 } 812 default: 813 throw InvalidProtocolBufferException.invalidWireType(); 814 } 815 } 816 } 817 818 @Override readBoolList(List<Boolean> target)819 public void readBoolList(List<Boolean> target) throws IOException { 820 if (target instanceof BooleanArrayList) { 821 BooleanArrayList plist = (BooleanArrayList) target; 822 switch (WireFormat.getTagWireType(tag)) { 823 case WIRETYPE_LENGTH_DELIMITED: 824 final int bytes = readVarint32(); 825 final int fieldEndPos = pos + bytes; 826 while (pos < fieldEndPos) { 827 plist.addBoolean(readVarint32() != 0); 828 } 829 requirePosition(fieldEndPos); 830 break; 831 case WIRETYPE_VARINT: 832 while (true) { 833 plist.addBoolean(readBool()); 834 835 if (isAtEnd()) { 836 return; 837 } 838 int prevPos = pos; 839 int nextTag = readVarint32(); 840 if (nextTag != tag) { 841 // We've reached the end of the repeated field. Rewind the buffer position to before 842 // the new tag. 843 pos = prevPos; 844 return; 845 } 846 } 847 default: 848 throw InvalidProtocolBufferException.invalidWireType(); 849 } 850 } else { 851 switch (WireFormat.getTagWireType(tag)) { 852 case WIRETYPE_LENGTH_DELIMITED: 853 final int bytes = readVarint32(); 854 final int fieldEndPos = pos + bytes; 855 while (pos < fieldEndPos) { 856 target.add(readVarint32() != 0); 857 } 858 requirePosition(fieldEndPos); 859 break; 860 case WIRETYPE_VARINT: 861 while (true) { 862 target.add(readBool()); 863 864 if (isAtEnd()) { 865 return; 866 } 867 int prevPos = pos; 868 int nextTag = readVarint32(); 869 if (nextTag != tag) { 870 // We've reached the end of the repeated field. Rewind the buffer position to before 871 // the new tag. 872 pos = prevPos; 873 return; 874 } 875 } 876 default: 877 throw InvalidProtocolBufferException.invalidWireType(); 878 } 879 } 880 } 881 882 @Override readStringList(List<String> target)883 public void readStringList(List<String> target) throws IOException { 884 readStringListInternal(target, false); 885 } 886 887 @Override readStringListRequireUtf8(List<String> target)888 public void readStringListRequireUtf8(List<String> target) throws IOException { 889 readStringListInternal(target, true); 890 } 891 readStringListInternal(List<String> target, boolean requireUtf8)892 public void readStringListInternal(List<String> target, boolean requireUtf8) 893 throws IOException { 894 if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) { 895 throw InvalidProtocolBufferException.invalidWireType(); 896 } 897 898 if (target instanceof LazyStringList && !requireUtf8) { 899 LazyStringList lazyList = (LazyStringList) target; 900 while (true) { 901 lazyList.add(readBytes()); 902 903 if (isAtEnd()) { 904 return; 905 } 906 int prevPos = pos; 907 int nextTag = readVarint32(); 908 if (nextTag != tag) { 909 // We've reached the end of the repeated field. Rewind the buffer position to before 910 // the new tag. 911 pos = prevPos; 912 return; 913 } 914 } 915 } else { 916 while (true) { 917 target.add(readStringInternal(requireUtf8)); 918 919 if (isAtEnd()) { 920 return; 921 } 922 int prevPos = pos; 923 int nextTag = readVarint32(); 924 if (nextTag != tag) { 925 // We've reached the end of the repeated field. Rewind the buffer position to before 926 // the new tag. 927 pos = prevPos; 928 return; 929 } 930 } 931 } 932 } 933 934 @Override readMessageList( List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)935 public <T> void readMessageList( 936 List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry) 937 throws IOException { 938 final Schema<T> schema = Protobuf.getInstance().schemaFor(targetType); 939 readMessageList(target, schema, extensionRegistry); 940 } 941 942 @Override readMessageList( List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)943 public <T> void readMessageList( 944 List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) 945 throws IOException { 946 if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) { 947 throw InvalidProtocolBufferException.invalidWireType(); 948 } 949 final int listTag = tag; 950 while (true) { 951 target.add(readMessage(schema, extensionRegistry)); 952 953 if (isAtEnd()) { 954 return; 955 } 956 int prevPos = pos; 957 int nextTag = readVarint32(); 958 if (nextTag != listTag) { 959 // We've reached the end of the repeated field. Rewind the buffer position to before 960 // the new tag. 961 pos = prevPos; 962 return; 963 } 964 } 965 } 966 967 @Override readGroupList( List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)968 public <T> void readGroupList( 969 List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry) 970 throws IOException { 971 final Schema<T> schema = Protobuf.getInstance().schemaFor(targetType); 972 readGroupList(target, schema, extensionRegistry); 973 } 974 975 @Override readGroupList( List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)976 public <T> void readGroupList( 977 List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) 978 throws IOException { 979 if (WireFormat.getTagWireType(tag) != WIRETYPE_START_GROUP) { 980 throw InvalidProtocolBufferException.invalidWireType(); 981 } 982 final int listTag = tag; 983 while (true) { 984 target.add(readGroup(schema, extensionRegistry)); 985 986 if (isAtEnd()) { 987 return; 988 } 989 int prevPos = pos; 990 int nextTag = readVarint32(); 991 if (nextTag != listTag) { 992 // We've reached the end of the repeated field. Rewind the buffer position to before 993 // the new tag. 994 pos = prevPos; 995 return; 996 } 997 } 998 } 999 1000 @Override readBytesList(List<ByteString> target)1001 public void readBytesList(List<ByteString> target) throws IOException { 1002 if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) { 1003 throw InvalidProtocolBufferException.invalidWireType(); 1004 } 1005 1006 while (true) { 1007 target.add(readBytes()); 1008 1009 if (isAtEnd()) { 1010 return; 1011 } 1012 int prevPos = pos; 1013 int nextTag = readVarint32(); 1014 if (nextTag != tag) { 1015 // We've reached the end of the repeated field. Rewind the buffer position to before 1016 // the new tag. 1017 pos = prevPos; 1018 return; 1019 } 1020 } 1021 } 1022 1023 @Override readUInt32List(List<Integer> target)1024 public void readUInt32List(List<Integer> target) throws IOException { 1025 if (target instanceof IntArrayList) { 1026 IntArrayList plist = (IntArrayList) target; 1027 switch (WireFormat.getTagWireType(tag)) { 1028 case WIRETYPE_LENGTH_DELIMITED: 1029 final int bytes = readVarint32(); 1030 final int fieldEndPos = pos + bytes; 1031 while (pos < fieldEndPos) { 1032 plist.addInt(readVarint32()); 1033 } 1034 break; 1035 case WIRETYPE_VARINT: 1036 while (true) { 1037 plist.addInt(readUInt32()); 1038 1039 if (isAtEnd()) { 1040 return; 1041 } 1042 int prevPos = pos; 1043 int nextTag = readVarint32(); 1044 if (nextTag != tag) { 1045 // We've reached the end of the repeated field. Rewind the buffer position to before 1046 // the new tag. 1047 pos = prevPos; 1048 return; 1049 } 1050 } 1051 default: 1052 throw InvalidProtocolBufferException.invalidWireType(); 1053 } 1054 } else { 1055 switch (WireFormat.getTagWireType(tag)) { 1056 case WIRETYPE_LENGTH_DELIMITED: 1057 final int bytes = readVarint32(); 1058 final int fieldEndPos = pos + bytes; 1059 while (pos < fieldEndPos) { 1060 target.add(readVarint32()); 1061 } 1062 break; 1063 case WIRETYPE_VARINT: 1064 while (true) { 1065 target.add(readUInt32()); 1066 1067 if (isAtEnd()) { 1068 return; 1069 } 1070 int prevPos = pos; 1071 int nextTag = readVarint32(); 1072 if (nextTag != tag) { 1073 // We've reached the end of the repeated field. Rewind the buffer position to before 1074 // the new tag. 1075 pos = prevPos; 1076 return; 1077 } 1078 } 1079 default: 1080 throw InvalidProtocolBufferException.invalidWireType(); 1081 } 1082 } 1083 } 1084 1085 @Override readEnumList(List<Integer> target)1086 public void readEnumList(List<Integer> target) throws IOException { 1087 if (target instanceof IntArrayList) { 1088 IntArrayList plist = (IntArrayList) target; 1089 switch (WireFormat.getTagWireType(tag)) { 1090 case WIRETYPE_LENGTH_DELIMITED: 1091 final int bytes = readVarint32(); 1092 final int fieldEndPos = pos + bytes; 1093 while (pos < fieldEndPos) { 1094 plist.addInt(readVarint32()); 1095 } 1096 break; 1097 case WIRETYPE_VARINT: 1098 while (true) { 1099 plist.addInt(readEnum()); 1100 1101 if (isAtEnd()) { 1102 return; 1103 } 1104 int prevPos = pos; 1105 int nextTag = readVarint32(); 1106 if (nextTag != tag) { 1107 // We've reached the end of the repeated field. Rewind the buffer position to before 1108 // the new tag. 1109 pos = prevPos; 1110 return; 1111 } 1112 } 1113 default: 1114 throw InvalidProtocolBufferException.invalidWireType(); 1115 } 1116 } else { 1117 switch (WireFormat.getTagWireType(tag)) { 1118 case WIRETYPE_LENGTH_DELIMITED: 1119 final int bytes = readVarint32(); 1120 final int fieldEndPos = pos + bytes; 1121 while (pos < fieldEndPos) { 1122 target.add(readVarint32()); 1123 } 1124 break; 1125 case WIRETYPE_VARINT: 1126 while (true) { 1127 target.add(readEnum()); 1128 1129 if (isAtEnd()) { 1130 return; 1131 } 1132 int prevPos = pos; 1133 int nextTag = readVarint32(); 1134 if (nextTag != tag) { 1135 // We've reached the end of the repeated field. Rewind the buffer position to before 1136 // the new tag. 1137 pos = prevPos; 1138 return; 1139 } 1140 } 1141 default: 1142 throw InvalidProtocolBufferException.invalidWireType(); 1143 } 1144 } 1145 } 1146 1147 @Override readSFixed32List(List<Integer> target)1148 public void readSFixed32List(List<Integer> target) throws IOException { 1149 if (target instanceof IntArrayList) { 1150 IntArrayList plist = (IntArrayList) target; 1151 switch (WireFormat.getTagWireType(tag)) { 1152 case WIRETYPE_LENGTH_DELIMITED: 1153 final int bytes = readVarint32(); 1154 verifyPackedFixed32Length(bytes); 1155 final int fieldEndPos = pos + bytes; 1156 while (pos < fieldEndPos) { 1157 plist.addInt(readLittleEndian32_NoCheck()); 1158 } 1159 break; 1160 case WIRETYPE_FIXED32: 1161 while (true) { 1162 plist.addInt(readSFixed32()); 1163 1164 if (isAtEnd()) { 1165 return; 1166 } 1167 int prevPos = pos; 1168 int nextTag = readVarint32(); 1169 if (nextTag != tag) { 1170 // We've reached the end of the repeated field. Rewind the buffer position to before 1171 // the new tag. 1172 pos = prevPos; 1173 return; 1174 } 1175 } 1176 default: 1177 throw InvalidProtocolBufferException.invalidWireType(); 1178 } 1179 } else { 1180 switch (WireFormat.getTagWireType(tag)) { 1181 case WIRETYPE_LENGTH_DELIMITED: 1182 final int bytes = readVarint32(); 1183 verifyPackedFixed32Length(bytes); 1184 final int fieldEndPos = pos + bytes; 1185 while (pos < fieldEndPos) { 1186 target.add(readLittleEndian32_NoCheck()); 1187 } 1188 break; 1189 case WIRETYPE_FIXED32: 1190 while (true) { 1191 target.add(readSFixed32()); 1192 1193 if (isAtEnd()) { 1194 return; 1195 } 1196 int prevPos = pos; 1197 int nextTag = readVarint32(); 1198 if (nextTag != tag) { 1199 // We've reached the end of the repeated field. Rewind the buffer position to before 1200 // the new tag. 1201 pos = prevPos; 1202 return; 1203 } 1204 } 1205 default: 1206 throw InvalidProtocolBufferException.invalidWireType(); 1207 } 1208 } 1209 } 1210 1211 @Override readSFixed64List(List<Long> target)1212 public void readSFixed64List(List<Long> target) throws IOException { 1213 if (target instanceof LongArrayList) { 1214 LongArrayList plist = (LongArrayList) target; 1215 switch (WireFormat.getTagWireType(tag)) { 1216 case WIRETYPE_LENGTH_DELIMITED: 1217 final int bytes = readVarint32(); 1218 verifyPackedFixed64Length(bytes); 1219 final int fieldEndPos = pos + bytes; 1220 while (pos < fieldEndPos) { 1221 plist.addLong(readLittleEndian64_NoCheck()); 1222 } 1223 break; 1224 case WIRETYPE_FIXED64: 1225 while (true) { 1226 plist.addLong(readSFixed64()); 1227 1228 if (isAtEnd()) { 1229 return; 1230 } 1231 int prevPos = pos; 1232 int nextTag = readVarint32(); 1233 if (nextTag != tag) { 1234 // We've reached the end of the repeated field. Rewind the buffer position to before 1235 // the new tag. 1236 pos = prevPos; 1237 return; 1238 } 1239 } 1240 default: 1241 throw InvalidProtocolBufferException.invalidWireType(); 1242 } 1243 } else { 1244 switch (WireFormat.getTagWireType(tag)) { 1245 case WIRETYPE_LENGTH_DELIMITED: 1246 final int bytes = readVarint32(); 1247 verifyPackedFixed64Length(bytes); 1248 final int fieldEndPos = pos + bytes; 1249 while (pos < fieldEndPos) { 1250 target.add(readLittleEndian64_NoCheck()); 1251 } 1252 break; 1253 case WIRETYPE_FIXED64: 1254 while (true) { 1255 target.add(readSFixed64()); 1256 1257 if (isAtEnd()) { 1258 return; 1259 } 1260 int prevPos = pos; 1261 int nextTag = readVarint32(); 1262 if (nextTag != tag) { 1263 // We've reached the end of the repeated field. Rewind the buffer position to before 1264 // the new tag. 1265 pos = prevPos; 1266 return; 1267 } 1268 } 1269 default: 1270 throw InvalidProtocolBufferException.invalidWireType(); 1271 } 1272 } 1273 } 1274 1275 @Override readSInt32List(List<Integer> target)1276 public void readSInt32List(List<Integer> target) throws IOException { 1277 if (target instanceof IntArrayList) { 1278 IntArrayList plist = (IntArrayList) target; 1279 switch (WireFormat.getTagWireType(tag)) { 1280 case WIRETYPE_LENGTH_DELIMITED: 1281 final int bytes = readVarint32(); 1282 final int fieldEndPos = pos + bytes; 1283 while (pos < fieldEndPos) { 1284 plist.addInt(CodedInputStream.decodeZigZag32(readVarint32())); 1285 } 1286 break; 1287 case WIRETYPE_VARINT: 1288 while (true) { 1289 plist.addInt(readSInt32()); 1290 1291 if (isAtEnd()) { 1292 return; 1293 } 1294 int prevPos = pos; 1295 int nextTag = readVarint32(); 1296 if (nextTag != tag) { 1297 // We've reached the end of the repeated field. Rewind the buffer position to before 1298 // the new tag. 1299 pos = prevPos; 1300 return; 1301 } 1302 } 1303 default: 1304 throw InvalidProtocolBufferException.invalidWireType(); 1305 } 1306 } else { 1307 switch (WireFormat.getTagWireType(tag)) { 1308 case WIRETYPE_LENGTH_DELIMITED: 1309 final int bytes = readVarint32(); 1310 final int fieldEndPos = pos + bytes; 1311 while (pos < fieldEndPos) { 1312 target.add(CodedInputStream.decodeZigZag32(readVarint32())); 1313 } 1314 break; 1315 case WIRETYPE_VARINT: 1316 while (true) { 1317 target.add(readSInt32()); 1318 1319 if (isAtEnd()) { 1320 return; 1321 } 1322 int prevPos = pos; 1323 int nextTag = readVarint32(); 1324 if (nextTag != tag) { 1325 // We've reached the end of the repeated field. Rewind the buffer position to before 1326 // the new tag. 1327 pos = prevPos; 1328 return; 1329 } 1330 } 1331 default: 1332 throw InvalidProtocolBufferException.invalidWireType(); 1333 } 1334 } 1335 } 1336 1337 @Override readSInt64List(List<Long> target)1338 public void readSInt64List(List<Long> target) throws IOException { 1339 if (target instanceof LongArrayList) { 1340 LongArrayList plist = (LongArrayList) target; 1341 switch (WireFormat.getTagWireType(tag)) { 1342 case WIRETYPE_LENGTH_DELIMITED: 1343 final int bytes = readVarint32(); 1344 final int fieldEndPos = pos + bytes; 1345 while (pos < fieldEndPos) { 1346 plist.addLong(CodedInputStream.decodeZigZag64(readVarint64())); 1347 } 1348 break; 1349 case WIRETYPE_VARINT: 1350 while (true) { 1351 plist.addLong(readSInt64()); 1352 1353 if (isAtEnd()) { 1354 return; 1355 } 1356 int prevPos = pos; 1357 int nextTag = readVarint32(); 1358 if (nextTag != tag) { 1359 // We've reached the end of the repeated field. Rewind the buffer position to before 1360 // the new tag. 1361 pos = prevPos; 1362 return; 1363 } 1364 } 1365 default: 1366 throw InvalidProtocolBufferException.invalidWireType(); 1367 } 1368 } else { 1369 switch (WireFormat.getTagWireType(tag)) { 1370 case WIRETYPE_LENGTH_DELIMITED: 1371 final int bytes = readVarint32(); 1372 final int fieldEndPos = pos + bytes; 1373 while (pos < fieldEndPos) { 1374 target.add(CodedInputStream.decodeZigZag64(readVarint64())); 1375 } 1376 break; 1377 case WIRETYPE_VARINT: 1378 while (true) { 1379 target.add(readSInt64()); 1380 1381 if (isAtEnd()) { 1382 return; 1383 } 1384 int prevPos = pos; 1385 int nextTag = readVarint32(); 1386 if (nextTag != tag) { 1387 // We've reached the end of the repeated field. Rewind the buffer position to before 1388 // the new tag. 1389 pos = prevPos; 1390 return; 1391 } 1392 } 1393 default: 1394 throw InvalidProtocolBufferException.invalidWireType(); 1395 } 1396 } 1397 } 1398 1399 @SuppressWarnings("unchecked") 1400 @Override readMap( Map<K, V> target, MapEntryLite.Metadata<K, V> metadata, ExtensionRegistryLite extensionRegistry)1401 public <K, V> void readMap( 1402 Map<K, V> target, 1403 MapEntryLite.Metadata<K, V> metadata, 1404 ExtensionRegistryLite extensionRegistry) 1405 throws IOException { 1406 requireWireType(WIRETYPE_LENGTH_DELIMITED); 1407 int size = readVarint32(); 1408 requireBytes(size); 1409 1410 // Update the limit. 1411 int prevLimit = limit; 1412 int newLimit = pos + size; 1413 limit = newLimit; 1414 1415 try { 1416 K key = metadata.defaultKey; 1417 V value = metadata.defaultValue; 1418 while (true) { 1419 int number = getFieldNumber(); 1420 if (number == READ_DONE) { 1421 break; 1422 } 1423 try { 1424 switch (number) { 1425 case 1: 1426 key = (K) readField(metadata.keyType, null, null); 1427 break; 1428 case 2: 1429 value = 1430 (V) 1431 readField( 1432 metadata.valueType, 1433 metadata.defaultValue.getClass(), 1434 extensionRegistry); 1435 break; 1436 default: 1437 if (!skipField()) { 1438 throw new InvalidProtocolBufferException("Unable to parse map entry."); 1439 } 1440 break; 1441 } 1442 } catch (InvalidProtocolBufferException.InvalidWireTypeException ignore) { 1443 // the type doesn't match, skip the field. 1444 if (!skipField()) { 1445 throw new InvalidProtocolBufferException("Unable to parse map entry."); 1446 } 1447 } 1448 } 1449 target.put(key, value); 1450 } finally { 1451 // Restore the limit. 1452 limit = prevLimit; 1453 } 1454 } 1455 readField( WireFormat.FieldType fieldType, Class<?> messageType, ExtensionRegistryLite extensionRegistry)1456 private Object readField( 1457 WireFormat.FieldType fieldType, 1458 Class<?> messageType, 1459 ExtensionRegistryLite extensionRegistry) 1460 throws IOException { 1461 switch (fieldType) { 1462 case BOOL: 1463 return readBool(); 1464 case BYTES: 1465 return readBytes(); 1466 case DOUBLE: 1467 return readDouble(); 1468 case ENUM: 1469 return readEnum(); 1470 case FIXED32: 1471 return readFixed32(); 1472 case FIXED64: 1473 return readFixed64(); 1474 case FLOAT: 1475 return readFloat(); 1476 case INT32: 1477 return readInt32(); 1478 case INT64: 1479 return readInt64(); 1480 case MESSAGE: 1481 return readMessage(messageType, extensionRegistry); 1482 case SFIXED32: 1483 return readSFixed32(); 1484 case SFIXED64: 1485 return readSFixed64(); 1486 case SINT32: 1487 return readSInt32(); 1488 case SINT64: 1489 return readSInt64(); 1490 case STRING: 1491 return readStringRequireUtf8(); 1492 case UINT32: 1493 return readUInt32(); 1494 case UINT64: 1495 return readUInt64(); 1496 default: 1497 throw new RuntimeException("unsupported field type."); 1498 } 1499 } 1500 1501 /** Read a raw Varint from the stream. If larger than 32 bits, discard the upper bits. */ readVarint32()1502 private int readVarint32() throws IOException { 1503 // See implementation notes for readRawVarint64 1504 int i = pos; 1505 1506 if (limit == pos) { 1507 throw InvalidProtocolBufferException.truncatedMessage(); 1508 } 1509 1510 int x; 1511 if ((x = buffer[i++]) >= 0) { 1512 pos = i; 1513 return x; 1514 } else if (limit - i < 9) { 1515 return (int) readVarint64SlowPath(); 1516 } else if ((x ^= (buffer[i++] << 7)) < 0) { 1517 x ^= (~0 << 7); 1518 } else if ((x ^= (buffer[i++] << 14)) >= 0) { 1519 x ^= (~0 << 7) ^ (~0 << 14); 1520 } else if ((x ^= (buffer[i++] << 21)) < 0) { 1521 x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21); 1522 } else { 1523 int y = buffer[i++]; 1524 x ^= y << 28; 1525 x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28); 1526 if (y < 0 1527 && buffer[i++] < 0 1528 && buffer[i++] < 0 1529 && buffer[i++] < 0 1530 && buffer[i++] < 0 1531 && buffer[i++] < 0) { 1532 throw InvalidProtocolBufferException.malformedVarint(); 1533 } 1534 } 1535 pos = i; 1536 return x; 1537 } 1538 readVarint64()1539 public long readVarint64() throws IOException { 1540 // Implementation notes: 1541 // 1542 // Optimized for one-byte values, expected to be common. 1543 // The particular code below was selected from various candidates 1544 // empirically, by winning VarintBenchmark. 1545 // 1546 // Sign extension of (signed) Java bytes is usually a nuisance, but 1547 // we exploit it here to more easily obtain the sign of bytes read. 1548 // Instead of cleaning up the sign extension bits by masking eagerly, 1549 // we delay until we find the final (positive) byte, when we clear all 1550 // accumulated bits with one xor. We depend on javac to constant fold. 1551 int i = pos; 1552 1553 if (limit == i) { 1554 throw InvalidProtocolBufferException.truncatedMessage(); 1555 } 1556 1557 final byte[] buffer = this.buffer; 1558 long x; 1559 int y; 1560 if ((y = buffer[i++]) >= 0) { 1561 pos = i; 1562 return y; 1563 } else if (limit - i < 9) { 1564 return readVarint64SlowPath(); 1565 } else if ((y ^= (buffer[i++] << 7)) < 0) { 1566 x = y ^ (~0 << 7); 1567 } else if ((y ^= (buffer[i++] << 14)) >= 0) { 1568 x = y ^ ((~0 << 7) ^ (~0 << 14)); 1569 } else if ((y ^= (buffer[i++] << 21)) < 0) { 1570 x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21)); 1571 } else if ((x = y ^ ((long) buffer[i++] << 28)) >= 0L) { 1572 x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28); 1573 } else if ((x ^= ((long) buffer[i++] << 35)) < 0L) { 1574 x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35); 1575 } else if ((x ^= ((long) buffer[i++] << 42)) >= 0L) { 1576 x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42); 1577 } else if ((x ^= ((long) buffer[i++] << 49)) < 0L) { 1578 x ^= 1579 (~0L << 7) 1580 ^ (~0L << 14) 1581 ^ (~0L << 21) 1582 ^ (~0L << 28) 1583 ^ (~0L << 35) 1584 ^ (~0L << 42) 1585 ^ (~0L << 49); 1586 } else { 1587 x ^= ((long) buffer[i++] << 56); 1588 x ^= 1589 (~0L << 7) 1590 ^ (~0L << 14) 1591 ^ (~0L << 21) 1592 ^ (~0L << 28) 1593 ^ (~0L << 35) 1594 ^ (~0L << 42) 1595 ^ (~0L << 49) 1596 ^ (~0L << 56); 1597 if (x < 0L) { 1598 if (buffer[i++] < 0L) { 1599 throw InvalidProtocolBufferException.malformedVarint(); 1600 } 1601 } 1602 } 1603 pos = i; 1604 return x; 1605 } 1606 readVarint64SlowPath()1607 private long readVarint64SlowPath() throws IOException { 1608 long result = 0; 1609 for (int shift = 0; shift < 64; shift += 7) { 1610 final byte b = readByte(); 1611 result |= (long) (b & 0x7F) << shift; 1612 if ((b & 0x80) == 0) { 1613 return result; 1614 } 1615 } 1616 throw InvalidProtocolBufferException.malformedVarint(); 1617 } 1618 readByte()1619 private byte readByte() throws IOException { 1620 if (pos == limit) { 1621 throw InvalidProtocolBufferException.truncatedMessage(); 1622 } 1623 return buffer[pos++]; 1624 } 1625 readLittleEndian32()1626 private int readLittleEndian32() throws IOException { 1627 requireBytes(FIXED32_SIZE); 1628 return readLittleEndian32_NoCheck(); 1629 } 1630 readLittleEndian64()1631 private long readLittleEndian64() throws IOException { 1632 requireBytes(FIXED64_SIZE); 1633 return readLittleEndian64_NoCheck(); 1634 } 1635 readLittleEndian32_NoCheck()1636 private int readLittleEndian32_NoCheck() { 1637 int p = pos; 1638 final byte[] buffer = this.buffer; 1639 pos = p + FIXED32_SIZE; 1640 return (((buffer[p] & 0xff)) 1641 | ((buffer[p + 1] & 0xff) << 8) 1642 | ((buffer[p + 2] & 0xff) << 16) 1643 | ((buffer[p + 3] & 0xff) << 24)); 1644 } 1645 readLittleEndian64_NoCheck()1646 private long readLittleEndian64_NoCheck() { 1647 int p = pos; 1648 final byte[] buffer = this.buffer; 1649 pos = p + FIXED64_SIZE; 1650 return (((buffer[p] & 0xffL)) 1651 | ((buffer[p + 1] & 0xffL) << 8) 1652 | ((buffer[p + 2] & 0xffL) << 16) 1653 | ((buffer[p + 3] & 0xffL) << 24) 1654 | ((buffer[p + 4] & 0xffL) << 32) 1655 | ((buffer[p + 5] & 0xffL) << 40) 1656 | ((buffer[p + 6] & 0xffL) << 48) 1657 | ((buffer[p + 7] & 0xffL) << 56)); 1658 } 1659 skipVarint()1660 private void skipVarint() throws IOException { 1661 if (limit - pos >= 10) { 1662 final byte[] buffer = this.buffer; 1663 int p = pos; 1664 for (int i = 0; i < 10; i++) { 1665 if (buffer[p++] >= 0) { 1666 pos = p; 1667 return; 1668 } 1669 } 1670 } 1671 skipVarintSlowPath(); 1672 } 1673 skipVarintSlowPath()1674 private void skipVarintSlowPath() throws IOException { 1675 for (int i = 0; i < 10; i++) { 1676 if (readByte() >= 0) { 1677 return; 1678 } 1679 } 1680 throw InvalidProtocolBufferException.malformedVarint(); 1681 } 1682 skipBytes(final int size)1683 private void skipBytes(final int size) throws IOException { 1684 requireBytes(size); 1685 1686 pos += size; 1687 } 1688 skipGroup()1689 private void skipGroup() throws IOException { 1690 int prevEndGroupTag = endGroupTag; 1691 endGroupTag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WIRETYPE_END_GROUP); 1692 while (true) { 1693 if (getFieldNumber() == READ_DONE || !skipField()) { 1694 break; 1695 } 1696 } 1697 if (tag != endGroupTag) { 1698 throw InvalidProtocolBufferException.parseFailure(); 1699 } 1700 endGroupTag = prevEndGroupTag; 1701 } 1702 requireBytes(int size)1703 private void requireBytes(int size) throws IOException { 1704 if (size < 0 || size > (limit - pos)) { 1705 throw InvalidProtocolBufferException.truncatedMessage(); 1706 } 1707 } 1708 requireWireType(int requiredWireType)1709 private void requireWireType(int requiredWireType) throws IOException { 1710 if (WireFormat.getTagWireType(tag) != requiredWireType) { 1711 throw InvalidProtocolBufferException.invalidWireType(); 1712 } 1713 } 1714 verifyPackedFixed64Length(int bytes)1715 private void verifyPackedFixed64Length(int bytes) throws IOException { 1716 requireBytes(bytes); 1717 if ((bytes & FIXED64_MULTIPLE_MASK) != 0) { 1718 // Require that the number of bytes be a multiple of 8. 1719 throw InvalidProtocolBufferException.parseFailure(); 1720 } 1721 } 1722 verifyPackedFixed32Length(int bytes)1723 private void verifyPackedFixed32Length(int bytes) throws IOException { 1724 requireBytes(bytes); 1725 if ((bytes & FIXED32_MULTIPLE_MASK) != 0) { 1726 // Require that the number of bytes be a multiple of 4. 1727 throw InvalidProtocolBufferException.parseFailure(); 1728 } 1729 } 1730 requirePosition(int expectedPosition)1731 private void requirePosition(int expectedPosition) throws IOException { 1732 if (pos != expectedPosition) { 1733 throw InvalidProtocolBufferException.truncatedMessage(); 1734 } 1735 } 1736 } 1737 } 1738