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 //  Based on original Protocol Buffers design by
     33 //  Sanjay Ghemawat, Jeff Dean, and others.
     34 
     35 #include <google/protobuf/wire_format_lite_inl.h>
     36 
     37 #include <stack>
     38 #include <string>
     39 #include <vector>
     40 #include <google/protobuf/stubs/common.h>
     41 #include <google/protobuf/io/coded_stream_inl.h>
     42 #include <google/protobuf/io/zero_copy_stream.h>
     43 #include <google/protobuf/io/zero_copy_stream_impl.h>
     44 
     45 namespace google {
     46 namespace protobuf {
     47 namespace internal {
     48 
     49 #ifndef _MSC_VER    // MSVC doesn't like definitions of inline constants, GCC
     50                     // requires them.
     51 const int WireFormatLite::kMessageSetItemStartTag;
     52 const int WireFormatLite::kMessageSetItemEndTag;
     53 const int WireFormatLite::kMessageSetTypeIdTag;
     54 const int WireFormatLite::kMessageSetMessageTag;
     55 
     56 #endif
     57 
     58 const int WireFormatLite::kMessageSetItemTagsSize =
     59   io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) +
     60   io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) +
     61   io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) +
     62   io::CodedOutputStream::VarintSize32(kMessageSetMessageTag);
     63 
     64 const WireFormatLite::CppType
     65 WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
     66   static_cast<CppType>(0),  // 0 is reserved for errors
     67 
     68   CPPTYPE_DOUBLE,   // TYPE_DOUBLE
     69   CPPTYPE_FLOAT,    // TYPE_FLOAT
     70   CPPTYPE_INT64,    // TYPE_INT64
     71   CPPTYPE_UINT64,   // TYPE_UINT64
     72   CPPTYPE_INT32,    // TYPE_INT32
     73   CPPTYPE_UINT64,   // TYPE_FIXED64
     74   CPPTYPE_UINT32,   // TYPE_FIXED32
     75   CPPTYPE_BOOL,     // TYPE_BOOL
     76   CPPTYPE_STRING,   // TYPE_STRING
     77   CPPTYPE_MESSAGE,  // TYPE_GROUP
     78   CPPTYPE_MESSAGE,  // TYPE_MESSAGE
     79   CPPTYPE_STRING,   // TYPE_BYTES
     80   CPPTYPE_UINT32,   // TYPE_UINT32
     81   CPPTYPE_ENUM,     // TYPE_ENUM
     82   CPPTYPE_INT32,    // TYPE_SFIXED32
     83   CPPTYPE_INT64,    // TYPE_SFIXED64
     84   CPPTYPE_INT32,    // TYPE_SINT32
     85   CPPTYPE_INT64,    // TYPE_SINT64
     86 };
     87 
     88 const WireFormatLite::WireType
     89 WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
     90   static_cast<WireFormatLite::WireType>(-1),  // invalid
     91   WireFormatLite::WIRETYPE_FIXED64,           // TYPE_DOUBLE
     92   WireFormatLite::WIRETYPE_FIXED32,           // TYPE_FLOAT
     93   WireFormatLite::WIRETYPE_VARINT,            // TYPE_INT64
     94   WireFormatLite::WIRETYPE_VARINT,            // TYPE_UINT64
     95   WireFormatLite::WIRETYPE_VARINT,            // TYPE_INT32
     96   WireFormatLite::WIRETYPE_FIXED64,           // TYPE_FIXED64
     97   WireFormatLite::WIRETYPE_FIXED32,           // TYPE_FIXED32
     98   WireFormatLite::WIRETYPE_VARINT,            // TYPE_BOOL
     99   WireFormatLite::WIRETYPE_LENGTH_DELIMITED,  // TYPE_STRING
    100   WireFormatLite::WIRETYPE_START_GROUP,       // TYPE_GROUP
    101   WireFormatLite::WIRETYPE_LENGTH_DELIMITED,  // TYPE_MESSAGE
    102   WireFormatLite::WIRETYPE_LENGTH_DELIMITED,  // TYPE_BYTES
    103   WireFormatLite::WIRETYPE_VARINT,            // TYPE_UINT32
    104   WireFormatLite::WIRETYPE_VARINT,            // TYPE_ENUM
    105   WireFormatLite::WIRETYPE_FIXED32,           // TYPE_SFIXED32
    106   WireFormatLite::WIRETYPE_FIXED64,           // TYPE_SFIXED64
    107   WireFormatLite::WIRETYPE_VARINT,            // TYPE_SINT32
    108   WireFormatLite::WIRETYPE_VARINT,            // TYPE_SINT64
    109 };
    110 
    111 bool WireFormatLite::SkipField(
    112     io::CodedInputStream* input, uint32 tag) {
    113   switch (WireFormatLite::GetTagWireType(tag)) {
    114     case WireFormatLite::WIRETYPE_VARINT: {
    115       uint64 value;
    116       if (!input->ReadVarint64(&value)) return false;
    117       return true;
    118     }
    119     case WireFormatLite::WIRETYPE_FIXED64: {
    120       uint64 value;
    121       if (!input->ReadLittleEndian64(&value)) return false;
    122       return true;
    123     }
    124     case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
    125       uint32 length;
    126       if (!input->ReadVarint32(&length)) return false;
    127       if (!input->Skip(length)) return false;
    128       return true;
    129     }
    130     case WireFormatLite::WIRETYPE_START_GROUP: {
    131       if (!input->IncrementRecursionDepth()) return false;
    132       if (!SkipMessage(input)) return false;
    133       input->DecrementRecursionDepth();
    134       // Check that the ending tag matched the starting tag.
    135       if (!input->LastTagWas(WireFormatLite::MakeTag(
    136           WireFormatLite::GetTagFieldNumber(tag),
    137           WireFormatLite::WIRETYPE_END_GROUP))) {
    138         return false;
    139       }
    140       return true;
    141     }
    142     case WireFormatLite::WIRETYPE_END_GROUP: {
    143       return false;
    144     }
    145     case WireFormatLite::WIRETYPE_FIXED32: {
    146       uint32 value;
    147       if (!input->ReadLittleEndian32(&value)) return false;
    148       return true;
    149     }
    150     default: {
    151       return false;
    152     }
    153   }
    154 }
    155 
    156 bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
    157   while(true) {
    158     uint32 tag = input->ReadTag();
    159     if (tag == 0) {
    160       // End of input.  This is a valid place to end, so return true.
    161       return true;
    162     }
    163 
    164     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
    165 
    166     if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
    167       // Must be the end of the message.
    168       return true;
    169     }
    170 
    171     if (!SkipField(input, tag)) return false;
    172   }
    173 }
    174 
    175 bool FieldSkipper::SkipField(
    176     io::CodedInputStream* input, uint32 tag) {
    177   return WireFormatLite::SkipField(input, tag);
    178 }
    179 
    180 bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
    181   return WireFormatLite::SkipMessage(input);
    182 }
    183 
    184 void FieldSkipper::SkipUnknownEnum(
    185     int field_number, int value) {
    186   // Nothing.
    187 }
    188 
    189 bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
    190                                             bool (*is_valid)(int),
    191                                             RepeatedField<int>* values) {
    192   uint32 length;
    193   if (!input->ReadVarint32(&length)) return false;
    194   io::CodedInputStream::Limit limit = input->PushLimit(length);
    195   while (input->BytesUntilLimit() > 0) {
    196     int value;
    197     if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
    198         int, WireFormatLite::TYPE_ENUM>(input, &value)) {
    199       return false;
    200     }
    201     if (is_valid(value)) {
    202       values->Add(value);
    203     }
    204   }
    205   input->PopLimit(limit);
    206   return true;
    207 }
    208 
    209 void WireFormatLite::WriteInt32(int field_number, int32 value,
    210                                 io::CodedOutputStream* output) {
    211   WriteTag(field_number, WIRETYPE_VARINT, output);
    212   WriteInt32NoTag(value, output);
    213 }
    214 void WireFormatLite::WriteInt64(int field_number, int64 value,
    215                                 io::CodedOutputStream* output) {
    216   WriteTag(field_number, WIRETYPE_VARINT, output);
    217   WriteInt64NoTag(value, output);
    218 }
    219 void WireFormatLite::WriteUInt32(int field_number, uint32 value,
    220                                  io::CodedOutputStream* output) {
    221   WriteTag(field_number, WIRETYPE_VARINT, output);
    222   WriteUInt32NoTag(value, output);
    223 }
    224 void WireFormatLite::WriteUInt64(int field_number, uint64 value,
    225                                  io::CodedOutputStream* output) {
    226   WriteTag(field_number, WIRETYPE_VARINT, output);
    227   WriteUInt64NoTag(value, output);
    228 }
    229 void WireFormatLite::WriteSInt32(int field_number, int32 value,
    230                                  io::CodedOutputStream* output) {
    231   WriteTag(field_number, WIRETYPE_VARINT, output);
    232   WriteSInt32NoTag(value, output);
    233 }
    234 void WireFormatLite::WriteSInt64(int field_number, int64 value,
    235                                  io::CodedOutputStream* output) {
    236   WriteTag(field_number, WIRETYPE_VARINT, output);
    237   WriteSInt64NoTag(value, output);
    238 }
    239 void WireFormatLite::WriteFixed32(int field_number, uint32 value,
    240                                   io::CodedOutputStream* output) {
    241   WriteTag(field_number, WIRETYPE_FIXED32, output);
    242   WriteFixed32NoTag(value, output);
    243 }
    244 void WireFormatLite::WriteFixed64(int field_number, uint64 value,
    245                                   io::CodedOutputStream* output) {
    246   WriteTag(field_number, WIRETYPE_FIXED64, output);
    247   WriteFixed64NoTag(value, output);
    248 }
    249 void WireFormatLite::WriteSFixed32(int field_number, int32 value,
    250                                    io::CodedOutputStream* output) {
    251   WriteTag(field_number, WIRETYPE_FIXED32, output);
    252   WriteSFixed32NoTag(value, output);
    253 }
    254 void WireFormatLite::WriteSFixed64(int field_number, int64 value,
    255                                    io::CodedOutputStream* output) {
    256   WriteTag(field_number, WIRETYPE_FIXED64, output);
    257   WriteSFixed64NoTag(value, output);
    258 }
    259 void WireFormatLite::WriteFloat(int field_number, float value,
    260                                 io::CodedOutputStream* output) {
    261   WriteTag(field_number, WIRETYPE_FIXED32, output);
    262   WriteFloatNoTag(value, output);
    263 }
    264 void WireFormatLite::WriteDouble(int field_number, double value,
    265                                  io::CodedOutputStream* output) {
    266   WriteTag(field_number, WIRETYPE_FIXED64, output);
    267   WriteDoubleNoTag(value, output);
    268 }
    269 void WireFormatLite::WriteBool(int field_number, bool value,
    270                                io::CodedOutputStream* output) {
    271   WriteTag(field_number, WIRETYPE_VARINT, output);
    272   WriteBoolNoTag(value, output);
    273 }
    274 void WireFormatLite::WriteEnum(int field_number, int value,
    275                                io::CodedOutputStream* output) {
    276   WriteTag(field_number, WIRETYPE_VARINT, output);
    277   WriteEnumNoTag(value, output);
    278 }
    279 
    280 void WireFormatLite::WriteString(int field_number, const string& value,
    281                                  io::CodedOutputStream* output) {
    282   // String is for UTF-8 text only
    283   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    284   output->WriteVarint32(value.size());
    285   output->WriteString(value);
    286 }
    287 void WireFormatLite::WriteBytes(int field_number, const string& value,
    288                                 io::CodedOutputStream* output) {
    289   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    290   output->WriteVarint32(value.size());
    291   output->WriteString(value);
    292 }
    293 
    294 
    295 void WireFormatLite::WriteGroup(int field_number,
    296                                 const MessageLite& value,
    297                                 io::CodedOutputStream* output) {
    298   WriteTag(field_number, WIRETYPE_START_GROUP, output);
    299   value.SerializeWithCachedSizes(output);
    300   WriteTag(field_number, WIRETYPE_END_GROUP, output);
    301 }
    302 
    303 void WireFormatLite::WriteMessage(int field_number,
    304                                   const MessageLite& value,
    305                                   io::CodedOutputStream* output) {
    306   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    307   const int size = value.GetCachedSize();
    308   output->WriteVarint32(size);
    309   value.SerializeWithCachedSizes(output);
    310 }
    311 
    312 void WireFormatLite::WriteGroupMaybeToArray(int field_number,
    313                                             const MessageLite& value,
    314                                             io::CodedOutputStream* output) {
    315   WriteTag(field_number, WIRETYPE_START_GROUP, output);
    316   const int size = value.GetCachedSize();
    317   uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
    318   if (target != NULL) {
    319     uint8* end = value.SerializeWithCachedSizesToArray(target);
    320     GOOGLE_DCHECK_EQ(end - target, size);
    321   } else {
    322     value.SerializeWithCachedSizes(output);
    323   }
    324   WriteTag(field_number, WIRETYPE_END_GROUP, output);
    325 }
    326 
    327 void WireFormatLite::WriteMessageMaybeToArray(int field_number,
    328                                               const MessageLite& value,
    329                                               io::CodedOutputStream* output) {
    330   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    331   const int size = value.GetCachedSize();
    332   output->WriteVarint32(size);
    333   uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
    334   if (target != NULL) {
    335     uint8* end = value.SerializeWithCachedSizesToArray(target);
    336     GOOGLE_DCHECK_EQ(end - target, size);
    337   } else {
    338     value.SerializeWithCachedSizes(output);
    339   }
    340 }
    341 
    342 bool WireFormatLite::ReadString(io::CodedInputStream* input,
    343                                 string* value) {
    344   // String is for UTF-8 text only
    345   uint32 length;
    346   if (!input->ReadVarint32(&length)) return false;
    347   if (!input->InternalReadStringInline(value, length)) return false;
    348   return true;
    349 }
    350 bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
    351                                string* value) {
    352   uint32 length;
    353   if (!input->ReadVarint32(&length)) return false;
    354   return input->InternalReadStringInline(value, length);
    355 }
    356 
    357 }  // namespace internal
    358 }  // namespace protobuf
    359 }  // namespace google
    360