Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: third_party/protobuf/src/google/protobuf/io/coded_stream.cc

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 369
370 // We have overrun the maximum size of a varint (10 bytes). Assume 370 // We have overrun the maximum size of a varint (10 bytes). Assume
371 // the data is corrupt. 371 // the data is corrupt.
372 return std::make_pair(false, ptr); 372 return std::make_pair(false, ptr);
373 373
374 done: 374 done:
375 *value = result; 375 *value = result;
376 return std::make_pair(true, ptr); 376 return std::make_pair(true, ptr);
377 } 377 }
378 378
379 GOOGLE_ATTRIBUTE_ALWAYS_INLINE::std::pair<bool, const uint8*> ReadVarint64FromAr ray(
380 const uint8* buffer, uint64* value);
381 inline ::std::pair<bool, const uint8*> ReadVarint64FromArray(
382 const uint8* buffer, uint64* value) {
383 const uint8* ptr = buffer;
384 uint32 b;
385
386 // Splitting into 32-bit pieces gives better performance on 32-bit
387 // processors.
388 uint32 part0 = 0, part1 = 0, part2 = 0;
389
390 b = *(ptr++); part0 = b ; if (!(b & 0x80)) goto done;
391 part0 -= 0x80;
392 b = *(ptr++); part0 += b << 7; if (!(b & 0x80)) goto done;
393 part0 -= 0x80 << 7;
394 b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done;
395 part0 -= 0x80 << 14;
396 b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done;
397 part0 -= 0x80 << 21;
398 b = *(ptr++); part1 = b ; if (!(b & 0x80)) goto done;
399 part1 -= 0x80;
400 b = *(ptr++); part1 += b << 7; if (!(b & 0x80)) goto done;
401 part1 -= 0x80 << 7;
402 b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done;
403 part1 -= 0x80 << 14;
404 b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done;
405 part1 -= 0x80 << 21;
406 b = *(ptr++); part2 = b ; if (!(b & 0x80)) goto done;
407 part2 -= 0x80;
408 b = *(ptr++); part2 += b << 7; if (!(b & 0x80)) goto done;
409 // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0.
410
411 // We have overrun the maximum size of a varint (10 bytes). Assume
412 // the data is corrupt.
413 return std::make_pair(false, ptr);
414
415 done:
416 *value = (static_cast<uint64>(part0)) |
417 (static_cast<uint64>(part1) << 28) |
418 (static_cast<uint64>(part2) << 56);
419 return std::make_pair(true, ptr);
420 }
421
379 } // namespace 422 } // namespace
380 423
381 bool CodedInputStream::ReadVarint32Slow(uint32* value) { 424 bool CodedInputStream::ReadVarint32Slow(uint32* value) {
382 // Directly invoke ReadVarint64Fallback, since we already tried to optimize 425 // Directly invoke ReadVarint64Fallback, since we already tried to optimize
383 // for one-byte varints. 426 // for one-byte varints.
384 std::pair<uint64, bool> p = ReadVarint64Fallback(); 427 std::pair<uint64, bool> p = ReadVarint64Fallback();
385 *value = static_cast<uint32>(p.first); 428 *value = static_cast<uint32>(p.first);
386 return p.second; 429 return p.second;
387 } 430 }
388 431
(...skipping 12 matching lines...) Expand all
401 return temp; 444 return temp;
402 } else { 445 } else {
403 // Really slow case: we will incur the cost of an extra function call here, 446 // Really slow case: we will incur the cost of an extra function call here,
404 // but moving this out of line reduces the size of this function, which 447 // but moving this out of line reduces the size of this function, which
405 // improves the common case. In micro benchmarks, this is worth about 10-15% 448 // improves the common case. In micro benchmarks, this is worth about 10-15%
406 uint32 temp; 449 uint32 temp;
407 return ReadVarint32Slow(&temp) ? static_cast<int64>(temp) : -1; 450 return ReadVarint32Slow(&temp) ? static_cast<int64>(temp) : -1;
408 } 451 }
409 } 452 }
410 453
454 int CodedInputStream::ReadVarintSizeAsIntSlow() {
455 // Directly invoke ReadVarint64Fallback, since we already tried to optimize
456 // for one-byte varints.
457 std::pair<uint64, bool> p = ReadVarint64Fallback();
458 if (!p.second || p.first > static_cast<uint64>(INT_MAX)) return -1;
459 return p.first;
460 }
461
462 int CodedInputStream::ReadVarintSizeAsIntFallback() {
463 if (BufferSize() >= kMaxVarintBytes ||
464 // Optimization: We're also safe if the buffer is non-empty and it ends
465 // with a byte that would terminate a varint.
466 (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
467 uint64 temp;
468 ::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp);
469 if (!p.first || temp > static_cast<uint64>(INT_MAX)) return -1;
470 buffer_ = p.second;
471 return temp;
472 } else {
473 // Really slow case: we will incur the cost of an extra function call here,
474 // but moving this out of line reduces the size of this function, which
475 // improves the common case. In micro benchmarks, this is worth about 10-15%
476 return ReadVarintSizeAsIntSlow();
477 }
478 }
479
411 uint32 CodedInputStream::ReadTagSlow() { 480 uint32 CodedInputStream::ReadTagSlow() {
412 if (buffer_ == buffer_end_) { 481 if (buffer_ == buffer_end_) {
413 // Call refresh. 482 // Call refresh.
414 if (!Refresh()) { 483 if (!Refresh()) {
415 // Refresh failed. Make sure that it failed due to EOF, not because 484 // Refresh failed. Make sure that it failed due to EOF, not because
416 // we hit total_bytes_limit_, which, unlike normal limits, is not a 485 // we hit total_bytes_limit_, which, unlike normal limits, is not a
417 // valid place to end a message. 486 // valid place to end a message.
418 int current_position = total_bytes_read_ - buffer_size_after_limit_; 487 int current_position = total_bytes_read_ - buffer_size_after_limit_;
419 if (current_position >= total_bytes_limit_) { 488 if (current_position >= total_bytes_limit_) {
420 // Hit total_bytes_limit_. But if we also hit the normal limit, 489 // Hit total_bytes_limit_. But if we also hit the normal limit,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 542
474 bool CodedInputStream::ReadVarint64Slow(uint64* value) { 543 bool CodedInputStream::ReadVarint64Slow(uint64* value) {
475 // Slow path: This read might cross the end of the buffer, so we 544 // Slow path: This read might cross the end of the buffer, so we
476 // need to check and refresh the buffer if and when it does. 545 // need to check and refresh the buffer if and when it does.
477 546
478 uint64 result = 0; 547 uint64 result = 0;
479 int count = 0; 548 int count = 0;
480 uint32 b; 549 uint32 b;
481 550
482 do { 551 do {
483 if (count == kMaxVarintBytes) return false; 552 if (count == kMaxVarintBytes) {
553 *value = 0;
554 return false;
555 }
484 while (buffer_ == buffer_end_) { 556 while (buffer_ == buffer_end_) {
485 if (!Refresh()) return false; 557 if (!Refresh()) {
558 *value = 0;
559 return false;
560 }
486 } 561 }
487 b = *buffer_; 562 b = *buffer_;
488 result |= static_cast<uint64>(b & 0x7F) << (7 * count); 563 result |= static_cast<uint64>(b & 0x7F) << (7 * count);
489 Advance(1); 564 Advance(1);
490 ++count; 565 ++count;
491 } while (b & 0x80); 566 } while (b & 0x80);
492 567
493 *value = result; 568 *value = result;
494 return true; 569 return true;
495 } 570 }
496 571
497 std::pair<uint64, bool> CodedInputStream::ReadVarint64Fallback() { 572 std::pair<uint64, bool> CodedInputStream::ReadVarint64Fallback() {
498 if (BufferSize() >= kMaxVarintBytes || 573 if (BufferSize() >= kMaxVarintBytes ||
499 // Optimization: We're also safe if the buffer is non-empty and it ends 574 // Optimization: We're also safe if the buffer is non-empty and it ends
500 // with a byte that would terminate a varint. 575 // with a byte that would terminate a varint.
501 (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { 576 (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
502 // Fast path: We have enough bytes left in the buffer to guarantee that 577 uint64 temp;
503 // this read won't cross the end, so we can skip the checks. 578 ::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp);
504 579 if (!p.first) {
505 const uint8* ptr = buffer_; 580 return std::make_pair(0, false);
506 uint32 b; 581 }
507 582 buffer_ = p.second;
508 // Splitting into 32-bit pieces gives better performance on 32-bit 583 return std::make_pair(temp, true);
509 // processors.
510 uint32 part0 = 0, part1 = 0, part2 = 0;
511
512 b = *(ptr++); part0 = b ; if (!(b & 0x80)) goto done;
513 part0 -= 0x80;
514 b = *(ptr++); part0 += b << 7; if (!(b & 0x80)) goto done;
515 part0 -= 0x80 << 7;
516 b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done;
517 part0 -= 0x80 << 14;
518 b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done;
519 part0 -= 0x80 << 21;
520 b = *(ptr++); part1 = b ; if (!(b & 0x80)) goto done;
521 part1 -= 0x80;
522 b = *(ptr++); part1 += b << 7; if (!(b & 0x80)) goto done;
523 part1 -= 0x80 << 7;
524 b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done;
525 part1 -= 0x80 << 14;
526 b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done;
527 part1 -= 0x80 << 21;
528 b = *(ptr++); part2 = b ; if (!(b & 0x80)) goto done;
529 part2 -= 0x80;
530 b = *(ptr++); part2 += b << 7; if (!(b & 0x80)) goto done;
531 // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0.
532
533 // We have overrun the maximum size of a varint (10 bytes). The data
534 // must be corrupt.
535 return std::make_pair(0, false);
536
537 done:
538 Advance(ptr - buffer_);
539 return std::make_pair((static_cast<uint64>(part0)) |
540 (static_cast<uint64>(part1) << 28) |
541 (static_cast<uint64>(part2) << 56),
542 true);
543 } else { 584 } else {
544 uint64 temp; 585 uint64 temp;
545 bool success = ReadVarint64Slow(&temp); 586 bool success = ReadVarint64Slow(&temp);
546 return std::make_pair(temp, success); 587 return std::make_pair(temp, success);
547 } 588 }
548 } 589 }
549 590
550 bool CodedInputStream::Refresh() { 591 bool CodedInputStream::Refresh() {
551 GOOGLE_DCHECK_EQ(0, BufferSize()); 592 GOOGLE_DCHECK_EQ(0, BufferSize());
552 593
553 if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 || 594 if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
554 total_bytes_read_ == current_limit_) { 595 total_bytes_read_ == current_limit_) {
555 // We've hit a limit. Stop. 596 // We've hit a limit. Stop.
556 int current_position = total_bytes_read_ - buffer_size_after_limit_; 597 int current_position = total_bytes_read_ - buffer_size_after_limit_;
557 598
558 if (current_position >= total_bytes_limit_ && 599 if (current_position >= total_bytes_limit_ &&
559 total_bytes_limit_ != current_limit_) { 600 total_bytes_limit_ != current_limit_) {
560 // Hit total_bytes_limit_. 601 // Hit total_bytes_limit_.
561 PrintTotalBytesLimitError(); 602 PrintTotalBytesLimitError();
562 } 603 }
563 604
564 return false; 605 return false;
565 } 606 }
566 607
567 if (total_bytes_warning_threshold_ >= 0 && 608 if (total_bytes_warning_threshold_ >= 0 &&
568 total_bytes_read_ >= total_bytes_warning_threshold_) { 609 total_bytes_read_ >= total_bytes_warning_threshold_) {
569 GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message. If th e " 610 GOOGLE_LOG(INFO) << "Reading dangerously large protocol message. If the "
570 "message turns out to be larger than " 611 "message turns out to be larger than "
571 << total_bytes_limit_ << " bytes, parsing will be halted " 612 << total_bytes_limit_ << " bytes, parsing will be halted "
572 "for security reasons. To increase the limit (or to " 613 "for security reasons. To increase the limit (or to "
573 "disable these warnings), see " 614 "disable these warnings), see "
574 "CodedInputStream::SetTotalBytesLimit() in " 615 "CodedInputStream::SetTotalBytesLimit() in "
575 "google/protobuf/io/coded_stream.h."; 616 "google/protobuf/io/coded_stream.h.";
576 617
577 // Don't warn again for this stream, and print total size at the end. 618 // Don't warn again for this stream, and print total size at the end.
578 total_bytes_warning_threshold_ = -2; 619 total_bytes_warning_threshold_ = -2;
579 } 620 }
580 621
581 const void* void_buffer; 622 const void* void_buffer;
582 int buffer_size; 623 int buffer_size;
583 if (NextNonEmpty(input_, &void_buffer, &buffer_size)) { 624 if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
584 buffer_ = reinterpret_cast<const uint8*>(void_buffer); 625 buffer_ = reinterpret_cast<const uint8*>(void_buffer);
585 buffer_end_ = buffer_ + buffer_size; 626 buffer_end_ = buffer_ + buffer_size;
(...skipping 21 matching lines...) Expand all
607 return true; 648 return true;
608 } else { 649 } else {
609 buffer_ = NULL; 650 buffer_ = NULL;
610 buffer_end_ = NULL; 651 buffer_end_ = NULL;
611 return false; 652 return false;
612 } 653 }
613 } 654 }
614 655
615 // CodedOutputStream ================================================= 656 // CodedOutputStream =================================================
616 657
658 bool CodedOutputStream::default_serialization_deterministic_ = false;
659
617 CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output) 660 CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
618 : output_(output), 661 : output_(output),
619 buffer_(NULL), 662 buffer_(NULL),
620 buffer_size_(0), 663 buffer_size_(0),
621 total_bytes_(0), 664 total_bytes_(0),
622 had_error_(false), 665 had_error_(false),
623 aliasing_enabled_(false) { 666 aliasing_enabled_(false),
667 serialization_deterministic_is_overridden_(false) {
624 // Eagerly Refresh() so buffer space is immediately available. 668 // Eagerly Refresh() so buffer space is immediately available.
625 Refresh(); 669 Refresh();
626 // The Refresh() may have failed. If the client doesn't write any data, 670 // The Refresh() may have failed. If the client doesn't write any data,
627 // though, don't consider this an error. If the client does write data, then 671 // though, don't consider this an error. If the client does write data, then
628 // another Refresh() will be attempted and it will set the error once again. 672 // another Refresh() will be attempted and it will set the error once again.
629 had_error_ = false; 673 had_error_ = false;
630 } 674 }
631 675
632 CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output, 676 CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output,
633 bool do_eager_refresh) 677 bool do_eager_refresh)
634 : output_(output), 678 : output_(output),
635 buffer_(NULL), 679 buffer_(NULL),
636 buffer_size_(0), 680 buffer_size_(0),
637 total_bytes_(0), 681 total_bytes_(0),
638 had_error_(false), 682 had_error_(false),
639 aliasing_enabled_(false) { 683 aliasing_enabled_(false),
684 serialization_deterministic_is_overridden_(false) {
640 if (do_eager_refresh) { 685 if (do_eager_refresh) {
641 // Eagerly Refresh() so buffer space is immediately available. 686 // Eagerly Refresh() so buffer space is immediately available.
642 Refresh(); 687 Refresh();
643 // The Refresh() may have failed. If the client doesn't write any data, 688 // The Refresh() may have failed. If the client doesn't write any data,
644 // though, don't consider this an error. If the client does write data, then 689 // though, don't consider this an error. If the client does write data, then
645 // another Refresh() will be attempted and it will set the error once again. 690 // another Refresh() will be attempted and it will set the error once again.
646 had_error_ = false; 691 had_error_ = false;
647 } 692 }
648 } 693 }
649 694
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 } 787 }
743 788
744 void CodedOutputStream::WriteVarint32SlowPath(uint32 value) { 789 void CodedOutputStream::WriteVarint32SlowPath(uint32 value) {
745 uint8 bytes[kMaxVarint32Bytes]; 790 uint8 bytes[kMaxVarint32Bytes];
746 uint8* target = &bytes[0]; 791 uint8* target = &bytes[0];
747 uint8* end = WriteVarint32ToArray(value, target); 792 uint8* end = WriteVarint32ToArray(value, target);
748 int size = end - target; 793 int size = end - target;
749 WriteRaw(bytes, size); 794 WriteRaw(bytes, size);
750 } 795 }
751 796
752 inline uint8* CodedOutputStream::WriteVarint64ToArrayInline( 797 void CodedOutputStream::WriteVarint64SlowPath(uint64 value) {
753 uint64 value, uint8* target) { 798 uint8 bytes[kMaxVarintBytes];
754 // Splitting into 32-bit pieces gives better performance on 32-bit 799 uint8* target = &bytes[0];
755 // processors. 800 uint8* end = WriteVarint64ToArray(value, target);
756 uint32 part0 = static_cast<uint32>(value ); 801 int size = end - target;
757 uint32 part1 = static_cast<uint32>(value >> 28); 802 WriteRaw(bytes, size);
758 uint32 part2 = static_cast<uint32>(value >> 56);
759
760 int size;
761
762 // Here we can't really optimize for small numbers, since the value is
763 // split into three parts. Cheking for numbers < 128, for instance,
764 // would require three comparisons, since you'd have to make sure part1
765 // and part2 are zero. However, if the caller is using 64-bit integers,
766 // it is likely that they expect the numbers to often be very large, so
767 // we probably don't want to optimize for small numbers anyway. Thus,
768 // we end up with a hardcoded binary search tree...
769 if (part2 == 0) {
770 if (part1 == 0) {
771 if (part0 < (1 << 14)) {
772 if (part0 < (1 << 7)) {
773 size = 1; goto size1;
774 } else {
775 size = 2; goto size2;
776 }
777 } else {
778 if (part0 < (1 << 21)) {
779 size = 3; goto size3;
780 } else {
781 size = 4; goto size4;
782 }
783 }
784 } else {
785 if (part1 < (1 << 14)) {
786 if (part1 < (1 << 7)) {
787 size = 5; goto size5;
788 } else {
789 size = 6; goto size6;
790 }
791 } else {
792 if (part1 < (1 << 21)) {
793 size = 7; goto size7;
794 } else {
795 size = 8; goto size8;
796 }
797 }
798 }
799 } else {
800 if (part2 < (1 << 7)) {
801 size = 9; goto size9;
802 } else {
803 size = 10; goto size10;
804 }
805 }
806
807 GOOGLE_LOG(FATAL) << "Can't get here.";
808
809 size10: target[9] = static_cast<uint8>((part2 >> 7) | 0x80);
810 size9 : target[8] = static_cast<uint8>((part2 ) | 0x80);
811 size8 : target[7] = static_cast<uint8>((part1 >> 21) | 0x80);
812 size7 : target[6] = static_cast<uint8>((part1 >> 14) | 0x80);
813 size6 : target[5] = static_cast<uint8>((part1 >> 7) | 0x80);
814 size5 : target[4] = static_cast<uint8>((part1 ) | 0x80);
815 size4 : target[3] = static_cast<uint8>((part0 >> 21) | 0x80);
816 size3 : target[2] = static_cast<uint8>((part0 >> 14) | 0x80);
817 size2 : target[1] = static_cast<uint8>((part0 >> 7) | 0x80);
818 size1 : target[0] = static_cast<uint8>((part0 ) | 0x80);
819
820 target[size-1] &= 0x7F;
821 return target + size;
822 }
823
824 void CodedOutputStream::WriteVarint64(uint64 value) {
825 if (buffer_size_ >= kMaxVarintBytes) {
826 // Fast path: We have enough bytes left in the buffer to guarantee that
827 // this write won't cross the end, so we can skip the checks.
828 uint8* target = buffer_;
829
830 uint8* end = WriteVarint64ToArrayInline(value, target);
831 int size = end - target;
832 Advance(size);
833 } else {
834 // Slow path: This write might cross the end of the buffer, so we
835 // compose the bytes first then use WriteRaw().
836 uint8 bytes[kMaxVarintBytes];
837 int size = 0;
838 while (value > 0x7F) {
839 bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
840 value >>= 7;
841 }
842 bytes[size++] = static_cast<uint8>(value) & 0x7F;
843 WriteRaw(bytes, size);
844 }
845 }
846
847 uint8* CodedOutputStream::WriteVarint64ToArray(
848 uint64 value, uint8* target) {
849 return WriteVarint64ToArrayInline(value, target);
850 } 803 }
851 804
852 bool CodedOutputStream::Refresh() { 805 bool CodedOutputStream::Refresh() {
853 void* void_buffer; 806 void* void_buffer;
854 if (output_->Next(&void_buffer, &buffer_size_)) { 807 if (output_->Next(&void_buffer, &buffer_size_)) {
855 buffer_ = reinterpret_cast<uint8*>(void_buffer); 808 buffer_ = reinterpret_cast<uint8*>(void_buffer);
856 total_bytes_ += buffer_size_; 809 total_bytes_ += buffer_size_;
857 return true; 810 return true;
858 } else { 811 } else {
859 buffer_ = NULL; 812 buffer_ = NULL;
860 buffer_size_ = 0; 813 buffer_size_ = 0;
861 had_error_ = true; 814 had_error_ = true;
862 return false; 815 return false;
863 } 816 }
864 } 817 }
865 818
866 int CodedOutputStream::VarintSize32Fallback(uint32 value) { 819 size_t CodedOutputStream::VarintSize32Fallback(uint32 value) {
867 if (value < (1 << 7)) { 820 // This computes floor(log2(value)) / 7 + 1
868 return 1; 821 // Use an explicit multiplication to implement the divide of
869 } else if (value < (1 << 14)) { 822 // a number in the 1..31 range.
870 return 2; 823 GOOGLE_DCHECK_NE(0, value); // This is enforced by our caller.
871 } else if (value < (1 << 21)) { 824
872 return 3; 825 uint32 log2value = Bits::Log2FloorNonZero(value);
873 } else if (value < (1 << 28)) { 826 return static_cast<size_t>((log2value * 9 + 73) / 64);
874 return 4;
875 } else {
876 return 5;
877 }
878 } 827 }
879 828
880 int CodedOutputStream::VarintSize64(uint64 value) { 829 size_t CodedOutputStream::VarintSize64(uint64 value) {
881 if (value < (1ull << 35)) { 830 // This computes value == 0 ? 1 : floor(log2(value)) / 7 + 1
882 if (value < (1ull << 7)) { 831 // Use an explicit multiplication to implement the divide of
883 return 1; 832 // a number in the 1..63 range.
884 } else if (value < (1ull << 14)) { 833 // Explicit OR 0x1 to avoid calling clz(0), which is undefined.
885 return 2; 834 uint32 log2value = Bits::Log2FloorNonZero64(value | 0x1);
886 } else if (value < (1ull << 21)) { 835 return static_cast<size_t>((log2value * 9 + 73) / 64);
887 return 3;
888 } else if (value < (1ull << 28)) {
889 return 4;
890 } else {
891 return 5;
892 }
893 } else {
894 if (value < (1ull << 42)) {
895 return 6;
896 } else if (value < (1ull << 49)) {
897 return 7;
898 } else if (value < (1ull << 56)) {
899 return 8;
900 } else if (value < (1ull << 63)) {
901 return 9;
902 } else {
903 return 10;
904 }
905 }
906 } 836 }
907 837
908 uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str, 838 uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str,
909 uint8* target) { 839 uint8* target) {
910 GOOGLE_DCHECK_LE(str.size(), kuint32max); 840 GOOGLE_DCHECK_LE(str.size(), kuint32max);
911 target = WriteVarint32ToArray(str.size(), target); 841 target = WriteVarint32ToArray(str.size(), target);
912 return WriteStringToArray(str, target); 842 return WriteStringToArray(str, target);
913 } 843 }
914 844
915 } // namespace io 845 } // namespace io
916 } // namespace protobuf 846 } // namespace protobuf
917 } // namespace google 847 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698