coded_stream.cc revision fbaaef999ba563838ebd00874ed8a1c01fbf286d
16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Protocol Buffers - Google's data interchange format
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Copyright 2008 Google Inc.  All rights reserved.
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// http://code.google.com/p/protobuf/
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Redistribution and use in source and binary forms, with or without
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// modification, are permitted provided that the following conditions are
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// met:
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//     * Redistributions of source code must retain the above copyright
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// notice, this list of conditions and the following disclaimer.
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//     * Redistributions in binary form must reproduce the above
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// copyright notice, this list of conditions and the following disclaimer
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// in the documentation and/or other materials provided with the
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// distribution.
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//     * Neither the name of Google Inc. nor the names of its
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// contributors may be used to endorse or promote products derived from
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// this software without specific prior written permission.
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Author: kenton@google.com (Kenton Varda)
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//  Based on original Protocol Buffers design by
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//  Sanjay Ghemawat, Jeff Dean, and others.
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// This implementation is heavily optimized to make reads and writes
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// of small values (especially varints) as fast as possible.  In
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// particular, we optimize for the common case that a read or a write
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// will not cross the end of the buffer, since we can avoid a lot
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// of branching in this case.
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stack>
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <limits.h>
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/io/coded_stream.h>
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/io/zero_copy_stream.h>
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/stubs/common.h>
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <google/protobuf/stubs/stl_util-inl.h>
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace google {
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace protobuf {
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace io {
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace {
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int kDefaultTotalBytesLimit = 64 << 20;  // 64MB
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int kDefaultTotalBytesWarningThreshold = 32 << 20;  // 32MB
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int kDefaultRecursionLimit = 64;
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int kMaxVarintBytes = 10;
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int kMaxVarint32Bytes = 5;
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}  // namespace
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// CodedInputStream ==================================================
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCodedInputStream::CodedInputStream(ZeroCopyInputStream* input)
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  : input_(input),
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_(NULL),
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_size_(0),
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    total_bytes_read_(0),
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    overflow_bytes_(0),
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    last_tag_(0),
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    legitimate_message_end_(false),
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    aliasing_enabled_(false),
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    current_limit_(INT_MAX),
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_size_after_limit_(0),
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    total_bytes_limit_(kDefaultTotalBytesLimit),
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    recursion_depth_(0),
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    recursion_limit_(kDefaultRecursionLimit) {
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // Eagerly Refresh() so buffer space is immediately available.
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  Refresh();
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCodedInputStream::CodedInputStream(const uint8* buffer, int size)
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  : input_(NULL),
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_(buffer),
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_size_(size),
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    total_bytes_read_(size),
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    overflow_bytes_(0),
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    last_tag_(0),
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    legitimate_message_end_(false),
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    aliasing_enabled_(false),
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    current_limit_(size),
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_size_after_limit_(0),
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    total_bytes_limit_(kDefaultTotalBytesLimit),
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    recursion_depth_(0),
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    recursion_limit_(kDefaultRecursionLimit) {
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // Note that setting current_limit_ == size is important to prevent some
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // code paths from trying to access input_ and segfaulting.
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCodedInputStream::~CodedInputStream() {
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if (input_ != NULL) {
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    BackUpInputToCurrentPosition();
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CodedInputStream::BackUpInputToCurrentPosition() {
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  int backup_bytes = buffer_size_ + buffer_size_after_limit_ + overflow_bytes_;
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if (backup_bytes > 0) {
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    input_->BackUp(backup_bytes);
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // total_bytes_read_ doesn't include overflow_bytes_.
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    total_bytes_read_ -= buffer_size_ + buffer_size_after_limit_;
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_size_ = 0;
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_size_after_limit_ = 0;
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    overflow_bytes_ = 0;
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orginline void CodedInputStream::RecomputeBufferLimits() {
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  buffer_size_ += buffer_size_after_limit_;
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  int closest_limit = min(current_limit_, total_bytes_limit_);
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if (closest_limit < total_bytes_read_) {
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // The limit position is in the current buffer.  We must adjust
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // the buffer size accordingly.
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_size_after_limit_ = total_bytes_read_ - closest_limit;
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_size_ -= buffer_size_after_limit_;
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  } else {
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    buffer_size_after_limit_ = 0;
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // Current position relative to the beginning of the stream.
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  int current_position = total_bytes_read_ -
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      (buffer_size_ + buffer_size_after_limit_);
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  Limit old_limit = current_limit_;
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // security: byte_limit is possibly evil, so check for negative values
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // and overflow.
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if (byte_limit >= 0 &&
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      byte_limit <= INT_MAX - current_position) {
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    current_limit_ = current_position + byte_limit;
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  } else {
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Negative or overflow.
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    current_limit_ = INT_MAX;
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // We need to enforce all limits, not just the new one, so if the previous
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // limit was before the new requested limit, we continue to enforce the
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // previous limit.
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  current_limit_ = min(current_limit_, old_limit);
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  RecomputeBufferLimits();
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return old_limit;
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CodedInputStream::PopLimit(Limit limit) {
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // The limit passed in is actually the *old* limit, which we returned from
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // PushLimit().
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  current_limit_ = limit;
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  RecomputeBufferLimits();
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // We may no longer be at a legitimate message end.  ReadTag() needs to be
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // called again to find out.
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  legitimate_message_end_ = false;
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint CodedInputStream::BytesUntilLimit() {
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if (current_limit_ == INT_MAX) return -1;
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  int current_position = total_bytes_read_ -
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      (buffer_size_ + buffer_size_after_limit_);
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return current_limit_ - current_position;
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CodedInputStream::SetTotalBytesLimit(
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int total_bytes_limit, int warning_threshold) {
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // Make sure the limit isn't already past, since this could confuse other
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  // code.
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  int current_position = total_bytes_read_ -
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org      (buffer_size_ + buffer_size_after_limit_);
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  total_bytes_limit_ = max(current_position, total_bytes_limit);
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  total_bytes_warning_threshold_ = warning_threshold;
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  RecomputeBufferLimits();
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CodedInputStream::PrintTotalBytesLimitError() {
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too "
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                "big (more than " << total_bytes_limit_
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             << " bytes).  To increase the limit (or to disable these "
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                "warnings), see CodedInputStream::SetTotalBytesLimit() "
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                "in google/protobuf/io/coded_stream.h.";
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgbool CodedInputStream::Skip(int count) {
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if (count < 0) return false;  // security: count is often user-supplied
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  if (count <= buffer_size_) {
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Just skipping within the current buffer.  Easy.
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Advance(count);
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return true;
210  }
211
212  if (buffer_size_after_limit_ > 0) {
213    // We hit a limit inside this buffer.  Advance to the limit and fail.
214    Advance(buffer_size_);
215    return false;
216  }
217
218  count -= buffer_size_;
219  buffer_ = NULL;
220  buffer_size_ = 0;
221
222  // Make sure this skip doesn't try to skip past the current limit.
223  int closest_limit = min(current_limit_, total_bytes_limit_);
224  int bytes_until_limit = closest_limit - total_bytes_read_;
225  if (bytes_until_limit < count) {
226    // We hit the limit.  Skip up to it then fail.
227    if (bytes_until_limit > 0) {
228      total_bytes_read_ = closest_limit;
229      input_->Skip(bytes_until_limit);
230    }
231    return false;
232  }
233
234  total_bytes_read_ += count;
235  return input_->Skip(count);
236}
237
238bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
239  if (buffer_size_ == 0 && !Refresh()) return false;
240
241  *data = buffer_;
242  *size = buffer_size_;
243  return true;
244}
245
246bool CodedInputStream::ReadRaw(void* buffer, int size) {
247  while (buffer_size_ < size) {
248    // Reading past end of buffer.  Copy what we have, then refresh.
249    memcpy(buffer, buffer_, buffer_size_);
250    buffer = reinterpret_cast<uint8*>(buffer) + buffer_size_;
251    size -= buffer_size_;
252    Advance(buffer_size_);
253    if (!Refresh()) return false;
254  }
255
256  memcpy(buffer, buffer_, size);
257  Advance(size);
258
259  return true;
260}
261
262bool CodedInputStream::ReadString(string* buffer, int size) {
263  if (size < 0) return false;  // security: size is often user-supplied
264
265  if (!buffer->empty()) {
266    buffer->clear();
267  }
268
269  if (size < buffer_size_) {
270    STLStringResizeUninitialized(buffer, size);
271    memcpy((uint8*)buffer->data(), buffer_, size);
272    Advance(size);
273    return true;
274  }
275
276  while (buffer_size_ < size) {
277    // Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
278    if (buffer_size_ != 0) {
279      // Note:  string1.append(string2) is O(string2.size()) (as opposed to
280      //   O(string1.size() + string2.size()), which would be bad).
281      buffer->append(reinterpret_cast<const char*>(buffer_), buffer_size_);
282    }
283    size -= buffer_size_;
284    Advance(buffer_size_);
285    if (!Refresh()) return false;
286  }
287
288  buffer->append(reinterpret_cast<const char*>(buffer_), size);
289  Advance(size);
290
291  return true;
292}
293
294
295bool CodedInputStream::ReadLittleEndian32(uint32* value) {
296  uint8 bytes[sizeof(*value)];
297
298  const uint8* ptr;
299  if (buffer_size_ >= sizeof(*value)) {
300    // Fast path:  Enough bytes in the buffer to read directly.
301    ptr = buffer_;
302    Advance(sizeof(*value));
303  } else {
304    // Slow path:  Had to read past the end of the buffer.
305    if (!ReadRaw(bytes, sizeof(*value))) return false;
306    ptr = bytes;
307  }
308
309  *value = (static_cast<uint32>(ptr[0])      ) |
310           (static_cast<uint32>(ptr[1]) <<  8) |
311           (static_cast<uint32>(ptr[2]) << 16) |
312           (static_cast<uint32>(ptr[3]) << 24);
313  return true;
314}
315
316bool CodedInputStream::ReadLittleEndian64(uint64* value) {
317  uint8 bytes[sizeof(*value)];
318
319  const uint8* ptr;
320  if (buffer_size_ >= sizeof(*value)) {
321    // Fast path:  Enough bytes in the buffer to read directly.
322    ptr = buffer_;
323    Advance(sizeof(*value));
324  } else {
325    // Slow path:  Had to read past the end of the buffer.
326    if (!ReadRaw(bytes, sizeof(*value))) return false;
327    ptr = bytes;
328  }
329
330  uint32 part0 = (static_cast<uint32>(ptr[0])      ) |
331                 (static_cast<uint32>(ptr[1]) <<  8) |
332                 (static_cast<uint32>(ptr[2]) << 16) |
333                 (static_cast<uint32>(ptr[3]) << 24);
334  uint32 part1 = (static_cast<uint32>(ptr[4])      ) |
335                 (static_cast<uint32>(ptr[5]) <<  8) |
336                 (static_cast<uint32>(ptr[6]) << 16) |
337                 (static_cast<uint32>(ptr[7]) << 24);
338  *value = static_cast<uint64>(part0) |
339          (static_cast<uint64>(part1) << 32);
340  return true;
341}
342
343bool CodedInputStream::ReadVarint32Fallback(uint32* value) {
344  if (buffer_size_ >= kMaxVarintBytes ||
345      // Optimization:  If the varint ends at exactly the end of the buffer,
346      // we can detect that and still use the fast path.
347      (buffer_size_ != 0 && !(buffer_[buffer_size_-1] & 0x80))) {
348    // Fast path:  We have enough bytes left in the buffer to guarantee that
349    // this read won't cross the end, so we can skip the checks.
350    const uint8* ptr = buffer_;
351    uint32 b;
352    uint32 result;
353
354    b = *(ptr++); result  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
355    b = *(ptr++); result |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
356    b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
357    b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
358    b = *(ptr++); result |=  b         << 28; if (!(b & 0x80)) goto done;
359
360    // If the input is larger than 32 bits, we still need to read it all
361    // and discard the high-order bits.
362    for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
363      b = *(ptr++); if (!(b & 0x80)) goto done;
364    }
365
366    // We have overrun the maximum size of a varint (10 bytes).  Assume
367    // the data is corrupt.
368    return false;
369
370   done:
371    Advance(ptr - buffer_);
372    *value = result;
373    return true;
374
375  } else {
376    // Optimization:  If we're at a limit, detect that quickly.  (This is
377    // common when reading tags.)
378    while (buffer_size_ == 0) {
379      // Detect cases where we definitely hit a byte limit without calling
380      // Refresh().
381      if (// If we hit a limit, buffer_size_after_limit_ will be non-zero.
382          buffer_size_after_limit_ > 0 &&
383          // Make sure that the limit we hit is not total_bytes_limit_, since
384          // in that case we still need to call Refresh() so that it prints an
385          // error.
386          total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) {
387        // We hit a byte limit.
388        legitimate_message_end_ = true;
389        return false;
390      }
391
392      // Call refresh.
393      if (!Refresh()) {
394        // Refresh failed.  Make sure that it failed due to EOF, not because
395        // we hit total_bytes_limit_, which, unlike normal limits, is not a
396        // valid place to end a message.
397        int current_position = total_bytes_read_ - buffer_size_after_limit_;
398        if (current_position >= total_bytes_limit_) {
399          // Hit total_bytes_limit_.  But if we also hit the normal limit,
400          // we're still OK.
401          legitimate_message_end_ = current_limit_ == total_bytes_limit_;
402        } else {
403          legitimate_message_end_ = true;
404        }
405        return false;
406      }
407    }
408
409    // Slow path:  Just do a 64-bit read.
410    uint64 result;
411    if (!ReadVarint64(&result)) return false;
412    *value = (uint32)result;
413    return true;
414  }
415}
416
417bool CodedInputStream::ReadVarint64(uint64* value) {
418  if (buffer_size_ >= kMaxVarintBytes ||
419      // Optimization:  If the varint ends at exactly the end of the buffer,
420      // we can detect that and still use the fast path.
421      (buffer_size_ != 0 && !(buffer_[buffer_size_-1] & 0x80))) {
422    // Fast path:  We have enough bytes left in the buffer to guarantee that
423    // this read won't cross the end, so we can skip the checks.
424
425    const uint8* ptr = buffer_;
426    uint32 b;
427
428    // Splitting into 32-bit pieces gives better performance on 32-bit
429    // processors.
430    uint32 part0 = 0, part1 = 0, part2 = 0;
431
432    b = *(ptr++); part0  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
433    b = *(ptr++); part0 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
434    b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
435    b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
436    b = *(ptr++); part1  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
437    b = *(ptr++); part1 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
438    b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
439    b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
440    b = *(ptr++); part2  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
441    b = *(ptr++); part2 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
442
443    // We have overrun the maximum size of a varint (10 bytes).  The data
444    // must be corrupt.
445    return false;
446
447   done:
448    Advance(ptr - buffer_);
449    *value = (static_cast<uint64>(part0)      ) |
450             (static_cast<uint64>(part1) << 28) |
451             (static_cast<uint64>(part2) << 56);
452    return true;
453
454  } else {
455    // Slow path:  This read might cross the end of the buffer, so we
456    // need to check and refresh the buffer if and when it does.
457
458    uint64 result = 0;
459    int count = 0;
460    uint32 b;
461
462    do {
463      if (count == kMaxVarintBytes) return false;
464      while (buffer_size_ == 0) {
465        if (!Refresh()) return false;
466      }
467      b = *buffer_;
468      result |= static_cast<uint64>(b & 0x7F) << (7 * count);
469      Advance(1);
470      ++count;
471    } while(b & 0x80);
472
473    *value = result;
474    return true;
475  }
476}
477
478bool CodedInputStream::Refresh() {
479  GOOGLE_DCHECK_EQ(buffer_size_, 0);
480
481  if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
482      total_bytes_read_ == current_limit_) {
483    // We've hit a limit.  Stop.
484    int current_position = total_bytes_read_ - buffer_size_after_limit_;
485
486    if (current_position >= total_bytes_limit_ &&
487        total_bytes_limit_ != current_limit_) {
488      // Hit total_bytes_limit_.
489      PrintTotalBytesLimitError();
490    }
491
492    return false;
493  }
494
495  if (total_bytes_warning_threshold_ >= 0 &&
496      total_bytes_read_ >= total_bytes_warning_threshold_) {
497      GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message.  If the "
498                      "message turns out to be larger than "
499                   << total_bytes_limit_ << " bytes, parsing will be halted "
500                      "for security reasons.  To increase the limit (or to "
501                      "disable these warnings), see "
502                      "CodedInputStream::SetTotalBytesLimit() in "
503                      "google/protobuf/io/coded_stream.h.";
504
505    // Don't warn again for this stream.
506    total_bytes_warning_threshold_ = -1;
507  }
508
509  const void* void_buffer;
510  if (input_->Next(&void_buffer, &buffer_size_)) {
511    buffer_ = reinterpret_cast<const uint8*>(void_buffer);
512    GOOGLE_CHECK_GE(buffer_size_, 0);
513
514    if (total_bytes_read_ <= INT_MAX - buffer_size_) {
515      total_bytes_read_ += buffer_size_;
516    } else {
517      // Overflow.  Reset buffer_size_ to not include the bytes beyond INT_MAX.
518      // We can't get that far anyway, because total_bytes_limit_ is guaranteed
519      // to be less than it.  We need to keep track of the number of bytes
520      // we discarded, though, so that we can call input_->BackUp() to back
521      // up over them on destruction.
522
523      // The following line is equivalent to:
524      //   overflow_bytes_ = total_bytes_read_ + buffer_size_ - INT_MAX;
525      // except that it avoids overflows.  Signed integer overflow has
526      // undefined results according to the C standard.
527      overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size_);
528      buffer_size_ -= overflow_bytes_;
529      total_bytes_read_ = INT_MAX;
530    }
531
532    RecomputeBufferLimits();
533    return true;
534  } else {
535    buffer_ = NULL;
536    buffer_size_ = 0;
537    return false;
538  }
539}
540
541// CodedOutputStream =================================================
542
543CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
544  : output_(output),
545    buffer_(NULL),
546    buffer_size_(0),
547    total_bytes_(0),
548    had_error_(false) {
549  // Eagerly Refresh() so buffer space is immediately available.
550  Refresh();
551  // The Refresh() may have failed. If the client doesn't write any data,
552  // though, don't consider this an error. If the client does write data, then
553  // another Refresh() will be attempted and it will set the error once again.
554  had_error_ = false;
555}
556
557CodedOutputStream::~CodedOutputStream() {
558  if (buffer_size_ > 0) {
559    output_->BackUp(buffer_size_);
560  }
561}
562
563bool CodedOutputStream::Skip(int count) {
564  if (count < 0) return false;
565
566  while (count > buffer_size_) {
567    count -= buffer_size_;
568    if (!Refresh()) return false;
569  }
570
571  Advance(count);
572  return true;
573}
574
575bool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) {
576  if (buffer_size_ == 0 && !Refresh()) return false;
577
578  *data = buffer_;
579  *size = buffer_size_;
580  return true;
581}
582
583void CodedOutputStream::WriteRaw(const void* data, int size) {
584  while (buffer_size_ < size) {
585    memcpy(buffer_, data, buffer_size_);
586    size -= buffer_size_;
587    data = reinterpret_cast<const uint8*>(data) + buffer_size_;
588    if (!Refresh()) return;
589  }
590
591  memcpy(buffer_, data, size);
592  Advance(size);
593}
594
595uint8* CodedOutputStream::WriteRawToArray(
596    const void* data, int size, uint8* target) {
597  memcpy(target, data, size);
598  return target + size;
599}
600
601
602void CodedOutputStream::WriteLittleEndian32(uint32 value) {
603  uint8 bytes[sizeof(value)];
604
605  bool use_fast = buffer_size_ >= sizeof(value);
606  uint8* ptr = use_fast ? buffer_ : bytes;
607
608  WriteLittleEndian32ToArray(value, ptr);
609
610  if (use_fast) {
611    Advance(sizeof(value));
612  } else {
613    WriteRaw(bytes, sizeof(value));
614  }
615}
616
617void CodedOutputStream::WriteLittleEndian64(uint64 value) {
618  uint8 bytes[sizeof(value)];
619
620  bool use_fast = buffer_size_ >= sizeof(value);
621  uint8* ptr = use_fast ? buffer_ : bytes;
622
623  WriteLittleEndian64ToArray(value, ptr);
624
625  if (use_fast) {
626    Advance(sizeof(value));
627  } else {
628    WriteRaw(bytes, sizeof(value));
629  }
630}
631
632inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
633    uint32 value, uint8* target) {
634  target[0] = static_cast<uint8>(value | 0x80);
635  if (value >= (1 << 7)) {
636    target[1] = static_cast<uint8>((value >>  7) | 0x80);
637    if (value >= (1 << 14)) {
638      target[2] = static_cast<uint8>((value >> 14) | 0x80);
639      if (value >= (1 << 21)) {
640        target[3] = static_cast<uint8>((value >> 21) | 0x80);
641        if (value >= (1 << 28)) {
642          target[4] = static_cast<uint8>(value >> 28);
643          return target + 5;
644        } else {
645          target[3] &= 0x7F;
646          return target + 4;
647        }
648      } else {
649        target[2] &= 0x7F;
650        return target + 3;
651      }
652    } else {
653      target[1] &= 0x7F;
654      return target + 2;
655    }
656  } else {
657    target[0] &= 0x7F;
658    return target + 1;
659  }
660}
661
662void CodedOutputStream::WriteVarint32(uint32 value) {
663  if (buffer_size_ >= kMaxVarint32Bytes) {
664    // Fast path:  We have enough bytes left in the buffer to guarantee that
665    // this write won't cross the end, so we can skip the checks.
666    uint8* target = buffer_;
667    uint8* end = WriteVarint32FallbackToArrayInline(value, target);
668    int size = end - target;
669    Advance(size);
670  } else {
671    // Slow path:  This write might cross the end of the buffer, so we
672    // compose the bytes first then use WriteRaw().
673    uint8 bytes[kMaxVarint32Bytes];
674    int size = 0;
675    while (value > 0x7F) {
676      bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
677      value >>= 7;
678    }
679    bytes[size++] = static_cast<uint8>(value) & 0x7F;
680    WriteRaw(bytes, size);
681  }
682}
683
684uint8* CodedOutputStream::WriteVarint32FallbackToArray(
685    uint32 value, uint8* target) {
686  return WriteVarint32FallbackToArrayInline(value, target);
687}
688
689inline uint8* CodedOutputStream::WriteVarint64ToArrayInline(
690    uint64 value, uint8* target) {
691  // Splitting into 32-bit pieces gives better performance on 32-bit
692  // processors.
693  uint32 part0 = static_cast<uint32>(value      );
694  uint32 part1 = static_cast<uint32>(value >> 28);
695  uint32 part2 = static_cast<uint32>(value >> 56);
696
697  int size;
698
699  // Here we can't really optimize for small numbers, since the value is
700  // split into three parts.  Cheking for numbers < 128, for instance,
701  // would require three comparisons, since you'd have to make sure part1
702  // and part2 are zero.  However, if the caller is using 64-bit integers,
703  // it is likely that they expect the numbers to often be very large, so
704  // we probably don't want to optimize for small numbers anyway.  Thus,
705  // we end up with a hardcoded binary search tree...
706  if (part2 == 0) {
707    if (part1 == 0) {
708      if (part0 < (1 << 14)) {
709        if (part0 < (1 << 7)) {
710          size = 1; goto size1;
711        } else {
712          size = 2; goto size2;
713        }
714      } else {
715        if (part0 < (1 << 21)) {
716          size = 3; goto size3;
717        } else {
718          size = 4; goto size4;
719        }
720      }
721    } else {
722      if (part1 < (1 << 14)) {
723        if (part1 < (1 << 7)) {
724          size = 5; goto size5;
725        } else {
726          size = 6; goto size6;
727        }
728      } else {
729        if (part1 < (1 << 21)) {
730          size = 7; goto size7;
731        } else {
732          size = 8; goto size8;
733        }
734      }
735    }
736  } else {
737    if (part2 < (1 << 7)) {
738      size = 9; goto size9;
739    } else {
740      size = 10; goto size10;
741    }
742  }
743
744  GOOGLE_LOG(FATAL) << "Can't get here.";
745
746  size10: target[9] = static_cast<uint8>((part2 >>  7) | 0x80);
747  size9 : target[8] = static_cast<uint8>((part2      ) | 0x80);
748  size8 : target[7] = static_cast<uint8>((part1 >> 21) | 0x80);
749  size7 : target[6] = static_cast<uint8>((part1 >> 14) | 0x80);
750  size6 : target[5] = static_cast<uint8>((part1 >>  7) | 0x80);
751  size5 : target[4] = static_cast<uint8>((part1      ) | 0x80);
752  size4 : target[3] = static_cast<uint8>((part0 >> 21) | 0x80);
753  size3 : target[2] = static_cast<uint8>((part0 >> 14) | 0x80);
754  size2 : target[1] = static_cast<uint8>((part0 >>  7) | 0x80);
755  size1 : target[0] = static_cast<uint8>((part0      ) | 0x80);
756
757  target[size-1] &= 0x7F;
758  return target + size;
759}
760
761void CodedOutputStream::WriteVarint64(uint64 value) {
762  if (buffer_size_ >= kMaxVarintBytes) {
763    // Fast path:  We have enough bytes left in the buffer to guarantee that
764    // this write won't cross the end, so we can skip the checks.
765    uint8* target = buffer_;
766
767    uint8* end = WriteVarint64ToArrayInline(value, target);
768    int size = end - target;
769    Advance(size);
770  } else {
771    // Slow path:  This write might cross the end of the buffer, so we
772    // compose the bytes first then use WriteRaw().
773    uint8 bytes[kMaxVarintBytes];
774    int size = 0;
775    while (value > 0x7F) {
776      bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
777      value >>= 7;
778    }
779    bytes[size++] = static_cast<uint8>(value) & 0x7F;
780    WriteRaw(bytes, size);
781  }
782}
783
784uint8* CodedOutputStream::WriteVarint64ToArray(
785    uint64 value, uint8* target) {
786  return WriteVarint64ToArrayInline(value, target);
787}
788
789bool CodedOutputStream::Refresh() {
790  void* void_buffer;
791  if (output_->Next(&void_buffer, &buffer_size_)) {
792    buffer_ = reinterpret_cast<uint8*>(void_buffer);
793    total_bytes_ += buffer_size_;
794    return true;
795  } else {
796    buffer_ = NULL;
797    buffer_size_ = 0;
798    had_error_ = true;
799    return false;
800  }
801}
802
803int CodedOutputStream::VarintSize32Fallback(uint32 value) {
804  if (value < (1 << 7)) {
805    return 1;
806  } else if (value < (1 << 14)) {
807    return 2;
808  } else if (value < (1 << 21)) {
809    return 3;
810  } else if (value < (1 << 28)) {
811    return 4;
812  } else {
813    return 5;
814  }
815}
816
817int CodedOutputStream::VarintSize64(uint64 value) {
818  if (value < (1ull << 35)) {
819    if (value < (1ull << 7)) {
820      return 1;
821    } else if (value < (1ull << 14)) {
822      return 2;
823    } else if (value < (1ull << 21)) {
824      return 3;
825    } else if (value < (1ull << 28)) {
826      return 4;
827    } else {
828      return 5;
829    }
830  } else {
831    if (value < (1ull << 42)) {
832      return 6;
833    } else if (value < (1ull << 49)) {
834      return 7;
835    } else if (value < (1ull << 56)) {
836      return 8;
837    } else if (value < (1ull << 63)) {
838      return 9;
839    } else {
840      return 10;
841    }
842  }
843}
844
845}  // namespace io
846}  // namespace protobuf
847}  // namespace google
848