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