coded_stream.cc revision fbaaef999ba563838ebd00874ed8a1c01fbf286d
1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
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
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <stack>
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <limits.h>
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/coded_stream.h>
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream.h>
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h>
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/stl_util-inl.h>
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace io {
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace {
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const int kDefaultTotalBytesLimit = 64 << 20;  // 64MB
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const int kDefaultTotalBytesWarningThreshold = 32 << 20;  // 32MB
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const int kDefaultRecursionLimit = 64;
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const int kMaxVarintBytes = 10;
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const int kMaxVarint32Bytes = 5;
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// CodedInputStream ==================================================
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCodedInputStream::CodedInputStream(ZeroCopyInputStream* input)
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : input_(input),
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_(NULL),
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_(0),
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_bytes_read_(0),
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    overflow_bytes_(0),
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    last_tag_(0),
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    legitimate_message_end_(false),
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    aliasing_enabled_(false),
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    current_limit_(INT_MAX),
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_after_limit_(0),
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_bytes_limit_(kDefaultTotalBytesLimit),
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    recursion_depth_(0),
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    recursion_limit_(kDefaultRecursionLimit) {
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Eagerly Refresh() so buffer space is immediately available.
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Refresh();
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCodedInputStream::CodedInputStream(const uint8* buffer, int size)
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : input_(NULL),
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_(buffer),
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_(size),
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_bytes_read_(size),
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    overflow_bytes_(0),
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    last_tag_(0),
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    legitimate_message_end_(false),
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    aliasing_enabled_(false),
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    current_limit_(size),
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_after_limit_(0),
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_bytes_limit_(kDefaultTotalBytesLimit),
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    recursion_depth_(0),
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    recursion_limit_(kDefaultRecursionLimit) {
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Note that setting current_limit_ == size is important to prevent some
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // code paths from trying to access input_ and segfaulting.
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCodedInputStream::~CodedInputStream() {
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (input_ != NULL) {
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    BackUpInputToCurrentPosition();
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedInputStream::BackUpInputToCurrentPosition() {
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int backup_bytes = buffer_size_ + buffer_size_after_limit_ + overflow_bytes_;
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (backup_bytes > 0) {
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    input_->BackUp(backup_bytes);
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // total_bytes_read_ doesn't include overflow_bytes_.
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_bytes_read_ -= buffer_size_ + buffer_size_after_limit_;
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_ = 0;
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_after_limit_ = 0;
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    overflow_bytes_ = 0;
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline void CodedInputStream::RecomputeBufferLimits() {
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer_size_ += buffer_size_after_limit_;
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int closest_limit = min(current_limit_, total_bytes_limit_);
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (closest_limit < total_bytes_read_) {
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // The limit position is in the current buffer.  We must adjust
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // the buffer size accordingly.
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_after_limit_ = total_bytes_read_ - closest_limit;
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_ -= buffer_size_after_limit_;
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_after_limit_ = 0;
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Current position relative to the beginning of the stream.
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int current_position = total_bytes_read_ -
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      (buffer_size_ + buffer_size_after_limit_);
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Limit old_limit = current_limit_;
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // security: byte_limit is possibly evil, so check for negative values
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // and overflow.
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (byte_limit >= 0 &&
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      byte_limit <= INT_MAX - current_position) {
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    current_limit_ = current_position + byte_limit;
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Negative or overflow.
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    current_limit_ = INT_MAX;
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We need to enforce all limits, not just the new one, so if the previous
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // limit was before the new requested limit, we continue to enforce the
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // previous limit.
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  current_limit_ = min(current_limit_, old_limit);
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecomputeBufferLimits();
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return old_limit;
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedInputStream::PopLimit(Limit limit) {
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // The limit passed in is actually the *old* limit, which we returned from
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // PushLimit().
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  current_limit_ = limit;
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecomputeBufferLimits();
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We may no longer be at a legitimate message end.  ReadTag() needs to be
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // called again to find out.
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  legitimate_message_end_ = false;
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint CodedInputStream::BytesUntilLimit() {
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (current_limit_ == INT_MAX) return -1;
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int current_position = total_bytes_read_ -
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      (buffer_size_ + buffer_size_after_limit_);
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return current_limit_ - current_position;
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedInputStream::SetTotalBytesLimit(
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int total_bytes_limit, int warning_threshold) {
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Make sure the limit isn't already past, since this could confuse other
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // code.
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int current_position = total_bytes_read_ -
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      (buffer_size_ + buffer_size_after_limit_);
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  total_bytes_limit_ = max(current_position, total_bytes_limit);
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  total_bytes_warning_threshold_ = warning_threshold;
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  RecomputeBufferLimits();
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedInputStream::PrintTotalBytesLimitError() {
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too "
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                "big (more than " << total_bytes_limit_
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville             << " bytes).  To increase the limit (or to disable these "
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                "warnings), see CodedInputStream::SetTotalBytesLimit() "
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                "in google/protobuf/io/coded_stream.h.";
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::Skip(int count) {
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (count < 0) return false;  // security: count is often user-supplied
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (count <= buffer_size_) {
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Just skipping within the current buffer.  Easy.
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(count);
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_after_limit_ > 0) {
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We hit a limit inside this buffer.  Advance to the limit and fail.
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(buffer_size_);
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  count -= buffer_size_;
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer_ = NULL;
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer_size_ = 0;
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Make sure this skip doesn't try to skip past the current limit.
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int closest_limit = min(current_limit_, total_bytes_limit_);
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int bytes_until_limit = closest_limit - total_bytes_read_;
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (bytes_until_limit < count) {
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We hit the limit.  Skip up to it then fail.
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (bytes_until_limit > 0) {
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      total_bytes_read_ = closest_limit;
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      input_->Skip(bytes_until_limit);
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  total_bytes_read_ += count;
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return input_->Skip(count);
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_ == 0 && !Refresh()) return false;
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *data = buffer_;
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *size = buffer_size_;
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::ReadRaw(void* buffer, int size) {
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (buffer_size_ < size) {
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Reading past end of buffer.  Copy what we have, then refresh.
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    memcpy(buffer, buffer_, buffer_size_);
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer = reinterpret_cast<uint8*>(buffer) + buffer_size_;
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    size -= buffer_size_;
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(buffer_size_);
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!Refresh()) return false;
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  memcpy(buffer, buffer_, size);
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Advance(size);
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::ReadString(string* buffer, int size) {
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (size < 0) return false;  // security: size is often user-supplied
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!buffer->empty()) {
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer->clear();
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (size < buffer_size_) {
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    STLStringResizeUninitialized(buffer, size);
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    memcpy((uint8*)buffer->data(), buffer_, size);
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(size);
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (buffer_size_ < size) {
277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (buffer_size_ != 0) {
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Note:  string1.append(string2) is O(string2.size()) (as opposed to
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      //   O(string1.size() + string2.size()), which would be bad).
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      buffer->append(reinterpret_cast<const char*>(buffer_), buffer_size_);
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    size -= buffer_size_;
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(buffer_size_);
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!Refresh()) return false;
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  buffer->append(reinterpret_cast<const char*>(buffer_), size);
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Advance(size);
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::ReadLittleEndian32(uint32* value) {
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint8 bytes[sizeof(*value)];
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const uint8* ptr;
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_ >= sizeof(*value)) {
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Fast path:  Enough bytes in the buffer to read directly.
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    ptr = buffer_;
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(sizeof(*value));
303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Slow path:  Had to read past the end of the buffer.
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!ReadRaw(bytes, sizeof(*value))) return false;
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    ptr = bytes;
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *value = (static_cast<uint32>(ptr[0])      ) |
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (static_cast<uint32>(ptr[1]) <<  8) |
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (static_cast<uint32>(ptr[2]) << 16) |
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville           (static_cast<uint32>(ptr[3]) << 24);
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::ReadLittleEndian64(uint64* value) {
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint8 bytes[sizeof(*value)];
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const uint8* ptr;
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_ >= sizeof(*value)) {
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Fast path:  Enough bytes in the buffer to read directly.
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    ptr = buffer_;
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(sizeof(*value));
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Slow path:  Had to read past the end of the buffer.
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!ReadRaw(bytes, sizeof(*value))) return false;
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    ptr = bytes;
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint32 part0 = (static_cast<uint32>(ptr[0])      ) |
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 (static_cast<uint32>(ptr[1]) <<  8) |
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 (static_cast<uint32>(ptr[2]) << 16) |
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 (static_cast<uint32>(ptr[3]) << 24);
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint32 part1 = (static_cast<uint32>(ptr[4])      ) |
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 (static_cast<uint32>(ptr[5]) <<  8) |
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 (static_cast<uint32>(ptr[6]) << 16) |
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 (static_cast<uint32>(ptr[7]) << 24);
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *value = static_cast<uint64>(part0) |
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          (static_cast<uint64>(part1) << 32);
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::ReadVarint32Fallback(uint32* value) {
344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_ >= kMaxVarintBytes ||
345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Optimization:  If the varint ends at exactly the end of the buffer,
346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // we can detect that and still use the fast path.
347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      (buffer_size_ != 0 && !(buffer_[buffer_size_-1] & 0x80))) {
348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Fast path:  We have enough bytes left in the buffer to guarantee that
349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // this read won't cross the end, so we can skip the checks.
350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const uint8* ptr = buffer_;
351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint32 b;
352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint32 result;
353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); result  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); result |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); result |=  b         << 28; if (!(b & 0x80)) goto done;
359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // If the input is larger than 32 bits, we still need to read it all
361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // and discard the high-order bits.
362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      b = *(ptr++); if (!(b & 0x80)) goto done;
364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We have overrun the maximum size of a varint (10 bytes).  Assume
367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // the data is corrupt.
368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   done:
371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(ptr - buffer_);
372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *value = result;
373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Optimization:  If we're at a limit, detect that quickly.  (This is
377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // common when reading tags.)
378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    while (buffer_size_ == 0) {
379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Detect cases where we definitely hit a byte limit without calling
380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Refresh().
381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (// If we hit a limit, buffer_size_after_limit_ will be non-zero.
382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          buffer_size_after_limit_ > 0 &&
383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          // Make sure that the limit we hit is not total_bytes_limit_, since
384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          // in that case we still need to call Refresh() so that it prints an
385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          // error.
386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) {
387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // We hit a byte limit.
388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        legitimate_message_end_ = true;
389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return false;
390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Call refresh.
393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (!Refresh()) {
394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // Refresh failed.  Make sure that it failed due to EOF, not because
395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // we hit total_bytes_limit_, which, unlike normal limits, is not a
396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // valid place to end a message.
397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        int current_position = total_bytes_read_ - buffer_size_after_limit_;
398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (current_position >= total_bytes_limit_) {
399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          // Hit total_bytes_limit_.  But if we also hit the normal limit,
400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          // we're still OK.
401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          legitimate_message_end_ = current_limit_ == total_bytes_limit_;
402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        } else {
403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          legitimate_message_end_ = true;
404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return false;
406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Slow path:  Just do a 64-bit read.
410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint64 result;
411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!ReadVarint64(&result)) return false;
412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *value = (uint32)result;
413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::ReadVarint64(uint64* value) {
418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_ >= kMaxVarintBytes ||
419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Optimization:  If the varint ends at exactly the end of the buffer,
420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // we can detect that and still use the fast path.
421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      (buffer_size_ != 0 && !(buffer_[buffer_size_-1] & 0x80))) {
422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Fast path:  We have enough bytes left in the buffer to guarantee that
423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // this read won't cross the end, so we can skip the checks.
424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const uint8* ptr = buffer_;
426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint32 b;
427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Splitting into 32-bit pieces gives better performance on 32-bit
429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // processors.
430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint32 part0 = 0, part1 = 0, part2 = 0;
431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); part0  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); part0 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); part1  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); part1 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); part2  = (b & 0x7F)      ; if (!(b & 0x80)) goto done;
441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    b = *(ptr++); part2 |= (b & 0x7F) <<  7; if (!(b & 0x80)) goto done;
442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We have overrun the maximum size of a varint (10 bytes).  The data
444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // must be corrupt.
445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville   done:
448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(ptr - buffer_);
449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *value = (static_cast<uint64>(part0)      ) |
450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville             (static_cast<uint64>(part1) << 28) |
451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville             (static_cast<uint64>(part2) << 56);
452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Slow path:  This read might cross the end of the buffer, so we
456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // need to check and refresh the buffer if and when it does.
457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint64 result = 0;
459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int count = 0;
460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint32 b;
461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    do {
463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (count == kMaxVarintBytes) return false;
464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      while (buffer_size_ == 0) {
465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (!Refresh()) return false;
466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      b = *buffer_;
468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      result |= static_cast<uint64>(b & 0x7F) << (7 * count);
469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      Advance(1);
470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      ++count;
471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } while(b & 0x80);
472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    *value = result;
474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedInputStream::Refresh() {
479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_DCHECK_EQ(buffer_size_, 0);
480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      total_bytes_read_ == current_limit_) {
483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We've hit a limit.  Stop.
484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int current_position = total_bytes_read_ - buffer_size_after_limit_;
485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (current_position >= total_bytes_limit_ &&
487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        total_bytes_limit_ != current_limit_) {
488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Hit total_bytes_limit_.
489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      PrintTotalBytesLimitError();
490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (total_bytes_warning_threshold_ >= 0 &&
496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      total_bytes_read_ >= total_bytes_warning_threshold_) {
497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message.  If the "
498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                      "message turns out to be larger than "
499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                   << total_bytes_limit_ << " bytes, parsing will be halted "
500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                      "for security reasons.  To increase the limit (or to "
501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                      "disable these warnings), see "
502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                      "CodedInputStream::SetTotalBytesLimit() in "
503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                      "google/protobuf/io/coded_stream.h.";
504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Don't warn again for this stream.
506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_bytes_warning_threshold_ = -1;
507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const void* void_buffer;
510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (input_->Next(&void_buffer, &buffer_size_)) {
511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_ = reinterpret_cast<const uint8*>(void_buffer);
512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GOOGLE_CHECK_GE(buffer_size_, 0);
513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (total_bytes_read_ <= INT_MAX - buffer_size_) {
515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      total_bytes_read_ += buffer_size_;
516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Overflow.  Reset buffer_size_ to not include the bytes beyond INT_MAX.
518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // We can't get that far anyway, because total_bytes_limit_ is guaranteed
519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // to be less than it.  We need to keep track of the number of bytes
520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // we discarded, though, so that we can call input_->BackUp() to back
521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // up over them on destruction.
522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // The following line is equivalent to:
524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      //   overflow_bytes_ = total_bytes_read_ + buffer_size_ - INT_MAX;
525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // except that it avoids overflows.  Signed integer overflow has
526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // undefined results according to the C standard.
527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size_);
528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      buffer_size_ -= overflow_bytes_;
529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      total_bytes_read_ = INT_MAX;
530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    RecomputeBufferLimits();
533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_ = NULL;
536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_ = 0;
537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// CodedOutputStream =================================================
542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : output_(output),
545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_(NULL),
546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_(0),
547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_bytes_(0),
548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    had_error_(false) {
549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Eagerly Refresh() so buffer space is immediately available.
550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Refresh();
551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // The Refresh() may have failed. If the client doesn't write any data,
552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // though, don't consider this an error. If the client does write data, then
553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // another Refresh() will be attempted and it will set the error once again.
554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  had_error_ = false;
555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleCodedOutputStream::~CodedOutputStream() {
558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_ > 0) {
559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    output_->BackUp(buffer_size_);
560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedOutputStream::Skip(int count) {
564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (count < 0) return false;
565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (count > buffer_size_) {
567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    count -= buffer_size_;
568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!Refresh()) return false;
569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Advance(count);
572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) {
576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_ == 0 && !Refresh()) return false;
577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *data = buffer_;
579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  *size = buffer_size_;
580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return true;
581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedOutputStream::WriteRaw(const void* data, int size) {
584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  while (buffer_size_ < size) {
585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    memcpy(buffer_, data, buffer_size_);
586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    size -= buffer_size_;
587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    data = reinterpret_cast<const uint8*>(data) + buffer_size_;
588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!Refresh()) return;
589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  memcpy(buffer_, data, size);
592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Advance(size);
593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleuint8* CodedOutputStream::WriteRawToArray(
596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const void* data, int size, uint8* target) {
597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  memcpy(target, data, size);
598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return target + size;
599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedOutputStream::WriteLittleEndian32(uint32 value) {
603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint8 bytes[sizeof(value)];
604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  bool use_fast = buffer_size_ >= sizeof(value);
606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint8* ptr = use_fast ? buffer_ : bytes;
607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  WriteLittleEndian32ToArray(value, ptr);
609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (use_fast) {
611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(sizeof(value));
612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    WriteRaw(bytes, sizeof(value));
614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedOutputStream::WriteLittleEndian64(uint64 value) {
618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint8 bytes[sizeof(value)];
619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  bool use_fast = buffer_size_ >= sizeof(value);
621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint8* ptr = use_fast ? buffer_ : bytes;
622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  WriteLittleEndian64ToArray(value, ptr);
624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (use_fast) {
626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(sizeof(value));
627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    WriteRaw(bytes, sizeof(value));
629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint32 value, uint8* target) {
634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  target[0] = static_cast<uint8>(value | 0x80);
635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (value >= (1 << 7)) {
636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    target[1] = static_cast<uint8>((value >>  7) | 0x80);
637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (value >= (1 << 14)) {
638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      target[2] = static_cast<uint8>((value >> 14) | 0x80);
639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (value >= (1 << 21)) {
640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        target[3] = static_cast<uint8>((value >> 21) | 0x80);
641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (value >= (1 << 28)) {
642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          target[4] = static_cast<uint8>(value >> 28);
643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          return target + 5;
644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        } else {
645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          target[3] &= 0x7F;
646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          return target + 4;
647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        target[2] &= 0x7F;
650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return target + 3;
651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      target[1] &= 0x7F;
654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return target + 2;
655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    target[0] &= 0x7F;
658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return target + 1;
659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedOutputStream::WriteVarint32(uint32 value) {
663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_ >= kMaxVarint32Bytes) {
664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Fast path:  We have enough bytes left in the buffer to guarantee that
665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // this write won't cross the end, so we can skip the checks.
666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint8* target = buffer_;
667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint8* end = WriteVarint32FallbackToArrayInline(value, target);
668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int size = end - target;
669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(size);
670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Slow path:  This write might cross the end of the buffer, so we
672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // compose the bytes first then use WriteRaw().
673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint8 bytes[kMaxVarint32Bytes];
674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int size = 0;
675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    while (value > 0x7F) {
676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      value >>= 7;
678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bytes[size++] = static_cast<uint8>(value) & 0x7F;
680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    WriteRaw(bytes, size);
681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleuint8* CodedOutputStream::WriteVarint32FallbackToArray(
685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint32 value, uint8* target) {
686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return WriteVarint32FallbackToArrayInline(value, target);
687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline uint8* CodedOutputStream::WriteVarint64ToArrayInline(
690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint64 value, uint8* target) {
691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Splitting into 32-bit pieces gives better performance on 32-bit
692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // processors.
693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint32 part0 = static_cast<uint32>(value      );
694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint32 part1 = static_cast<uint32>(value >> 28);
695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  uint32 part2 = static_cast<uint32>(value >> 56);
696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int size;
698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Here we can't really optimize for small numbers, since the value is
700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // split into three parts.  Cheking for numbers < 128, for instance,
701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // would require three comparisons, since you'd have to make sure part1
702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // and part2 are zero.  However, if the caller is using 64-bit integers,
703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // it is likely that they expect the numbers to often be very large, so
704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // we probably don't want to optimize for small numbers anyway.  Thus,
705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // we end up with a hardcoded binary search tree...
706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (part2 == 0) {
707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (part1 == 0) {
708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (part0 < (1 << 14)) {
709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (part0 < (1 << 7)) {
710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          size = 1; goto size1;
711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        } else {
712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          size = 2; goto size2;
713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (part0 < (1 << 21)) {
716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          size = 3; goto size3;
717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        } else {
718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          size = 4; goto size4;
719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (part1 < (1 << 14)) {
723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (part1 < (1 << 7)) {
724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          size = 5; goto size5;
725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        } else {
726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          size = 6; goto size6;
727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (part1 < (1 << 21)) {
730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          size = 7; goto size7;
731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        } else {
732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          size = 8; goto size8;
733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (part2 < (1 << 7)) {
738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      size = 9; goto size9;
739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      size = 10; goto size10;
741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_LOG(FATAL) << "Can't get here.";
745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  size10: target[9] = static_cast<uint8>((part2 >>  7) | 0x80);
747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  size9 : target[8] = static_cast<uint8>((part2      ) | 0x80);
748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  size8 : target[7] = static_cast<uint8>((part1 >> 21) | 0x80);
749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  size7 : target[6] = static_cast<uint8>((part1 >> 14) | 0x80);
750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  size6 : target[5] = static_cast<uint8>((part1 >>  7) | 0x80);
751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  size5 : target[4] = static_cast<uint8>((part1      ) | 0x80);
752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  size4 : target[3] = static_cast<uint8>((part0 >> 21) | 0x80);
753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  size3 : target[2] = static_cast<uint8>((part0 >> 14) | 0x80);
754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  size2 : target[1] = static_cast<uint8>((part0 >>  7) | 0x80);
755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  size1 : target[0] = static_cast<uint8>((part0      ) | 0x80);
756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  target[size-1] &= 0x7F;
758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return target + size;
759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid CodedOutputStream::WriteVarint64(uint64 value) {
762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (buffer_size_ >= kMaxVarintBytes) {
763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Fast path:  We have enough bytes left in the buffer to guarantee that
764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // this write won't cross the end, so we can skip the checks.
765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint8* target = buffer_;
766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint8* end = WriteVarint64ToArrayInline(value, target);
768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int size = end - target;
769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Advance(size);
770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Slow path:  This write might cross the end of the buffer, so we
772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // compose the bytes first then use WriteRaw().
773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint8 bytes[kMaxVarintBytes];
774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int size = 0;
775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    while (value > 0x7F) {
776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      value >>= 7;
778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bytes[size++] = static_cast<uint8>(value) & 0x7F;
780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    WriteRaw(bytes, size);
781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleuint8* CodedOutputStream::WriteVarint64ToArray(
785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint64 value, uint8* target) {
786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return WriteVarint64ToArrayInline(value, target);
787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool CodedOutputStream::Refresh() {
790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  void* void_buffer;
791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (output_->Next(&void_buffer, &buffer_size_)) {
792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_ = reinterpret_cast<uint8*>(void_buffer);
793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_bytes_ += buffer_size_;
794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return true;
795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_ = NULL;
797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    buffer_size_ = 0;
798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    had_error_ = true;
799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint CodedOutputStream::VarintSize32Fallback(uint32 value) {
804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (value < (1 << 7)) {
805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return 1;
806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (value < (1 << 14)) {
807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return 2;
808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (value < (1 << 21)) {
809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return 3;
810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else if (value < (1 << 28)) {
811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return 4;
812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return 5;
814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint CodedOutputStream::VarintSize64(uint64 value) {
818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (value < (1ull << 35)) {
819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (value < (1ull << 7)) {
820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 1;
821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (value < (1ull << 14)) {
822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 2;
823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (value < (1ull << 21)) {
824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 3;
825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (value < (1ull << 28)) {
826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 4;
827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 5;
829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (value < (1ull << 42)) {
832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 6;
833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (value < (1ull << 49)) {
834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 7;
835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (value < (1ull << 56)) {
836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 8;
837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (value < (1ull << 63)) {
838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 9;
839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return 10;
841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace io
846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
848