1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// https://developers.google.com/protocol-buffers/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Based on original Protocol Buffers design by 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sanjay Ghemawat, Jeff Dean, and others. 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This implementation is heavily optimized to make reads and writes 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// of small values (especially varints) as fast as possible. In 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// particular, we optimize for the common case that a read or a write 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// will not cross the end of the buffer, since we can avoid a lot 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// of branching in this case. 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 41d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/io/coded_stream_inl.h> 42d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <algorithm> 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <limits.h> 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream.h> 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h> 46a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <google/protobuf/stubs/stl_util.h> 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace io { 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const int kMaxVarintBytes = 10; 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const int kMaxVarint32Bytes = 5; 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 59a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsoninline bool NextNonEmpty(ZeroCopyInputStream* input, 60a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const void** data, int* size) { 61a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson bool success; 62a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson do { 63a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson success = input->Next(data, size); 64a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } while (success && *size == 0); 65a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return success; 66a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 67a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// CodedInputStream ================================================== 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 72a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonCodedInputStream::~CodedInputStream() { 73a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (input_ != NULL) { 74a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson BackUpInputToCurrentPosition(); 75a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 76a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 77a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (total_bytes_warning_threshold_ == -2) { 78a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_LOG(WARNING) << "The total number of bytes read was " << total_bytes_read_; 79a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 80a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 81a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 82a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Static. 83a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonint CodedInputStream::default_recursion_limit_ = 100; 84a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 85a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 86a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid CodedOutputStream::EnableAliasing(bool enabled) { 87a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson aliasing_enabled_ = enabled && output_->AllowsAliasing(); 88a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedInputStream::BackUpInputToCurrentPosition() { 91d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_; 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (backup_bytes > 0) { 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville input_->BackUp(backup_bytes); 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // total_bytes_read_ doesn't include overflow_bytes_. 96d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville total_bytes_read_ -= BufferSize() + buffer_size_after_limit_; 97d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer_end_ = buffer_; 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_size_after_limit_ = 0; 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville overflow_bytes_ = 0; 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline void CodedInputStream::RecomputeBufferLimits() { 104d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer_end_ += buffer_size_after_limit_; 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int closest_limit = min(current_limit_, total_bytes_limit_); 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (closest_limit < total_bytes_read_) { 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The limit position is in the current buffer. We must adjust 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the buffer size accordingly. 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_size_after_limit_ = total_bytes_read_ - closest_limit; 110d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer_end_ -= buffer_size_after_limit_; 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_size_after_limit_ = 0; 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) { 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Current position relative to the beginning of the stream. 118a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int current_position = CurrentPosition(); 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Limit old_limit = current_limit_; 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // security: byte_limit is possibly evil, so check for negative values 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // and overflow. 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (byte_limit >= 0 && 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville byte_limit <= INT_MAX - current_position) { 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville current_limit_ = current_position + byte_limit; 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Negative or overflow. 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville current_limit_ = INT_MAX; 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We need to enforce all limits, not just the new one, so if the previous 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // limit was before the new requested limit, we continue to enforce the 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // previous limit. 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville current_limit_ = min(current_limit_, old_limit); 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RecomputeBufferLimits(); 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return old_limit; 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedInputStream::PopLimit(Limit limit) { 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The limit passed in is actually the *old* limit, which we returned from 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // PushLimit(). 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville current_limit_ = limit; 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RecomputeBufferLimits(); 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We may no longer be at a legitimate message end. ReadTag() needs to be 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // called again to find out. 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville legitimate_message_end_ = false; 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 152a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonint CodedInputStream::BytesUntilLimit() const { 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (current_limit_ == INT_MAX) return -1; 154a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int current_position = CurrentPosition(); 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return current_limit_ - current_position; 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedInputStream::SetTotalBytesLimit( 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int total_bytes_limit, int warning_threshold) { 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Make sure the limit isn't already past, since this could confuse other 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // code. 163a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int current_position = CurrentPosition(); 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville total_bytes_limit_ = max(current_position, total_bytes_limit); 165a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (warning_threshold >= 0) { 166a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson total_bytes_warning_threshold_ = warning_threshold; 167a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 168a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // warning_threshold is negative 169a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson total_bytes_warning_threshold_ = -1; 170a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RecomputeBufferLimits(); 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 174a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonint CodedInputStream::BytesUntilTotalBytesLimit() const { 175a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (total_bytes_limit_ == INT_MAX) return -1; 176a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return total_bytes_limit_ - CurrentPosition(); 177a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 178a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedInputStream::PrintTotalBytesLimitError() { 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too " 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "big (more than " << total_bytes_limit_ 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << " bytes). To increase the limit (or to disable these " 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "warnings), see CodedInputStream::SetTotalBytesLimit() " 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "in google/protobuf/io/coded_stream.h."; 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::Skip(int count) { 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (count < 0) return false; // security: count is often user-supplied 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 190d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const int original_buffer_size = BufferSize(); 191d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 192d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (count <= original_buffer_size) { 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Just skipping within the current buffer. Easy. 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(count); 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (buffer_size_after_limit_ > 0) { 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We hit a limit inside this buffer. Advance to the limit and fail. 200d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Advance(original_buffer_size); 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 204d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville count -= original_buffer_size; 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_ = NULL; 206d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer_end_ = buffer_; 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Make sure this skip doesn't try to skip past the current limit. 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int closest_limit = min(current_limit_, total_bytes_limit_); 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int bytes_until_limit = closest_limit - total_bytes_read_; 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (bytes_until_limit < count) { 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We hit the limit. Skip up to it then fail. 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (bytes_until_limit > 0) { 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville total_bytes_read_ = closest_limit; 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville input_->Skip(bytes_until_limit); 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville total_bytes_read_ += count; 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return input_->Skip(count); 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) { 225d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (BufferSize() == 0 && !Refresh()) return false; 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *data = buffer_; 228d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville *size = BufferSize(); 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::ReadRaw(void* buffer, int size) { 233d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int current_buffer_size; 234d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while ((current_buffer_size = BufferSize()) < size) { 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Reading past end of buffer. Copy what we have, then refresh. 236d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville memcpy(buffer, buffer_, current_buffer_size); 237d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer = reinterpret_cast<uint8*>(buffer) + current_buffer_size; 238d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville size -= current_buffer_size; 239d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Advance(current_buffer_size); 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!Refresh()) return false; 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memcpy(buffer, buffer_, size); 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(size); 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::ReadString(string* buffer, int size) { 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (size < 0) return false; // security: size is often user-supplied 251d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return InternalReadStringInline(buffer, size); 252d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 254d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillebool CodedInputStream::ReadStringFallback(string* buffer, int size) { 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!buffer->empty()) { 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer->clear(); 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 259a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int closest_limit = min(current_limit_, total_bytes_limit_); 260a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (closest_limit != INT_MAX) { 261a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int bytes_to_limit = closest_limit - CurrentPosition(); 262a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (bytes_to_limit > 0 && size > 0 && size <= bytes_to_limit) { 263a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson buffer->reserve(size); 264a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 265a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 266a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 267d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int current_buffer_size; 268d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while ((current_buffer_size = BufferSize()) < size) { 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Some STL implementations "helpfully" crash on buffer->append(NULL, 0). 270d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (current_buffer_size != 0) { 271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note: string1.append(string2) is O(string2.size()) (as opposed to 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // O(string1.size() + string2.size()), which would be bad). 273d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer->append(reinterpret_cast<const char*>(buffer_), 274d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville current_buffer_size); 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 276d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville size -= current_buffer_size; 277d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Advance(current_buffer_size); 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!Refresh()) return false; 279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer->append(reinterpret_cast<const char*>(buffer_), size); 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(size); 283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 288d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillebool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) { 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 bytes[sizeof(*value)]; 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const uint8* ptr; 292d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (BufferSize() >= sizeof(*value)) { 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fast path: Enough bytes in the buffer to read directly. 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ptr = buffer_; 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(sizeof(*value)); 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Slow path: Had to read past the end of the buffer. 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!ReadRaw(bytes, sizeof(*value))) return false; 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ptr = bytes; 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 301d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ReadLittleEndian32FromArray(ptr, value); 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 305d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillebool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) { 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 bytes[sizeof(*value)]; 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const uint8* ptr; 309d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (BufferSize() >= sizeof(*value)) { 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fast path: Enough bytes in the buffer to read directly. 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ptr = buffer_; 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(sizeof(*value)); 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Slow path: Had to read past the end of the buffer. 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!ReadRaw(bytes, sizeof(*value))) return false; 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ptr = bytes; 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 318d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ReadLittleEndian64FromArray(ptr, value); 319d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return true; 320d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 321d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 322d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillenamespace { 323d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 324d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleinline const uint8* ReadVarint32FromArray( 325d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const uint8* buffer, uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; 326d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleinline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) { 327d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Fast path: We have enough bytes left in the buffer to guarantee that 328d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // this read won't cross the end, so we can skip the checks. 329d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const uint8* ptr = buffer; 330d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint32 b; 331d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint32 result; 332d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 333a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); result = b ; if (!(b & 0x80)) goto done; 334a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result -= 0x80; 335a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); result += b << 7; if (!(b & 0x80)) goto done; 336a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result -= 0x80 << 7; 337a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); result += b << 14; if (!(b & 0x80)) goto done; 338a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result -= 0x80 << 14; 339a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); result += b << 21; if (!(b & 0x80)) goto done; 340a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result -= 0x80 << 21; 341a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); result += b << 28; if (!(b & 0x80)) goto done; 342a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // "result -= 0x80 << 28" is irrevelant. 343d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 344d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // If the input is larger than 32 bits, we still need to read it all 345d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // and discard the high-order bits. 346d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) { 347d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville b = *(ptr++); if (!(b & 0x80)) goto done; 348d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 349d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 350d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // We have overrun the maximum size of a varint (10 bytes). Assume 351d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // the data is corrupt. 352d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return NULL; 353d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 354d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville done: 355d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville *value = result; 356d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return ptr; 357d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 359d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} // namespace 360d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 361d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillebool CodedInputStream::ReadVarint32Slow(uint32* value) { 362d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint64 result; 363d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Directly invoke ReadVarint64Fallback, since we already tried to optimize 364d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // for one-byte varints. 365d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (!ReadVarint64Fallback(&result)) return false; 366d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville *value = (uint32)result; 367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::ReadVarint32Fallback(uint32* value) { 371d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (BufferSize() >= kMaxVarintBytes || 372a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Optimization: We're also safe if the buffer is non-empty and it ends 373a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // with a byte that would terminate a varint. 374d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { 375d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const uint8* end = ReadVarint32FromArray(buffer_, value); 376d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (end == NULL) return false; 377d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer_ = end; 378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 380d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Really slow case: we will incur the cost of an extra function call here, 381d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // but moving this out of line reduces the size of this function, which 382d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // improves the common case. In micro benchmarks, this is worth about 10-15% 383d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return ReadVarint32Slow(value); 384d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 385d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 387d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleuint32 CodedInputStream::ReadTagSlow() { 388d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (buffer_ == buffer_end_) { 389d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Call refresh. 390d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (!Refresh()) { 391d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Refresh failed. Make sure that it failed due to EOF, not because 392d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // we hit total_bytes_limit_, which, unlike normal limits, is not a 393d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // valid place to end a message. 394d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int current_position = total_bytes_read_ - buffer_size_after_limit_; 395d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (current_position >= total_bytes_limit_) { 396d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Hit total_bytes_limit_. But if we also hit the normal limit, 397d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // we're still OK. 398d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville legitimate_message_end_ = current_limit_ == total_bytes_limit_; 399d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 400d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville legitimate_message_end_ = true; 401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 402d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return 0; 403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 404d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 406d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags 407d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // again, since we have now refreshed the buffer. 408a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson uint64 result = 0; 409d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (!ReadVarint64(&result)) return 0; 410d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return static_cast<uint32>(result); 411d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 412d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 413d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleuint32 CodedInputStream::ReadTagFallback() { 414a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const int buf_size = BufferSize(); 415a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (buf_size >= kMaxVarintBytes || 416a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Optimization: We're also safe if the buffer is non-empty and it ends 417a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // with a byte that would terminate a varint. 418a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson (buf_size > 0 && !(buffer_end_[-1] & 0x80))) { 419d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint32 tag; 420d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const uint8* end = ReadVarint32FromArray(buffer_, &tag); 421d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (end == NULL) { 422d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return 0; 423d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 424d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer_ = end; 425d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return tag; 426d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 427d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // We are commonly at a limit when attempting to read tags. Try to quickly 428d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // detect this case without making another function call. 429a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if ((buf_size == 0) && 430a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ((buffer_size_after_limit_ > 0) || 431a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson (total_bytes_read_ == current_limit_)) && 432d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Make sure that the limit we hit is not total_bytes_limit_, since 433d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // in that case we still need to call Refresh() so that it prints an 434d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // error. 435d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) { 436d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // We hit a byte limit. 437d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville legitimate_message_end_ = true; 438d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return 0; 439d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 440d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return ReadTagSlow(); 441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 444d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillebool CodedInputStream::ReadVarint64Slow(uint64* value) { 445d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Slow path: This read might cross the end of the buffer, so we 446d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // need to check and refresh the buffer if and when it does. 447d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 448d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint64 result = 0; 449d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int count = 0; 450d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville uint32 b; 451d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 452d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville do { 453d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (count == kMaxVarintBytes) return false; 454d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville while (buffer_ == buffer_end_) { 455d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (!Refresh()) return false; 456d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 457d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville b = *buffer_; 458d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result |= static_cast<uint64>(b & 0x7F) << (7 * count); 459d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Advance(1); 460d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ++count; 461d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } while (b & 0x80); 462d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 463d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville *value = result; 464d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return true; 465d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 466d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 467d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillebool CodedInputStream::ReadVarint64Fallback(uint64* value) { 468d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (BufferSize() >= kMaxVarintBytes || 469a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Optimization: We're also safe if the buffer is non-empty and it ends 470a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // with a byte that would terminate a varint. 471d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) { 472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fast path: We have enough bytes left in the buffer to guarantee that 473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // this read won't cross the end, so we can skip the checks. 474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const uint8* ptr = buffer_; 476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint32 b; 477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Splitting into 32-bit pieces gives better performance on 32-bit 479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // processors. 480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint32 part0 = 0, part1 = 0, part2 = 0; 481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 482a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); part0 = b ; if (!(b & 0x80)) goto done; 483a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson part0 -= 0x80; 484a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); part0 += b << 7; if (!(b & 0x80)) goto done; 485a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson part0 -= 0x80 << 7; 486a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done; 487a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson part0 -= 0x80 << 14; 488a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done; 489a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson part0 -= 0x80 << 21; 490a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); part1 = b ; if (!(b & 0x80)) goto done; 491a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson part1 -= 0x80; 492a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); part1 += b << 7; if (!(b & 0x80)) goto done; 493a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson part1 -= 0x80 << 7; 494a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done; 495a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson part1 -= 0x80 << 14; 496a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done; 497a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson part1 -= 0x80 << 21; 498a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); part2 = b ; if (!(b & 0x80)) goto done; 499a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson part2 -= 0x80; 500a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson b = *(ptr++); part2 += b << 7; if (!(b & 0x80)) goto done; 501a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0. 502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We have overrun the maximum size of a varint (10 bytes). The data 504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // must be corrupt. 505a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return false; 506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville done: 508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(ptr - buffer_); 509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *value = (static_cast<uint64>(part0) ) | 510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (static_cast<uint64>(part1) << 28) | 511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (static_cast<uint64>(part2) << 56); 512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 514d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return ReadVarint64Slow(value); 515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::Refresh() { 519d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville GOOGLE_DCHECK_EQ(0, BufferSize()); 520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 || 522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville total_bytes_read_ == current_limit_) { 523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We've hit a limit. Stop. 524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int current_position = total_bytes_read_ - buffer_size_after_limit_; 525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (current_position >= total_bytes_limit_ && 527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville total_bytes_limit_ != current_limit_) { 528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Hit total_bytes_limit_. 529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PrintTotalBytesLimitError(); 530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (total_bytes_warning_threshold_ >= 0 && 536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville total_bytes_read_ >= total_bytes_warning_threshold_) { 537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message. If the " 538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message turns out to be larger than " 539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << total_bytes_limit_ << " bytes, parsing will be halted " 540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "for security reasons. To increase the limit (or to " 541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "disable these warnings), see " 542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "CodedInputStream::SetTotalBytesLimit() in " 543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "google/protobuf/io/coded_stream.h."; 544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 545a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Don't warn again for this stream, and print total size at the end. 546a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson total_bytes_warning_threshold_ = -2; 547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* void_buffer; 550d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int buffer_size; 551a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (NextNonEmpty(input_, &void_buffer, &buffer_size)) { 552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_ = reinterpret_cast<const uint8*>(void_buffer); 553d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer_end_ = buffer_ + buffer_size; 554d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville GOOGLE_CHECK_GE(buffer_size, 0); 555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 556d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (total_bytes_read_ <= INT_MAX - buffer_size) { 557d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville total_bytes_read_ += buffer_size; 558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 559d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Overflow. Reset buffer_end_ to not include the bytes beyond INT_MAX. 560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We can't get that far anyway, because total_bytes_limit_ is guaranteed 561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // to be less than it. We need to keep track of the number of bytes 562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we discarded, though, so that we can call input_->BackUp() to back 563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // up over them on destruction. 564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The following line is equivalent to: 566d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // overflow_bytes_ = total_bytes_read_ + buffer_size - INT_MAX; 567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // except that it avoids overflows. Signed integer overflow has 568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // undefined results according to the C standard. 569d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size); 570d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer_end_ -= overflow_bytes_; 571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville total_bytes_read_ = INT_MAX; 572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville RecomputeBufferLimits(); 575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_ = NULL; 578d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville buffer_end_ = NULL; 579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// CodedOutputStream ================================================= 584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output) 586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : output_(output), 587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_(NULL), 588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_size_(0), 589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville total_bytes_(0), 590a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson had_error_(false), 591a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson aliasing_enabled_(false) { 592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Eagerly Refresh() so buffer space is immediately available. 593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Refresh(); 594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The Refresh() may have failed. If the client doesn't write any data, 595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // though, don't consider this an error. If the client does write data, then 596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // another Refresh() will be attempted and it will set the error once again. 597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville had_error_ = false; 598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCodedOutputStream::~CodedOutputStream() { 601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (buffer_size_ > 0) { 602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output_->BackUp(buffer_size_); 603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedOutputStream::Skip(int count) { 607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (count < 0) return false; 608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (count > buffer_size_) { 610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville count -= buffer_size_; 611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!Refresh()) return false; 612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(count); 615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) { 619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (buffer_size_ == 0 && !Refresh()) return false; 620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *data = buffer_; 622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *size = buffer_size_; 623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedOutputStream::WriteRaw(const void* data, int size) { 627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (buffer_size_ < size) { 628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memcpy(buffer_, data, buffer_size_); 629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size -= buffer_size_; 630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville data = reinterpret_cast<const uint8*>(data) + buffer_size_; 631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!Refresh()) return; 632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memcpy(buffer_, data, size); 635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(size); 636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleuint8* CodedOutputStream::WriteRawToArray( 639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* data, int size, uint8* target) { 640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memcpy(target, data, size); 641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return target + size; 642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 645a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid CodedOutputStream::WriteAliasedRaw(const void* data, int size) { 646a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (size < buffer_size_ 647a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ) { 648a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson WriteRaw(data, size); 649a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 650a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (buffer_size_ > 0) { 651a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output_->BackUp(buffer_size_); 652a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson total_bytes_ -= buffer_size_; 653a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson buffer_ = NULL; 654a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson buffer_size_ = 0; 655a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 656a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 657a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson total_bytes_ += size; 658a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson had_error_ |= !output_->WriteAliasedRaw(data, size); 659a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 660a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 661a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedOutputStream::WriteLittleEndian32(uint32 value) { 663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 bytes[sizeof(value)]; 664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool use_fast = buffer_size_ >= sizeof(value); 666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* ptr = use_fast ? buffer_ : bytes; 667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteLittleEndian32ToArray(value, ptr); 669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (use_fast) { 671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(sizeof(value)); 672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteRaw(bytes, sizeof(value)); 674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedOutputStream::WriteLittleEndian64(uint64 value) { 678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 bytes[sizeof(value)]; 679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool use_fast = buffer_size_ >= sizeof(value); 681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* ptr = use_fast ? buffer_ : bytes; 682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteLittleEndian64ToArray(value, ptr); 684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (use_fast) { 686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(sizeof(value)); 687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteRaw(bytes, sizeof(value)); 689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline( 693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint32 value, uint8* target) { 694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville target[0] = static_cast<uint8>(value | 0x80); 695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value >= (1 << 7)) { 696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville target[1] = static_cast<uint8>((value >> 7) | 0x80); 697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value >= (1 << 14)) { 698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville target[2] = static_cast<uint8>((value >> 14) | 0x80); 699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value >= (1 << 21)) { 700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville target[3] = static_cast<uint8>((value >> 21) | 0x80); 701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value >= (1 << 28)) { 702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville target[4] = static_cast<uint8>(value >> 28); 703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return target + 5; 704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville target[3] &= 0x7F; 706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return target + 4; 707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville target[2] &= 0x7F; 710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return target + 3; 711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville target[1] &= 0x7F; 714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return target + 2; 715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville target[0] &= 0x7F; 718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return target + 1; 719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedOutputStream::WriteVarint32(uint32 value) { 723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (buffer_size_ >= kMaxVarint32Bytes) { 724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fast path: We have enough bytes left in the buffer to guarantee that 725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // this write won't cross the end, so we can skip the checks. 726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* target = buffer_; 727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* end = WriteVarint32FallbackToArrayInline(value, target); 728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size = end - target; 729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(size); 730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Slow path: This write might cross the end of the buffer, so we 732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // compose the bytes first then use WriteRaw(). 733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 bytes[kMaxVarint32Bytes]; 734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size = 0; 735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (value > 0x7F) { 736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80; 737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value >>= 7; 738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bytes[size++] = static_cast<uint8>(value) & 0x7F; 740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteRaw(bytes, size); 741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleuint8* CodedOutputStream::WriteVarint32FallbackToArray( 745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint32 value, uint8* target) { 746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return WriteVarint32FallbackToArrayInline(value, target); 747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline uint8* CodedOutputStream::WriteVarint64ToArrayInline( 750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint64 value, uint8* target) { 751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Splitting into 32-bit pieces gives better performance on 32-bit 752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // processors. 753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint32 part0 = static_cast<uint32>(value ); 754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint32 part1 = static_cast<uint32>(value >> 28); 755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint32 part2 = static_cast<uint32>(value >> 56); 756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Here we can't really optimize for small numbers, since the value is 760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // split into three parts. Cheking for numbers < 128, for instance, 761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // would require three comparisons, since you'd have to make sure part1 762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // and part2 are zero. However, if the caller is using 64-bit integers, 763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // it is likely that they expect the numbers to often be very large, so 764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we probably don't want to optimize for small numbers anyway. Thus, 765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we end up with a hardcoded binary search tree... 766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (part2 == 0) { 767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (part1 == 0) { 768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (part0 < (1 << 14)) { 769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (part0 < (1 << 7)) { 770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 1; goto size1; 771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 2; goto size2; 773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (part0 < (1 << 21)) { 776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 3; goto size3; 777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 4; goto size4; 779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (part1 < (1 << 14)) { 783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (part1 < (1 << 7)) { 784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 5; goto size5; 785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 6; goto size6; 787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (part1 < (1 << 21)) { 790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 7; goto size7; 791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 8; goto size8; 793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (part2 < (1 << 7)) { 798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 9; goto size9; 799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = 10; goto size10; 801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "Can't get here."; 805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size10: target[9] = static_cast<uint8>((part2 >> 7) | 0x80); 807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size9 : target[8] = static_cast<uint8>((part2 ) | 0x80); 808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size8 : target[7] = static_cast<uint8>((part1 >> 21) | 0x80); 809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size7 : target[6] = static_cast<uint8>((part1 >> 14) | 0x80); 810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size6 : target[5] = static_cast<uint8>((part1 >> 7) | 0x80); 811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size5 : target[4] = static_cast<uint8>((part1 ) | 0x80); 812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size4 : target[3] = static_cast<uint8>((part0 >> 21) | 0x80); 813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size3 : target[2] = static_cast<uint8>((part0 >> 14) | 0x80); 814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size2 : target[1] = static_cast<uint8>((part0 >> 7) | 0x80); 815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size1 : target[0] = static_cast<uint8>((part0 ) | 0x80); 816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville target[size-1] &= 0x7F; 818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return target + size; 819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedOutputStream::WriteVarint64(uint64 value) { 822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (buffer_size_ >= kMaxVarintBytes) { 823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fast path: We have enough bytes left in the buffer to guarantee that 824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // this write won't cross the end, so we can skip the checks. 825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* target = buffer_; 826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* end = WriteVarint64ToArrayInline(value, target); 828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size = end - target; 829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Advance(size); 830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Slow path: This write might cross the end of the buffer, so we 832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // compose the bytes first then use WriteRaw(). 833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 bytes[kMaxVarintBytes]; 834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size = 0; 835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (value > 0x7F) { 836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80; 837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value >>= 7; 838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bytes[size++] = static_cast<uint8>(value) & 0x7F; 840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteRaw(bytes, size); 841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleuint8* CodedOutputStream::WriteVarint64ToArray( 845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint64 value, uint8* target) { 846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return WriteVarint64ToArrayInline(value, target); 847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 849fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedOutputStream::Refresh() { 850fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void* void_buffer; 851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (output_->Next(&void_buffer, &buffer_size_)) { 852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_ = reinterpret_cast<uint8*>(void_buffer); 853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville total_bytes_ += buffer_size_; 854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_ = NULL; 857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_size_ = 0; 858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville had_error_ = true; 859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint CodedOutputStream::VarintSize32Fallback(uint32 value) { 864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value < (1 << 7)) { 865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 1; 866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value < (1 << 14)) { 867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 2; 868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value < (1 << 21)) { 869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 3; 870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value < (1 << 28)) { 871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 4; 872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 5; 874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint CodedOutputStream::VarintSize64(uint64 value) { 878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value < (1ull << 35)) { 879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value < (1ull << 7)) { 880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 1; 881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value < (1ull << 14)) { 882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 2; 883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value < (1ull << 21)) { 884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 3; 885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value < (1ull << 28)) { 886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 4; 887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 5; 889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value < (1ull << 42)) { 892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 6; 893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value < (1ull << 49)) { 894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 7; 895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value < (1ull << 56)) { 896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 8; 897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value < (1ull << 63)) { 898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 9; 899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return 10; 901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 905a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonuint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str, 906a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson uint8* target) { 907a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_DCHECK_LE(str.size(), kuint32max); 908a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson target = WriteVarint32ToArray(str.size(), target); 909a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return WriteStringToArray(str, target); 910a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 911a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace io 913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 915