LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - wire_format_lite.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 34 183 18.6 %
Date: 2015-10-10 Functions: 8 37 21.6 %

          Line data    Source code
       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@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/logging.h>
      41             : #include <google/protobuf/stubs/common.h>
      42             : #include <google/protobuf/stubs/stringprintf.h>
      43             : #include <google/protobuf/io/coded_stream_inl.h>
      44             : #include <google/protobuf/io/zero_copy_stream.h>
      45             : #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
      46             : 
      47             : 
      48             : namespace google {
      49             : namespace protobuf {
      50             : namespace internal {
      51             : 
      52             : #ifndef _MSC_VER    // MSVC doesn't like definitions of inline constants, GCC
      53             :                     // requires them.
      54             : const int WireFormatLite::kMessageSetItemStartTag;
      55             : const int WireFormatLite::kMessageSetItemEndTag;
      56             : const int WireFormatLite::kMessageSetTypeIdTag;
      57             : const int WireFormatLite::kMessageSetMessageTag;
      58             : 
      59             : #endif
      60             : 
      61             : // IBM xlC requires prefixing constants with WireFormatLite::
      62             : const int WireFormatLite::kMessageSetItemTagsSize =
      63             :   io::CodedOutputStream::StaticVarintSize32<
      64             :       WireFormatLite::kMessageSetItemStartTag>::value +
      65             :   io::CodedOutputStream::StaticVarintSize32<
      66             :       WireFormatLite::kMessageSetItemEndTag>::value +
      67             :   io::CodedOutputStream::StaticVarintSize32<
      68             :       WireFormatLite::kMessageSetTypeIdTag>::value +
      69             :   io::CodedOutputStream::StaticVarintSize32<
      70             :       WireFormatLite::kMessageSetMessageTag>::value;
      71             : 
      72             : const WireFormatLite::CppType
      73             : WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
      74             :   static_cast<CppType>(0),  // 0 is reserved for errors
      75             : 
      76             :   CPPTYPE_DOUBLE,   // TYPE_DOUBLE
      77             :   CPPTYPE_FLOAT,    // TYPE_FLOAT
      78             :   CPPTYPE_INT64,    // TYPE_INT64
      79             :   CPPTYPE_UINT64,   // TYPE_UINT64
      80             :   CPPTYPE_INT32,    // TYPE_INT32
      81             :   CPPTYPE_UINT64,   // TYPE_FIXED64
      82             :   CPPTYPE_UINT32,   // TYPE_FIXED32
      83             :   CPPTYPE_BOOL,     // TYPE_BOOL
      84             :   CPPTYPE_STRING,   // TYPE_STRING
      85             :   CPPTYPE_MESSAGE,  // TYPE_GROUP
      86             :   CPPTYPE_MESSAGE,  // TYPE_MESSAGE
      87             :   CPPTYPE_STRING,   // TYPE_BYTES
      88             :   CPPTYPE_UINT32,   // TYPE_UINT32
      89             :   CPPTYPE_ENUM,     // TYPE_ENUM
      90             :   CPPTYPE_INT32,    // TYPE_SFIXED32
      91             :   CPPTYPE_INT64,    // TYPE_SFIXED64
      92             :   CPPTYPE_INT32,    // TYPE_SINT32
      93             :   CPPTYPE_INT64,    // TYPE_SINT64
      94             : };
      95             : 
      96             : const WireFormatLite::WireType
      97             : WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
      98             :   static_cast<WireFormatLite::WireType>(-1),  // invalid
      99             :   WireFormatLite::WIRETYPE_FIXED64,           // TYPE_DOUBLE
     100             :   WireFormatLite::WIRETYPE_FIXED32,           // TYPE_FLOAT
     101             :   WireFormatLite::WIRETYPE_VARINT,            // TYPE_INT64
     102             :   WireFormatLite::WIRETYPE_VARINT,            // TYPE_UINT64
     103             :   WireFormatLite::WIRETYPE_VARINT,            // TYPE_INT32
     104             :   WireFormatLite::WIRETYPE_FIXED64,           // TYPE_FIXED64
     105             :   WireFormatLite::WIRETYPE_FIXED32,           // TYPE_FIXED32
     106             :   WireFormatLite::WIRETYPE_VARINT,            // TYPE_BOOL
     107             :   WireFormatLite::WIRETYPE_LENGTH_DELIMITED,  // TYPE_STRING
     108             :   WireFormatLite::WIRETYPE_START_GROUP,       // TYPE_GROUP
     109             :   WireFormatLite::WIRETYPE_LENGTH_DELIMITED,  // TYPE_MESSAGE
     110             :   WireFormatLite::WIRETYPE_LENGTH_DELIMITED,  // TYPE_BYTES
     111             :   WireFormatLite::WIRETYPE_VARINT,            // TYPE_UINT32
     112             :   WireFormatLite::WIRETYPE_VARINT,            // TYPE_ENUM
     113             :   WireFormatLite::WIRETYPE_FIXED32,           // TYPE_SFIXED32
     114             :   WireFormatLite::WIRETYPE_FIXED64,           // TYPE_SFIXED64
     115             :   WireFormatLite::WIRETYPE_VARINT,            // TYPE_SINT32
     116             :   WireFormatLite::WIRETYPE_VARINT,            // TYPE_SINT64
     117             : };
     118             : 
     119           0 : bool WireFormatLite::SkipField(
     120           0 :     io::CodedInputStream* input, uint32 tag) {
     121           0 :   switch (WireFormatLite::GetTagWireType(tag)) {
     122             :     case WireFormatLite::WIRETYPE_VARINT: {
     123             :       uint64 value;
     124           0 :       if (!input->ReadVarint64(&value)) return false;
     125           0 :       return true;
     126             :     }
     127             :     case WireFormatLite::WIRETYPE_FIXED64: {
     128             :       uint64 value;
     129           0 :       if (!input->ReadLittleEndian64(&value)) return false;
     130           0 :       return true;
     131             :     }
     132             :     case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
     133             :       uint32 length;
     134           0 :       if (!input->ReadVarint32(&length)) return false;
     135           0 :       if (!input->Skip(length)) return false;
     136           0 :       return true;
     137             :     }
     138             :     case WireFormatLite::WIRETYPE_START_GROUP: {
     139           0 :       if (!input->IncrementRecursionDepth()) return false;
     140           0 :       if (!SkipMessage(input)) return false;
     141           0 :       input->DecrementRecursionDepth();
     142             :       // Check that the ending tag matched the starting tag.
     143           0 :       if (!input->LastTagWas(WireFormatLite::MakeTag(
     144             :           WireFormatLite::GetTagFieldNumber(tag),
     145           0 :           WireFormatLite::WIRETYPE_END_GROUP))) {
     146             :         return false;
     147             :       }
     148           0 :       return true;
     149             :     }
     150             :     case WireFormatLite::WIRETYPE_END_GROUP: {
     151             :       return false;
     152             :     }
     153             :     case WireFormatLite::WIRETYPE_FIXED32: {
     154             :       uint32 value;
     155           0 :       if (!input->ReadLittleEndian32(&value)) return false;
     156           0 :       return true;
     157             :     }
     158             :     default: {
     159             :       return false;
     160             :     }
     161             :   }
     162             : }
     163             : 
     164           0 : bool WireFormatLite::SkipField(
     165           0 :     io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) {
     166           0 :   switch (WireFormatLite::GetTagWireType(tag)) {
     167             :     case WireFormatLite::WIRETYPE_VARINT: {
     168             :       uint64 value;
     169           0 :       if (!input->ReadVarint64(&value)) return false;
     170           0 :       output->WriteVarint32(tag);
     171           0 :       output->WriteVarint64(value);
     172             :       return true;
     173             :     }
     174             :     case WireFormatLite::WIRETYPE_FIXED64: {
     175             :       uint64 value;
     176           0 :       if (!input->ReadLittleEndian64(&value)) return false;
     177           0 :       output->WriteVarint32(tag);
     178           0 :       output->WriteLittleEndian64(value);
     179             :       return true;
     180             :     }
     181             :     case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
     182             :       uint32 length;
     183           0 :       if (!input->ReadVarint32(&length)) return false;
     184           0 :       output->WriteVarint32(tag);
     185           0 :       output->WriteVarint32(length);
     186             :       // TODO(mkilavuz): Provide API to prevent extra string copying.
     187             :       string temp;
     188           0 :       if (!input->ReadString(&temp, length)) return false;
     189             :       output->WriteString(temp);
     190             :       return true;
     191             :     }
     192             :     case WireFormatLite::WIRETYPE_START_GROUP: {
     193           0 :       output->WriteVarint32(tag);
     194           0 :       if (!input->IncrementRecursionDepth()) return false;
     195           0 :       if (!SkipMessage(input, output)) return false;
     196           0 :       input->DecrementRecursionDepth();
     197             :       // Check that the ending tag matched the starting tag.
     198           0 :       if (!input->LastTagWas(WireFormatLite::MakeTag(
     199             :           WireFormatLite::GetTagFieldNumber(tag),
     200           0 :           WireFormatLite::WIRETYPE_END_GROUP))) {
     201             :         return false;
     202             :       }
     203           0 :       return true;
     204             :     }
     205             :     case WireFormatLite::WIRETYPE_END_GROUP: {
     206             :       return false;
     207             :     }
     208             :     case WireFormatLite::WIRETYPE_FIXED32: {
     209             :       uint32 value;
     210           0 :       if (!input->ReadLittleEndian32(&value)) return false;
     211           0 :       output->WriteVarint32(tag);
     212           0 :       output->WriteLittleEndian32(value);
     213             :       return true;
     214             :     }
     215             :     default: {
     216             :       return false;
     217             :     }
     218             :   }
     219             : }
     220             : 
     221           0 : bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
     222             :   while (true) {
     223           0 :     uint32 tag = input->ReadTag();
     224           0 :     if (tag == 0) {
     225             :       // End of input.  This is a valid place to end, so return true.
     226             :       return true;
     227             :     }
     228             : 
     229           0 :     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
     230             : 
     231           0 :     if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
     232             :       // Must be the end of the message.
     233             :       return true;
     234             :     }
     235             : 
     236           0 :     if (!SkipField(input, tag)) return false;
     237             :   }
     238             : }
     239             : 
     240           0 : bool WireFormatLite::SkipMessage(io::CodedInputStream* input,
     241             :     io::CodedOutputStream* output) {
     242             :   while (true) {
     243           0 :     uint32 tag = input->ReadTag();
     244           0 :     if (tag == 0) {
     245             :       // End of input.  This is a valid place to end, so return true.
     246             :       return true;
     247             :     }
     248             : 
     249           0 :     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
     250             : 
     251           0 :     if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
     252           0 :       output->WriteVarint32(tag);
     253             :       // Must be the end of the message.
     254           0 :       return true;
     255             :     }
     256             : 
     257           0 :     if (!SkipField(input, tag, output)) return false;
     258             :   }
     259             : }
     260             : 
     261           0 : bool FieldSkipper::SkipField(
     262             :     io::CodedInputStream* input, uint32 tag) {
     263           0 :   return WireFormatLite::SkipField(input, tag);
     264             : }
     265             : 
     266           0 : bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
     267           0 :   return WireFormatLite::SkipMessage(input);
     268             : }
     269             : 
     270           0 : void FieldSkipper::SkipUnknownEnum(
     271             :     int /* field_number */, int /* value */) {
     272             :   // Nothing.
     273           0 : }
     274             : 
     275           0 : bool CodedOutputStreamFieldSkipper::SkipField(
     276             :     io::CodedInputStream* input, uint32 tag) {
     277           0 :   return WireFormatLite::SkipField(input, tag, unknown_fields_);
     278             : }
     279             : 
     280           0 : bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) {
     281           0 :   return WireFormatLite::SkipMessage(input, unknown_fields_);
     282             : }
     283             : 
     284           0 : void CodedOutputStreamFieldSkipper::SkipUnknownEnum(
     285             :     int field_number, int value) {
     286           0 :   unknown_fields_->WriteVarint32(field_number);
     287           0 :   unknown_fields_->WriteVarint64(value);
     288           0 : }
     289             : 
     290           0 : bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
     291             :                                             bool (*is_valid)(int),
     292             :                                             RepeatedField<int>* values) {
     293             :   uint32 length;
     294           0 :   if (!input->ReadVarint32(&length)) return false;
     295           0 :   io::CodedInputStream::Limit limit = input->PushLimit(length);
     296           0 :   while (input->BytesUntilLimit() > 0) {
     297             :     int value;
     298           0 :     if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
     299             :         int, WireFormatLite::TYPE_ENUM>(input, &value)) {
     300           0 :       return false;
     301             :     }
     302           0 :     if (is_valid == NULL || is_valid(value)) {
     303           0 :       values->Add(value);
     304             :     }
     305             :   }
     306           0 :   input->PopLimit(limit);
     307             :   return true;
     308             : }
     309             : 
     310           0 : bool WireFormatLite::ReadPackedEnumPreserveUnknowns(
     311             :     io::CodedInputStream* input,
     312             :     int field_number,
     313             :     bool (*is_valid)(int),
     314             :     io::CodedOutputStream* unknown_fields_stream,
     315             :     RepeatedField<int>* values) {
     316             :   uint32 length;
     317           0 :   if (!input->ReadVarint32(&length)) return false;
     318           0 :   io::CodedInputStream::Limit limit = input->PushLimit(length);
     319           0 :   while (input->BytesUntilLimit() > 0) {
     320             :     int value;
     321           0 :     if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
     322             :         int, WireFormatLite::TYPE_ENUM>(input, &value)) {
     323           0 :       return false;
     324             :     }
     325           0 :     if (is_valid == NULL || is_valid(value)) {
     326           0 :       values->Add(value);
     327             :     } else {
     328             :       uint32 tag = WireFormatLite::MakeTag(field_number,
     329           0 :                                            WireFormatLite::WIRETYPE_VARINT);
     330           0 :       unknown_fields_stream->WriteVarint32(tag);
     331           0 :       unknown_fields_stream->WriteVarint32(value);
     332             :     }
     333             :   }
     334           0 :   input->PopLimit(limit);
     335             :   return true;
     336             : }
     337             : 
     338           8 : void WireFormatLite::WriteInt32(int field_number, int32 value,
     339             :                                 io::CodedOutputStream* output) {
     340             :   WriteTag(field_number, WIRETYPE_VARINT, output);
     341             :   WriteInt32NoTag(value, output);
     342           8 : }
     343           0 : void WireFormatLite::WriteInt64(int field_number, int64 value,
     344             :                                 io::CodedOutputStream* output) {
     345             :   WriteTag(field_number, WIRETYPE_VARINT, output);
     346             :   WriteInt64NoTag(value, output);
     347           0 : }
     348           0 : void WireFormatLite::WriteUInt32(int field_number, uint32 value,
     349             :                                  io::CodedOutputStream* output) {
     350             :   WriteTag(field_number, WIRETYPE_VARINT, output);
     351             :   WriteUInt32NoTag(value, output);
     352           0 : }
     353           0 : void WireFormatLite::WriteUInt64(int field_number, uint64 value,
     354             :                                  io::CodedOutputStream* output) {
     355             :   WriteTag(field_number, WIRETYPE_VARINT, output);
     356             :   WriteUInt64NoTag(value, output);
     357           0 : }
     358           0 : void WireFormatLite::WriteSInt32(int field_number, int32 value,
     359             :                                  io::CodedOutputStream* output) {
     360             :   WriteTag(field_number, WIRETYPE_VARINT, output);
     361             :   WriteSInt32NoTag(value, output);
     362           0 : }
     363           0 : void WireFormatLite::WriteSInt64(int field_number, int64 value,
     364             :                                  io::CodedOutputStream* output) {
     365             :   WriteTag(field_number, WIRETYPE_VARINT, output);
     366             :   WriteSInt64NoTag(value, output);
     367           0 : }
     368           0 : void WireFormatLite::WriteFixed32(int field_number, uint32 value,
     369             :                                   io::CodedOutputStream* output) {
     370             :   WriteTag(field_number, WIRETYPE_FIXED32, output);
     371             :   WriteFixed32NoTag(value, output);
     372           0 : }
     373           0 : void WireFormatLite::WriteFixed64(int field_number, uint64 value,
     374             :                                   io::CodedOutputStream* output) {
     375             :   WriteTag(field_number, WIRETYPE_FIXED64, output);
     376             :   WriteFixed64NoTag(value, output);
     377           0 : }
     378           0 : void WireFormatLite::WriteSFixed32(int field_number, int32 value,
     379             :                                    io::CodedOutputStream* output) {
     380             :   WriteTag(field_number, WIRETYPE_FIXED32, output);
     381             :   WriteSFixed32NoTag(value, output);
     382           0 : }
     383           0 : void WireFormatLite::WriteSFixed64(int field_number, int64 value,
     384             :                                    io::CodedOutputStream* output) {
     385             :   WriteTag(field_number, WIRETYPE_FIXED64, output);
     386             :   WriteSFixed64NoTag(value, output);
     387           0 : }
     388           0 : void WireFormatLite::WriteFloat(int field_number, float value,
     389             :                                 io::CodedOutputStream* output) {
     390             :   WriteTag(field_number, WIRETYPE_FIXED32, output);
     391             :   WriteFloatNoTag(value, output);
     392           0 : }
     393           0 : void WireFormatLite::WriteDouble(int field_number, double value,
     394             :                                  io::CodedOutputStream* output) {
     395             :   WriteTag(field_number, WIRETYPE_FIXED64, output);
     396             :   WriteDoubleNoTag(value, output);
     397           0 : }
     398           0 : void WireFormatLite::WriteBool(int field_number, bool value,
     399             :                                io::CodedOutputStream* output) {
     400             :   WriteTag(field_number, WIRETYPE_VARINT, output);
     401             :   WriteBoolNoTag(value, output);
     402           0 : }
     403           0 : void WireFormatLite::WriteEnum(int field_number, int value,
     404             :                                io::CodedOutputStream* output) {
     405             :   WriteTag(field_number, WIRETYPE_VARINT, output);
     406             :   WriteEnumNoTag(value, output);
     407           0 : }
     408             : 
     409          10 : void WireFormatLite::WriteString(int field_number, const string& value,
     410             :                                  io::CodedOutputStream* output) {
     411             :   // String is for UTF-8 text only
     412             :   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
     413          10 :   GOOGLE_CHECK(value.size() <= kint32max);
     414          10 :   output->WriteVarint32(value.size());
     415             :   output->WriteString(value);
     416          10 : }
     417          20 : void WireFormatLite::WriteStringMaybeAliased(
     418             :     int field_number, const string& value,
     419             :     io::CodedOutputStream* output) {
     420             :   // String is for UTF-8 text only
     421             :   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
     422          20 :   GOOGLE_CHECK(value.size() <= kint32max);
     423          20 :   output->WriteVarint32(value.size());
     424          20 :   output->WriteRawMaybeAliased(value.data(), value.size());
     425          20 : }
     426           0 : void WireFormatLite::WriteBytes(int field_number, const string& value,
     427             :                                 io::CodedOutputStream* output) {
     428             :   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
     429           0 :   GOOGLE_CHECK(value.size() <= kint32max);
     430           0 :   output->WriteVarint32(value.size());
     431             :   output->WriteString(value);
     432           0 : }
     433           8 : void WireFormatLite::WriteBytesMaybeAliased(
     434             :     int field_number, const string& value,
     435             :     io::CodedOutputStream* output) {
     436             :   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
     437           8 :   GOOGLE_CHECK(value.size() <= kint32max);
     438           8 :   output->WriteVarint32(value.size());
     439           8 :   output->WriteRawMaybeAliased(value.data(), value.size());
     440           8 : }
     441             : 
     442             : 
     443           0 : void WireFormatLite::WriteGroup(int field_number,
     444             :                                 const MessageLite& value,
     445             :                                 io::CodedOutputStream* output) {
     446             :   WriteTag(field_number, WIRETYPE_START_GROUP, output);
     447           0 :   value.SerializeWithCachedSizes(output);
     448             :   WriteTag(field_number, WIRETYPE_END_GROUP, output);
     449           0 : }
     450             : 
     451           4 : void WireFormatLite::WriteMessage(int field_number,
     452             :                                   const MessageLite& value,
     453             :                                   io::CodedOutputStream* output) {
     454             :   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
     455           4 :   const int size = value.GetCachedSize();
     456           4 :   output->WriteVarint32(size);
     457           4 :   value.SerializeWithCachedSizes(output);
     458           4 : }
     459             : 
     460           0 : void WireFormatLite::WriteGroupMaybeToArray(int field_number,
     461             :                                             const MessageLite& value,
     462             :                                             io::CodedOutputStream* output) {
     463             :   WriteTag(field_number, WIRETYPE_START_GROUP, output);
     464           0 :   const int size = value.GetCachedSize();
     465           0 :   uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
     466           0 :   if (target != NULL) {
     467           0 :     uint8* end = value.SerializeWithCachedSizesToArray(target);
     468             :     GOOGLE_DCHECK_EQ(end - target, size);
     469             :   } else {
     470           0 :     value.SerializeWithCachedSizes(output);
     471             :   }
     472             :   WriteTag(field_number, WIRETYPE_END_GROUP, output);
     473           0 : }
     474             : 
     475          14 : void WireFormatLite::WriteMessageMaybeToArray(int field_number,
     476             :                                               const MessageLite& value,
     477             :                                               io::CodedOutputStream* output) {
     478             :   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
     479          14 :   const int size = value.GetCachedSize();
     480          14 :   output->WriteVarint32(size);
     481          14 :   uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
     482          14 :   if (target != NULL) {
     483           0 :     uint8* end = value.SerializeWithCachedSizesToArray(target);
     484             :     GOOGLE_DCHECK_EQ(end - target, size);
     485             :   } else {
     486          14 :     value.SerializeWithCachedSizes(output);
     487             :   }
     488          14 : }
     489             : 
     490             : GOOGLE_ATTRIBUTE_ALWAYS_INLINE static bool ReadBytesToString(
     491             :     io::CodedInputStream* input, string* value);
     492             : inline static bool ReadBytesToString(io::CodedInputStream* input,
     493             :                                      string* value) {
     494             :   uint32 length;
     495     3065680 :   return input->ReadVarint32(&length) &&
     496     1532906 :       input->InternalReadStringInline(value, length);
     497             : }
     498             : 
     499     1532899 : bool WireFormatLite::ReadBytes(io::CodedInputStream* input, string* value) {
     500     1532779 :   return ReadBytesToString(input, value);
     501             : }
     502             : 
     503           0 : bool WireFormatLite::ReadBytes(io::CodedInputStream* input, string** p) {
     504           0 :   if (*p == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
     505           0 :     *p = new ::std::string();
     506             :   }
     507           0 :   return ReadBytesToString(input, *p);
     508             : }
     509             : 
     510      479229 : bool WireFormatLite::VerifyUtf8String(const char* data,
     511             :                                       int size,
     512             :                                       Operation op,
     513             :                                       const char* field_name) {
     514      479229 :   if (!IsStructurallyValidUTF8(data, size)) {
     515           0 :     const char* operation_str = NULL;
     516           0 :     switch (op) {
     517             :       case PARSE:
     518           0 :         operation_str = "parsing";
     519           0 :         break;
     520             :       case SERIALIZE:
     521           0 :         operation_str = "serializing";
     522           0 :         break;
     523             :       // no default case: have the compiler warn if a case is not covered.
     524             :     }
     525           0 :     string quoted_field_name = "";
     526           0 :     if (field_name != NULL) {
     527           0 :       quoted_field_name = StringPrintf(" '%s'", field_name);
     528             :     }
     529             :     // no space below to avoid double space when the field name is missing.
     530           0 :     GOOGLE_LOG(ERROR) << "String field" << quoted_field_name << " contains invalid "
     531           0 :                << "UTF-8 data when " << operation_str << " a protocol "
     532           0 :                << "buffer. Use the 'bytes' type if you intend to send raw "
     533           0 :                << "bytes. ";
     534           0 :     return false;
     535             :   }
     536             :   return true;
     537             : }
     538             : 
     539             : }  // namespace internal
     540             : }  // namespace protobuf
     541             : }  // namespace google

Generated by: LCOV version 1.10