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