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