Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // Author: kenton (at) google.com (Kenton Varda)
     32 //  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_lite.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::StaticVarintSize32<kMessageSetItemStartTag>::value +
     60   io::CodedOutputStream::StaticVarintSize32<kMessageSetItemEndTag>::value +
     61   io::CodedOutputStream::StaticVarintSize32<kMessageSetTypeIdTag>::value +
     62   io::CodedOutputStream::StaticVarintSize32<kMessageSetMessageTag>::value;
     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::SkipField(
    157     io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) {
    158   switch (WireFormatLite::GetTagWireType(tag)) {
    159     case WireFormatLite::WIRETYPE_VARINT: {
    160       uint64 value;
    161       if (!input->ReadVarint64(&value)) return false;
    162       output->WriteVarint32(tag);
    163       output->WriteVarint64(value);
    164       return true;
    165     }
    166     case WireFormatLite::WIRETYPE_FIXED64: {
    167       uint64 value;
    168       if (!input->ReadLittleEndian64(&value)) return false;
    169       output->WriteVarint32(tag);
    170       output->WriteLittleEndian64(value);
    171       return true;
    172     }
    173     case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
    174       uint32 length;
    175       if (!input->ReadVarint32(&length)) return false;
    176       output->WriteVarint32(tag);
    177       output->WriteVarint32(length);
    178       // TODO(mkilavuz): Provide API to prevent extra string copying.
    179       string temp;
    180       if (!input->ReadString(&temp, length)) return false;
    181       output->WriteString(temp);
    182       return true;
    183     }
    184     case WireFormatLite::WIRETYPE_START_GROUP: {
    185       output->WriteVarint32(tag);
    186       if (!input->IncrementRecursionDepth()) return false;
    187       if (!SkipMessage(input, output)) return false;
    188       input->DecrementRecursionDepth();
    189       // Check that the ending tag matched the starting tag.
    190       if (!input->LastTagWas(WireFormatLite::MakeTag(
    191           WireFormatLite::GetTagFieldNumber(tag),
    192           WireFormatLite::WIRETYPE_END_GROUP))) {
    193         return false;
    194       }
    195       return true;
    196     }
    197     case WireFormatLite::WIRETYPE_END_GROUP: {
    198       return false;
    199     }
    200     case WireFormatLite::WIRETYPE_FIXED32: {
    201       uint32 value;
    202       if (!input->ReadLittleEndian32(&value)) return false;
    203       output->WriteVarint32(tag);
    204       output->WriteLittleEndian32(value);
    205       return true;
    206     }
    207     default: {
    208       return false;
    209     }
    210   }
    211 }
    212 
    213 bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
    214   while (true) {
    215     uint32 tag = input->ReadTag();
    216     if (tag == 0) {
    217       // End of input.  This is a valid place to end, so return true.
    218       return true;
    219     }
    220 
    221     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
    222 
    223     if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
    224       // Must be the end of the message.
    225       return true;
    226     }
    227 
    228     if (!SkipField(input, tag)) return false;
    229   }
    230 }
    231 
    232 bool WireFormatLite::SkipMessage(io::CodedInputStream* input,
    233     io::CodedOutputStream* output) {
    234   while (true) {
    235     uint32 tag = input->ReadTag();
    236     if (tag == 0) {
    237       // End of input.  This is a valid place to end, so return true.
    238       return true;
    239     }
    240 
    241     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
    242 
    243     if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
    244       output->WriteVarint32(tag);
    245       // Must be the end of the message.
    246       return true;
    247     }
    248 
    249     if (!SkipField(input, tag, output)) return false;
    250   }
    251 }
    252 
    253 bool FieldSkipper::SkipField(
    254     io::CodedInputStream* input, uint32 tag) {
    255   return WireFormatLite::SkipField(input, tag);
    256 }
    257 
    258 bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
    259   return WireFormatLite::SkipMessage(input);
    260 }
    261 
    262 void FieldSkipper::SkipUnknownEnum(
    263     int /* field_number */, int /* value */) {
    264   // Nothing.
    265 }
    266 
    267 bool CodedOutputStreamFieldSkipper::SkipField(
    268     io::CodedInputStream* input, uint32 tag) {
    269   return WireFormatLite::SkipField(input, tag, unknown_fields_);
    270 }
    271 
    272 bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) {
    273   return WireFormatLite::SkipMessage(input, unknown_fields_);
    274 }
    275 
    276 void CodedOutputStreamFieldSkipper::SkipUnknownEnum(
    277     int field_number, int value) {
    278   unknown_fields_->WriteVarint32(field_number);
    279   unknown_fields_->WriteVarint64(value);
    280 }
    281 
    282 bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
    283                                             bool (*is_valid)(int),
    284                                             RepeatedField<int>* values) {
    285   uint32 length;
    286   if (!input->ReadVarint32(&length)) return false;
    287   io::CodedInputStream::Limit limit = input->PushLimit(length);
    288   while (input->BytesUntilLimit() > 0) {
    289     int value;
    290     if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
    291         int, WireFormatLite::TYPE_ENUM>(input, &value)) {
    292       return false;
    293     }
    294     if (is_valid(value)) {
    295       values->Add(value);
    296     }
    297   }
    298   input->PopLimit(limit);
    299   return true;
    300 }
    301 
    302 void WireFormatLite::WriteInt32(int field_number, int32 value,
    303                                 io::CodedOutputStream* output) {
    304   WriteTag(field_number, WIRETYPE_VARINT, output);
    305   WriteInt32NoTag(value, output);
    306 }
    307 void WireFormatLite::WriteInt64(int field_number, int64 value,
    308                                 io::CodedOutputStream* output) {
    309   WriteTag(field_number, WIRETYPE_VARINT, output);
    310   WriteInt64NoTag(value, output);
    311 }
    312 void WireFormatLite::WriteUInt32(int field_number, uint32 value,
    313                                  io::CodedOutputStream* output) {
    314   WriteTag(field_number, WIRETYPE_VARINT, output);
    315   WriteUInt32NoTag(value, output);
    316 }
    317 void WireFormatLite::WriteUInt64(int field_number, uint64 value,
    318                                  io::CodedOutputStream* output) {
    319   WriteTag(field_number, WIRETYPE_VARINT, output);
    320   WriteUInt64NoTag(value, output);
    321 }
    322 void WireFormatLite::WriteSInt32(int field_number, int32 value,
    323                                  io::CodedOutputStream* output) {
    324   WriteTag(field_number, WIRETYPE_VARINT, output);
    325   WriteSInt32NoTag(value, output);
    326 }
    327 void WireFormatLite::WriteSInt64(int field_number, int64 value,
    328                                  io::CodedOutputStream* output) {
    329   WriteTag(field_number, WIRETYPE_VARINT, output);
    330   WriteSInt64NoTag(value, output);
    331 }
    332 void WireFormatLite::WriteFixed32(int field_number, uint32 value,
    333                                   io::CodedOutputStream* output) {
    334   WriteTag(field_number, WIRETYPE_FIXED32, output);
    335   WriteFixed32NoTag(value, output);
    336 }
    337 void WireFormatLite::WriteFixed64(int field_number, uint64 value,
    338                                   io::CodedOutputStream* output) {
    339   WriteTag(field_number, WIRETYPE_FIXED64, output);
    340   WriteFixed64NoTag(value, output);
    341 }
    342 void WireFormatLite::WriteSFixed32(int field_number, int32 value,
    343                                    io::CodedOutputStream* output) {
    344   WriteTag(field_number, WIRETYPE_FIXED32, output);
    345   WriteSFixed32NoTag(value, output);
    346 }
    347 void WireFormatLite::WriteSFixed64(int field_number, int64 value,
    348                                    io::CodedOutputStream* output) {
    349   WriteTag(field_number, WIRETYPE_FIXED64, output);
    350   WriteSFixed64NoTag(value, output);
    351 }
    352 void WireFormatLite::WriteFloat(int field_number, float value,
    353                                 io::CodedOutputStream* output) {
    354   WriteTag(field_number, WIRETYPE_FIXED32, output);
    355   WriteFloatNoTag(value, output);
    356 }
    357 void WireFormatLite::WriteDouble(int field_number, double value,
    358                                  io::CodedOutputStream* output) {
    359   WriteTag(field_number, WIRETYPE_FIXED64, output);
    360   WriteDoubleNoTag(value, output);
    361 }
    362 void WireFormatLite::WriteBool(int field_number, bool value,
    363                                io::CodedOutputStream* output) {
    364   WriteTag(field_number, WIRETYPE_VARINT, output);
    365   WriteBoolNoTag(value, output);
    366 }
    367 void WireFormatLite::WriteEnum(int field_number, int value,
    368                                io::CodedOutputStream* output) {
    369   WriteTag(field_number, WIRETYPE_VARINT, output);
    370   WriteEnumNoTag(value, output);
    371 }
    372 
    373 void WireFormatLite::WriteString(int field_number, const string& value,
    374                                  io::CodedOutputStream* output) {
    375   // String is for UTF-8 text only
    376   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    377   GOOGLE_CHECK(value.size() <= kint32max);
    378   output->WriteVarint32(value.size());
    379   output->WriteString(value);
    380 }
    381 void WireFormatLite::WriteStringMaybeAliased(
    382     int field_number, const string& value,
    383     io::CodedOutputStream* output) {
    384   // String is for UTF-8 text only
    385   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    386   GOOGLE_CHECK(value.size() <= kint32max);
    387   output->WriteVarint32(value.size());
    388   output->WriteRawMaybeAliased(value.data(), value.size());
    389 }
    390 void WireFormatLite::WriteBytes(int field_number, const string& value,
    391                                 io::CodedOutputStream* output) {
    392   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    393   GOOGLE_CHECK(value.size() <= kint32max);
    394   output->WriteVarint32(value.size());
    395   output->WriteString(value);
    396 }
    397 void WireFormatLite::WriteBytesMaybeAliased(
    398     int field_number, const string& value,
    399     io::CodedOutputStream* output) {
    400   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    401   GOOGLE_CHECK(value.size() <= kint32max);
    402   output->WriteVarint32(value.size());
    403   output->WriteRawMaybeAliased(value.data(), value.size());
    404 }
    405 
    406 
    407 void WireFormatLite::WriteGroup(int field_number,
    408                                 const MessageLite& value,
    409                                 io::CodedOutputStream* output) {
    410   WriteTag(field_number, WIRETYPE_START_GROUP, output);
    411   value.SerializeWithCachedSizes(output);
    412   WriteTag(field_number, WIRETYPE_END_GROUP, output);
    413 }
    414 
    415 void WireFormatLite::WriteMessage(int field_number,
    416                                   const MessageLite& value,
    417                                   io::CodedOutputStream* output) {
    418   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    419   const int size = value.GetCachedSize();
    420   output->WriteVarint32(size);
    421   value.SerializeWithCachedSizes(output);
    422 }
    423 
    424 void WireFormatLite::WriteGroupMaybeToArray(int field_number,
    425                                             const MessageLite& value,
    426                                             io::CodedOutputStream* output) {
    427   WriteTag(field_number, WIRETYPE_START_GROUP, output);
    428   const int size = value.GetCachedSize();
    429   uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
    430   if (target != NULL) {
    431     uint8* end = value.SerializeWithCachedSizesToArray(target);
    432     GOOGLE_DCHECK_EQ(end - target, size);
    433   } else {
    434     value.SerializeWithCachedSizes(output);
    435   }
    436   WriteTag(field_number, WIRETYPE_END_GROUP, output);
    437 }
    438 
    439 void WireFormatLite::WriteMessageMaybeToArray(int field_number,
    440                                               const MessageLite& value,
    441                                               io::CodedOutputStream* output) {
    442   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
    443   const int size = value.GetCachedSize();
    444   output->WriteVarint32(size);
    445   uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
    446   if (target != NULL) {
    447     uint8* end = value.SerializeWithCachedSizesToArray(target);
    448     GOOGLE_DCHECK_EQ(end - target, size);
    449   } else {
    450     value.SerializeWithCachedSizes(output);
    451   }
    452 }
    453 
    454 bool WireFormatLite::ReadString(io::CodedInputStream* input,
    455                                 string* value) {
    456   // String is for UTF-8 text only
    457   uint32 length;
    458   if (!input->ReadVarint32(&length)) return false;
    459   if (!input->InternalReadStringInline(value, length)) return false;
    460   return true;
    461 }
    462 bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
    463                                string* value) {
    464   uint32 length;
    465   if (!input->ReadVarint32(&length)) return false;
    466   return input->InternalReadStringInline(value, length);
    467 }
    468 
    469 }  // namespace internal
    470 }  // namespace protobuf
    471 }  // namespace google
    472