Home | History | Annotate | Download | only in protobuf
      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 //         wink (at) google.com (Wink Saville) (refactored from wire_format.h)
     33 //  Based on original Protocol Buffers design by
     34 //  Sanjay Ghemawat, Jeff Dean, and others.
     35 
     36 #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
     37 #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
     38 
     39 #ifdef _MSC_VER
     40 // This is required for min/max on VS2013 only.
     41 #include <algorithm>
     42 #endif
     43 
     44 #include <string>
     45 #include <google/protobuf/stubs/common.h>
     46 #include <google/protobuf/stubs/logging.h>
     47 #include <google/protobuf/message_lite.h>
     48 #include <google/protobuf/repeated_field.h>
     49 #include <google/protobuf/wire_format_lite.h>
     50 #include <google/protobuf/io/coded_stream.h>
     51 #include <google/protobuf/arenastring.h>
     52 
     53 
     54 namespace google {
     55 namespace protobuf {
     56 namespace internal {
     57 
     58 // Implementation details of ReadPrimitive.
     59 
     60 template <>
     61 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(
     62     io::CodedInputStream* input,
     63     int32* value) {
     64   uint32 temp;
     65   if (!input->ReadVarint32(&temp)) return false;
     66   *value = static_cast<int32>(temp);
     67   return true;
     68 }
     69 template <>
     70 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>(
     71     io::CodedInputStream* input,
     72     int64* value) {
     73   uint64 temp;
     74   if (!input->ReadVarint64(&temp)) return false;
     75   *value = static_cast<int64>(temp);
     76   return true;
     77 }
     78 template <>
     79 inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
     80     io::CodedInputStream* input,
     81     uint32* value) {
     82   return input->ReadVarint32(value);
     83 }
     84 template <>
     85 inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
     86     io::CodedInputStream* input,
     87     uint64* value) {
     88   return input->ReadVarint64(value);
     89 }
     90 template <>
     91 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(
     92     io::CodedInputStream* input,
     93     int32* value) {
     94   uint32 temp;
     95   if (!input->ReadVarint32(&temp)) return false;
     96   *value = ZigZagDecode32(temp);
     97   return true;
     98 }
     99 template <>
    100 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(
    101     io::CodedInputStream* input,
    102     int64* value) {
    103   uint64 temp;
    104   if (!input->ReadVarint64(&temp)) return false;
    105   *value = ZigZagDecode64(temp);
    106   return true;
    107 }
    108 template <>
    109 inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
    110     io::CodedInputStream* input,
    111     uint32* value) {
    112   return input->ReadLittleEndian32(value);
    113 }
    114 template <>
    115 inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
    116     io::CodedInputStream* input,
    117     uint64* value) {
    118   return input->ReadLittleEndian64(value);
    119 }
    120 template <>
    121 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>(
    122     io::CodedInputStream* input,
    123     int32* value) {
    124   uint32 temp;
    125   if (!input->ReadLittleEndian32(&temp)) return false;
    126   *value = static_cast<int32>(temp);
    127   return true;
    128 }
    129 template <>
    130 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>(
    131     io::CodedInputStream* input,
    132     int64* value) {
    133   uint64 temp;
    134   if (!input->ReadLittleEndian64(&temp)) return false;
    135   *value = static_cast<int64>(temp);
    136   return true;
    137 }
    138 template <>
    139 inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
    140     io::CodedInputStream* input,
    141     float* value) {
    142   uint32 temp;
    143   if (!input->ReadLittleEndian32(&temp)) return false;
    144   *value = DecodeFloat(temp);
    145   return true;
    146 }
    147 template <>
    148 inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
    149     io::CodedInputStream* input,
    150     double* value) {
    151   uint64 temp;
    152   if (!input->ReadLittleEndian64(&temp)) return false;
    153   *value = DecodeDouble(temp);
    154   return true;
    155 }
    156 template <>
    157 inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
    158     io::CodedInputStream* input,
    159     bool* value) {
    160   uint64 temp;
    161   if (!input->ReadVarint64(&temp)) return false;
    162   *value = temp != 0;
    163   return true;
    164 }
    165 template <>
    166 inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
    167     io::CodedInputStream* input,
    168     int* value) {
    169   uint32 temp;
    170   if (!input->ReadVarint32(&temp)) return false;
    171   *value = static_cast<int>(temp);
    172   return true;
    173 }
    174 
    175 template <>
    176 inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
    177   uint32, WireFormatLite::TYPE_FIXED32>(
    178     const uint8* buffer,
    179     uint32* value) {
    180   return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
    181 }
    182 template <>
    183 inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
    184   uint64, WireFormatLite::TYPE_FIXED64>(
    185     const uint8* buffer,
    186     uint64* value) {
    187   return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
    188 }
    189 template <>
    190 inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
    191   int32, WireFormatLite::TYPE_SFIXED32>(
    192     const uint8* buffer,
    193     int32* value) {
    194   uint32 temp;
    195   buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
    196   *value = static_cast<int32>(temp);
    197   return buffer;
    198 }
    199 template <>
    200 inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
    201   int64, WireFormatLite::TYPE_SFIXED64>(
    202     const uint8* buffer,
    203     int64* value) {
    204   uint64 temp;
    205   buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
    206   *value = static_cast<int64>(temp);
    207   return buffer;
    208 }
    209 template <>
    210 inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
    211   float, WireFormatLite::TYPE_FLOAT>(
    212     const uint8* buffer,
    213     float* value) {
    214   uint32 temp;
    215   buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
    216   *value = DecodeFloat(temp);
    217   return buffer;
    218 }
    219 template <>
    220 inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
    221   double, WireFormatLite::TYPE_DOUBLE>(
    222     const uint8* buffer,
    223     double* value) {
    224   uint64 temp;
    225   buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
    226   *value = DecodeDouble(temp);
    227   return buffer;
    228 }
    229 
    230 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
    231 inline bool WireFormatLite::ReadRepeatedPrimitive(
    232     int,  // tag_size, unused.
    233     uint32 tag,
    234     io::CodedInputStream* input,
    235     RepeatedField<CType>* values) {
    236   CType value;
    237   if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
    238   values->Add(value);
    239   int elements_already_reserved = values->Capacity() - values->size();
    240   while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
    241     if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
    242     values->AddAlreadyReserved(value);
    243     elements_already_reserved--;
    244   }
    245   return true;
    246 }
    247 
    248 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
    249 inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
    250     int tag_size,
    251     uint32 tag,
    252     io::CodedInputStream* input,
    253     RepeatedField<CType>* values) {
    254   GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size);
    255   CType value;
    256   if (!ReadPrimitive<CType, DeclaredType>(input, &value))
    257     return false;
    258   values->Add(value);
    259 
    260   // For fixed size values, repeated values can be read more quickly by
    261   // reading directly from a raw array.
    262   //
    263   // We can get a tight loop by only reading as many elements as can be
    264   // added to the RepeatedField without having to do any resizing. Additionally,
    265   // we only try to read as many elements as are available from the current
    266   // buffer space. Doing so avoids having to perform boundary checks when
    267   // reading the value: the maximum number of elements that can be read is
    268   // known outside of the loop.
    269   const void* void_pointer;
    270   int size;
    271   input->GetDirectBufferPointerInline(&void_pointer, &size);
    272   if (size > 0) {
    273     const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
    274     // The number of bytes each type occupies on the wire.
    275     const int per_value_size = tag_size + sizeof(value);
    276 
    277     int elements_available =
    278         std::min(values->Capacity() - values->size(), size / per_value_size);
    279     int num_read = 0;
    280     while (num_read < elements_available &&
    281            (buffer = io::CodedInputStream::ExpectTagFromArray(
    282                buffer, tag)) != NULL) {
    283       buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
    284       values->AddAlreadyReserved(value);
    285       ++num_read;
    286     }
    287     const int read_bytes = num_read * per_value_size;
    288     if (read_bytes > 0) {
    289       input->Skip(read_bytes);
    290     }
    291   }
    292   return true;
    293 }
    294 
    295 // Specializations of ReadRepeatedPrimitive for the fixed size types, which use
    296 // the optimized code path.
    297 #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)             \
    298 template <>                                                                    \
    299 inline bool WireFormatLite::ReadRepeatedPrimitive<                             \
    300   CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                     \
    301     int tag_size,                                                              \
    302     uint32 tag,                                                                \
    303     io::CodedInputStream* input,                                               \
    304     RepeatedField<CPPTYPE>* values) {                                          \
    305   return ReadRepeatedFixedSizePrimitive<                                       \
    306     CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                   \
    307       tag_size, tag, input, values);                                           \
    308 }
    309 
    310 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
    311 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
    312 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
    313 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
    314 READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
    315 READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
    316 
    317 #undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
    318 
    319 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
    320 bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
    321     int tag_size,
    322     uint32 tag,
    323     io::CodedInputStream* input,
    324     RepeatedField<CType>* value) {
    325   return ReadRepeatedPrimitive<CType, DeclaredType>(
    326       tag_size, tag, input, value);
    327 }
    328 
    329 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
    330 inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
    331                                                 RepeatedField<CType>* values) {
    332   uint32 length;
    333   if (!input->ReadVarint32(&length)) return false;
    334   io::CodedInputStream::Limit limit = input->PushLimit(length);
    335   while (input->BytesUntilLimit() > 0) {
    336     CType value;
    337     if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
    338     values->Add(value);
    339   }
    340   input->PopLimit(limit);
    341   return true;
    342 }
    343 
    344 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
    345 inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
    346     io::CodedInputStream* input, RepeatedField<CType>* values) {
    347   uint32 length;
    348   if (!input->ReadVarint32(&length)) return false;
    349   const uint32 old_entries = values->size();
    350   const uint32 new_entries = length / sizeof(CType);
    351   const uint32 new_bytes = new_entries * sizeof(CType);
    352   if (new_bytes != length) return false;
    353   // We would *like* to pre-allocate the buffer to write into (for
    354   // speed), but *must* avoid performing a very large allocation due
    355   // to a malicious user-supplied "length" above.  So we have a fast
    356   // path that pre-allocates when the "length" is less than a bound.
    357   // We determine the bound by calling BytesUntilTotalBytesLimit() and
    358   // BytesUntilLimit().  These return -1 to mean "no limit set".
    359   // There are four cases:
    360   // TotalBytesLimit  Limit
    361   // -1               -1     Use slow path.
    362   // -1               >= 0   Use fast path if length <= Limit.
    363   // >= 0             -1     Use slow path.
    364   // >= 0             >= 0   Use fast path if length <= min(both limits).
    365   int64 bytes_limit = input->BytesUntilTotalBytesLimit();
    366   if (bytes_limit == -1) {
    367     bytes_limit = input->BytesUntilLimit();
    368   } else {
    369     bytes_limit =
    370         std::min(bytes_limit, static_cast<int64>(input->BytesUntilLimit()));
    371   }
    372   if (bytes_limit >= new_bytes) {
    373     // Fast-path that pre-allocates *values to the final size.
    374 #if defined(PROTOBUF_LITTLE_ENDIAN)
    375     values->Resize(old_entries + new_entries, 0);
    376     // values->mutable_data() may change after Resize(), so do this after:
    377     void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries);
    378     if (!input->ReadRaw(dest, new_bytes)) {
    379       values->Truncate(old_entries);
    380       return false;
    381     }
    382 #else
    383     values->Reserve(old_entries + new_entries);
    384     CType value;
    385     for (uint32 i = 0; i < new_entries; ++i) {
    386       if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
    387       values->AddAlreadyReserved(value);
    388     }
    389 #endif
    390   } else {
    391     // This is the slow-path case where "length" may be too large to
    392     // safely allocate.  We read as much as we can into *values
    393     // without pre-allocating "length" bytes.
    394     CType value;
    395     for (uint32 i = 0; i < new_entries; ++i) {
    396       if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
    397       values->Add(value);
    398     }
    399   }
    400   return true;
    401 }
    402 
    403 // Specializations of ReadPackedPrimitive for the fixed size types, which use
    404 // an optimized code path.
    405 #define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)      \
    406 template <>                                                                    \
    407 inline bool WireFormatLite::ReadPackedPrimitive<                               \
    408   CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                     \
    409     io::CodedInputStream* input,                                               \
    410     RepeatedField<CPPTYPE>* values) {                                          \
    411   return ReadPackedFixedSizePrimitive<                                         \
    412       CPPTYPE, WireFormatLite::DECLARED_TYPE>(input, values);                  \
    413 }
    414 
    415 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
    416 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
    417 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
    418 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
    419 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
    420 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
    421 
    422 #undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
    423 
    424 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
    425 bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
    426                                                  RepeatedField<CType>* values) {
    427   return ReadPackedPrimitive<CType, DeclaredType>(input, values);
    428 }
    429 
    430 
    431 
    432 inline bool WireFormatLite::ReadGroup(int field_number,
    433                                       io::CodedInputStream* input,
    434                                       MessageLite* value) {
    435   if (!input->IncrementRecursionDepth()) return false;
    436   if (!value->MergePartialFromCodedStream(input)) return false;
    437   input->DecrementRecursionDepth();
    438   // Make sure the last thing read was an end tag for this group.
    439   if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
    440     return false;
    441   }
    442   return true;
    443 }
    444 inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
    445                                         MessageLite* value) {
    446   uint32 length;
    447   if (!input->ReadVarint32(&length)) return false;
    448   std::pair<io::CodedInputStream::Limit, int> p =
    449       input->IncrementRecursionDepthAndPushLimit(length);
    450   if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false;
    451   // Make sure that parsing stopped when the limit was hit, not at an endgroup
    452   // tag.
    453   return input->DecrementRecursionDepthAndPopLimit(p.first);
    454 }
    455 
    456 // We name the template parameter something long and extremely unlikely to occur
    457 // elsewhere because a *qualified* member access expression designed to avoid
    458 // virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the
    459 // name of the qualifying class to be looked up both in the context of the full
    460 // expression (finding the template parameter) and in the context of the object
    461 // whose member we are accessing. This could potentially find a nested type
    462 // within that object. The standard goes on to require these names to refer to
    463 // the same entity, which this collision would violate. The lack of a safe way
    464 // to avoid this collision appears to be a defect in the standard, but until it
    465 // is corrected, we choose the name to avoid accidental collisions.
    466 template<typename MessageType_WorkAroundCppLookupDefect>
    467 inline bool WireFormatLite::ReadGroupNoVirtual(
    468     int field_number, io::CodedInputStream* input,
    469     MessageType_WorkAroundCppLookupDefect* value) {
    470   if (!input->IncrementRecursionDepth()) return false;
    471   if (!value->
    472       MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
    473     return false;
    474   input->UnsafeDecrementRecursionDepth();
    475   // Make sure the last thing read was an end tag for this group.
    476   if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
    477     return false;
    478   }
    479   return true;
    480 }
    481 template<typename MessageType_WorkAroundCppLookupDefect>
    482 inline bool WireFormatLite::ReadGroupNoVirtualNoRecursionDepth(
    483     int field_number, io::CodedInputStream* input,
    484     MessageType_WorkAroundCppLookupDefect* value) {
    485   return value->MessageType_WorkAroundCppLookupDefect::
    486              MergePartialFromCodedStream(input) &&
    487          input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP));
    488 }
    489 template<typename MessageType_WorkAroundCppLookupDefect>
    490 inline bool WireFormatLite::ReadMessageNoVirtual(
    491     io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
    492   uint32 length;
    493   if (!input->ReadVarint32(&length)) return false;
    494   std::pair<io::CodedInputStream::Limit, int> p =
    495       input->IncrementRecursionDepthAndPushLimit(length);
    496   if (p.second < 0 || !value->
    497       MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
    498     return false;
    499   // Make sure that parsing stopped when the limit was hit, not at an endgroup
    500   // tag.
    501   return input->DecrementRecursionDepthAndPopLimit(p.first);
    502 }
    503 template<typename MessageType_WorkAroundCppLookupDefect>
    504 inline bool WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
    505     io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
    506   io::CodedInputStream::Limit old_limit = input->ReadLengthAndPushLimit();
    507   if (!value->
    508       MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
    509     return false;
    510   // Make sure that parsing stopped when the limit was hit, not at an endgroup
    511   // tag.
    512   return input->CheckEntireMessageConsumedAndPopLimit(old_limit);
    513 }
    514 
    515 // ===================================================================
    516 
    517 inline void WireFormatLite::WriteTag(int field_number, WireType type,
    518                                      io::CodedOutputStream* output) {
    519   output->WriteTag(MakeTag(field_number, type));
    520 }
    521 
    522 inline void WireFormatLite::WriteInt32NoTag(int32 value,
    523                                             io::CodedOutputStream* output) {
    524   output->WriteVarint32SignExtended(value);
    525 }
    526 inline void WireFormatLite::WriteInt64NoTag(int64 value,
    527                                             io::CodedOutputStream* output) {
    528   output->WriteVarint64(static_cast<uint64>(value));
    529 }
    530 inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
    531                                              io::CodedOutputStream* output) {
    532   output->WriteVarint32(value);
    533 }
    534 inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
    535                                              io::CodedOutputStream* output) {
    536   output->WriteVarint64(value);
    537 }
    538 inline void WireFormatLite::WriteSInt32NoTag(int32 value,
    539                                              io::CodedOutputStream* output) {
    540   output->WriteVarint32(ZigZagEncode32(value));
    541 }
    542 inline void WireFormatLite::WriteSInt64NoTag(int64 value,
    543                                              io::CodedOutputStream* output) {
    544   output->WriteVarint64(ZigZagEncode64(value));
    545 }
    546 inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
    547                                               io::CodedOutputStream* output) {
    548   output->WriteLittleEndian32(value);
    549 }
    550 inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
    551                                               io::CodedOutputStream* output) {
    552   output->WriteLittleEndian64(value);
    553 }
    554 inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
    555                                                io::CodedOutputStream* output) {
    556   output->WriteLittleEndian32(static_cast<uint32>(value));
    557 }
    558 inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
    559                                                io::CodedOutputStream* output) {
    560   output->WriteLittleEndian64(static_cast<uint64>(value));
    561 }
    562 inline void WireFormatLite::WriteFloatNoTag(float value,
    563                                             io::CodedOutputStream* output) {
    564   output->WriteLittleEndian32(EncodeFloat(value));
    565 }
    566 inline void WireFormatLite::WriteDoubleNoTag(double value,
    567                                              io::CodedOutputStream* output) {
    568   output->WriteLittleEndian64(EncodeDouble(value));
    569 }
    570 inline void WireFormatLite::WriteBoolNoTag(bool value,
    571                                            io::CodedOutputStream* output) {
    572   output->WriteVarint32(value ? 1 : 0);
    573 }
    574 inline void WireFormatLite::WriteEnumNoTag(int value,
    575                                            io::CodedOutputStream* output) {
    576   output->WriteVarint32SignExtended(value);
    577 }
    578 
    579 // See comment on ReadGroupNoVirtual to understand the need for this template
    580 // parameter name.
    581 template<typename MessageType_WorkAroundCppLookupDefect>
    582 inline void WireFormatLite::WriteGroupNoVirtual(
    583     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
    584     io::CodedOutputStream* output) {
    585   WriteTag(field_number, WIRETYPE_START_GROUP, output);
    586   value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
    587   WriteTag(field_number, WIRETYPE_END_GROUP, output);
    588 }
    589 template<typename MessageType_WorkAroundCppLookupDefect>
    590 inline void WireFormatLite::WriteMessageNoVirtual(
    591     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
    592     io::CodedOutputStream* output) {
    593   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    594   output->WriteVarint32(
    595       value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
    596   value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
    597 }
    598 
    599 // ===================================================================
    600 
    601 inline uint8* WireFormatLite::WriteTagToArray(int field_number,
    602                                               WireType type,
    603                                               uint8* target) {
    604   return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
    605                                                 target);
    606 }
    607 
    608 inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
    609                                                      uint8* target) {
    610   return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
    611 }
    612 inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
    613                                                      uint8* target) {
    614   return io::CodedOutputStream::WriteVarint64ToArray(
    615       static_cast<uint64>(value), target);
    616 }
    617 inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
    618                                                       uint8* target) {
    619   return io::CodedOutputStream::WriteVarint32ToArray(value, target);
    620 }
    621 inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
    622                                                       uint8* target) {
    623   return io::CodedOutputStream::WriteVarint64ToArray(value, target);
    624 }
    625 inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
    626                                                       uint8* target) {
    627   return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
    628                                                      target);
    629 }
    630 inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
    631                                                       uint8* target) {
    632   return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
    633                                                      target);
    634 }
    635 inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
    636                                                        uint8* target) {
    637   return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
    638 }
    639 inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
    640                                                        uint8* target) {
    641   return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
    642 }
    643 inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
    644                                                         uint8* target) {
    645   return io::CodedOutputStream::WriteLittleEndian32ToArray(
    646       static_cast<uint32>(value), target);
    647 }
    648 inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
    649                                                         uint8* target) {
    650   return io::CodedOutputStream::WriteLittleEndian64ToArray(
    651       static_cast<uint64>(value), target);
    652 }
    653 inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
    654                                                      uint8* target) {
    655   return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
    656                                                            target);
    657 }
    658 inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
    659                                                       uint8* target) {
    660   return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
    661                                                            target);
    662 }
    663 inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
    664                                                     uint8* target) {
    665   return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
    666 }
    667 inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
    668                                                     uint8* target) {
    669   return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
    670 }
    671 
    672 inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
    673                                                 int32 value,
    674                                                 uint8* target) {
    675   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
    676   return WriteInt32NoTagToArray(value, target);
    677 }
    678 inline uint8* WireFormatLite::WriteInt64ToArray(int field_number,
    679                                                 int64 value,
    680                                                 uint8* target) {
    681   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
    682   return WriteInt64NoTagToArray(value, target);
    683 }
    684 inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number,
    685                                                  uint32 value,
    686                                                  uint8* target) {
    687   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
    688   return WriteUInt32NoTagToArray(value, target);
    689 }
    690 inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number,
    691                                                  uint64 value,
    692                                                  uint8* target) {
    693   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
    694   return WriteUInt64NoTagToArray(value, target);
    695 }
    696 inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number,
    697                                                  int32 value,
    698                                                  uint8* target) {
    699   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
    700   return WriteSInt32NoTagToArray(value, target);
    701 }
    702 inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number,
    703                                                  int64 value,
    704                                                  uint8* target) {
    705   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
    706   return WriteSInt64NoTagToArray(value, target);
    707 }
    708 inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
    709                                                   uint32 value,
    710                                                   uint8* target) {
    711   target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
    712   return WriteFixed32NoTagToArray(value, target);
    713 }
    714 inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
    715                                                   uint64 value,
    716                                                   uint8* target) {
    717   target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
    718   return WriteFixed64NoTagToArray(value, target);
    719 }
    720 inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
    721                                                    int32 value,
    722                                                    uint8* target) {
    723   target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
    724   return WriteSFixed32NoTagToArray(value, target);
    725 }
    726 inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
    727                                                    int64 value,
    728                                                    uint8* target) {
    729   target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
    730   return WriteSFixed64NoTagToArray(value, target);
    731 }
    732 inline uint8* WireFormatLite::WriteFloatToArray(int field_number,
    733                                                 float value,
    734                                                 uint8* target) {
    735   target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
    736   return WriteFloatNoTagToArray(value, target);
    737 }
    738 inline uint8* WireFormatLite::WriteDoubleToArray(int field_number,
    739                                                  double value,
    740                                                  uint8* target) {
    741   target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
    742   return WriteDoubleNoTagToArray(value, target);
    743 }
    744 inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
    745                                                bool value,
    746                                                uint8* target) {
    747   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
    748   return WriteBoolNoTagToArray(value, target);
    749 }
    750 inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
    751                                                int value,
    752                                                uint8* target) {
    753   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
    754   return WriteEnumNoTagToArray(value, target);
    755 }
    756 
    757 inline uint8* WireFormatLite::WriteStringToArray(int field_number,
    758                                                  const string& value,
    759                                                  uint8* target) {
    760   // String is for UTF-8 text only
    761   // WARNING:  In wire_format.cc, both strings and bytes are handled by
    762   //   WriteString() to avoid code duplication.  If the implementations become
    763   //   different, you will need to update that usage.
    764   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
    765   return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
    766 }
    767 inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
    768                                                 const string& value,
    769                                                 uint8* target) {
    770   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
    771   return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
    772 }
    773 
    774 
    775 inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
    776                                                 const MessageLite& value,
    777                                                 uint8* target) {
    778   target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
    779   target = value.SerializeWithCachedSizesToArray(target);
    780   return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
    781 }
    782 inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
    783                                                   const MessageLite& value,
    784                                                   uint8* target) {
    785   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
    786   target = io::CodedOutputStream::WriteVarint32ToArray(
    787     value.GetCachedSize(), target);
    788   return value.SerializeWithCachedSizesToArray(target);
    789 }
    790 
    791 // See comment on ReadGroupNoVirtual to understand the need for this template
    792 // parameter name.
    793 template<typename MessageType_WorkAroundCppLookupDefect>
    794 inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
    795     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
    796     uint8* target) {
    797   target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
    798   target = value.MessageType_WorkAroundCppLookupDefect
    799       ::SerializeWithCachedSizesToArray(target);
    800   return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
    801 }
    802 template<typename MessageType_WorkAroundCppLookupDefect>
    803 inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
    804     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
    805     uint8* target) {
    806   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
    807   target = io::CodedOutputStream::WriteVarint32ToArray(
    808     value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
    809   return value.MessageType_WorkAroundCppLookupDefect
    810       ::SerializeWithCachedSizesToArray(target);
    811 }
    812 
    813 // ===================================================================
    814 
    815 inline int WireFormatLite::Int32Size(int32 value) {
    816   return io::CodedOutputStream::VarintSize32SignExtended(value);
    817 }
    818 inline int WireFormatLite::Int64Size(int64 value) {
    819   return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
    820 }
    821 inline int WireFormatLite::UInt32Size(uint32 value) {
    822   return io::CodedOutputStream::VarintSize32(value);
    823 }
    824 inline int WireFormatLite::UInt64Size(uint64 value) {
    825   return io::CodedOutputStream::VarintSize64(value);
    826 }
    827 inline int WireFormatLite::SInt32Size(int32 value) {
    828   return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
    829 }
    830 inline int WireFormatLite::SInt64Size(int64 value) {
    831   return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
    832 }
    833 inline int WireFormatLite::EnumSize(int value) {
    834   return io::CodedOutputStream::VarintSize32SignExtended(value);
    835 }
    836 
    837 inline int WireFormatLite::StringSize(const string& value) {
    838   return static_cast<int>(
    839       io::CodedOutputStream::VarintSize32(static_cast<uint32>(value.size())) +
    840       value.size());
    841 }
    842 inline int WireFormatLite::BytesSize(const string& value) {
    843   return static_cast<int>(
    844       io::CodedOutputStream::VarintSize32(static_cast<uint32>(value.size())) +
    845       value.size());
    846 }
    847 
    848 
    849 inline int WireFormatLite::GroupSize(const MessageLite& value) {
    850   return value.ByteSize();
    851 }
    852 inline int WireFormatLite::MessageSize(const MessageLite& value) {
    853   return LengthDelimitedSize(value.ByteSize());
    854 }
    855 
    856 // See comment on ReadGroupNoVirtual to understand the need for this template
    857 // parameter name.
    858 template<typename MessageType_WorkAroundCppLookupDefect>
    859 inline int WireFormatLite::GroupSizeNoVirtual(
    860     const MessageType_WorkAroundCppLookupDefect& value) {
    861   return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
    862 }
    863 template<typename MessageType_WorkAroundCppLookupDefect>
    864 inline int WireFormatLite::MessageSizeNoVirtual(
    865     const MessageType_WorkAroundCppLookupDefect& value) {
    866   return LengthDelimitedSize(
    867       value.MessageType_WorkAroundCppLookupDefect::ByteSize());
    868 }
    869 
    870 inline int WireFormatLite::LengthDelimitedSize(int length) {
    871   return io::CodedOutputStream::VarintSize32(length) + length;
    872 }
    873 
    874 }  // namespace internal
    875 }  // namespace protobuf
    876 
    877 }  // namespace google
    878 #endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
    879