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