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