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