LCOV - code coverage report
Current view: top level - toolkit/components/protobuf/src/google/protobuf - message_lite.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 11 139 7.9 %
Date: 2017-07-14 16:53:18 Functions: 2 29 6.9 %
Legend: Lines: hit not hit

          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             : // Authors: wink@google.com (Wink Saville),
      32             : //          kenton@google.com (Kenton Varda)
      33             : //  Based on original Protocol Buffers design by
      34             : //  Sanjay Ghemawat, Jeff Dean, and others.
      35             : 
      36             : #include <google/protobuf/message_lite.h>
      37             : #include <string>
      38             : #include <google/protobuf/stubs/common.h>
      39             : #include <google/protobuf/io/coded_stream.h>
      40             : #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
      41             : #include <google/protobuf/stubs/stl_util.h>
      42             : 
      43             : namespace google {
      44             : namespace protobuf {
      45             : 
      46         582 : MessageLite::~MessageLite() {}
      47             : 
      48           0 : string MessageLite::InitializationErrorString() const {
      49           0 :   return "(cannot determine missing fields for lite message)";
      50             : }
      51             : 
      52             : namespace {
      53             : 
      54             : // When serializing, we first compute the byte size, then serialize the message.
      55             : // If serialization produces a different number of bytes than expected, we
      56             : // call this function, which crashes.  The problem could be due to a bug in the
      57             : // protobuf implementation but is more likely caused by concurrent modification
      58             : // of the message.  This function attempts to distinguish between the two and
      59             : // provide a useful error message.
      60           0 : void ByteSizeConsistencyError(int byte_size_before_serialization,
      61             :                               int byte_size_after_serialization,
      62             :                               int bytes_produced_by_serialization) {
      63           0 :   GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization)
      64           0 :       << "Protocol message was modified concurrently during serialization.";
      65           0 :   GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization)
      66             :       << "Byte size calculation and serialization were inconsistent.  This "
      67             :          "may indicate a bug in protocol buffers or it may be caused by "
      68           0 :          "concurrent modification of the message.";
      69           0 :   GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal.";
      70           0 : }
      71             : 
      72           0 : string InitializationErrorMessage(const char* action,
      73             :                                   const MessageLite& message) {
      74             :   // Note:  We want to avoid depending on strutil in the lite library, otherwise
      75             :   //   we'd use:
      76             :   //
      77             :   // return strings::Substitute(
      78             :   //   "Can't $0 message of type \"$1\" because it is missing required "
      79             :   //   "fields: $2",
      80             :   //   action, message.GetTypeName(),
      81             :   //   message.InitializationErrorString());
      82             : 
      83           0 :   string result;
      84           0 :   result += "Can't ";
      85           0 :   result += action;
      86           0 :   result += " message of type \"";
      87           0 :   result += message.GetTypeName();
      88           0 :   result += "\" because it is missing required fields: ";
      89           0 :   result += message.InitializationErrorString();
      90           0 :   return result;
      91             : }
      92             : 
      93             : // Several of the Parse methods below just do one thing and then call another
      94             : // method.  In a naive implementation, we might have ParseFromString() call
      95             : // ParseFromArray() which would call ParseFromZeroCopyStream() which would call
      96             : // ParseFromCodedStream() which would call MergeFromCodedStream() which would
      97             : // call MergePartialFromCodedStream().  However, when parsing very small
      98             : // messages, every function call introduces significant overhead.  To avoid
      99             : // this without reproducing code, we use these forced-inline helpers.
     100             : //
     101             : // Note:  GCC only allows GOOGLE_ATTRIBUTE_ALWAYS_INLINE on declarations, not
     102             : //   definitions.
     103             : inline bool InlineMergeFromCodedStream(io::CodedInputStream* input,
     104             :                                        MessageLite* message)
     105             :                                        GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
     106             : inline bool InlineParseFromCodedStream(io::CodedInputStream* input,
     107             :                                        MessageLite* message)
     108             :                                        GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
     109             : inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
     110             :                                               MessageLite* message)
     111             :                                               GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
     112             : inline bool InlineParseFromArray(const void* data, int size,
     113             :                                  MessageLite* message)
     114             :                                  GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
     115             : inline bool InlineParsePartialFromArray(const void* data, int size,
     116             :                                         MessageLite* message)
     117             :                                         GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
     118             : 
     119             : bool InlineMergeFromCodedStream(io::CodedInputStream* input,
     120             :                                 MessageLite* message) {
     121           6 :   if (!message->MergePartialFromCodedStream(input)) return false;
     122           6 :   if (!message->IsInitialized()) {
     123           0 :     GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);
     124           0 :     return false;
     125             :   }
     126           6 :   return true;
     127             : }
     128             : 
     129             : bool InlineParseFromCodedStream(io::CodedInputStream* input,
     130             :                                 MessageLite* message) {
     131           6 :   message->Clear();
     132           6 :   return InlineMergeFromCodedStream(input, message);
     133             : }
     134             : 
     135             : bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
     136             :                                        MessageLite* message) {
     137           0 :   message->Clear();
     138           0 :   return message->MergePartialFromCodedStream(input);
     139             : }
     140             : 
     141             : bool InlineParseFromArray(const void* data, int size, MessageLite* message) {
     142          12 :   io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
     143          12 :   return InlineParseFromCodedStream(&input, message) &&
     144          12 :          input.ConsumedEntireMessage();
     145             : }
     146             : 
     147             : bool InlineParsePartialFromArray(const void* data, int size,
     148             :                                  MessageLite* message) {
     149           0 :   io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
     150           0 :   return InlineParsePartialFromCodedStream(&input, message) &&
     151           0 :          input.ConsumedEntireMessage();
     152             : }
     153             : 
     154             : }  // namespace
     155             : 
     156           0 : bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) {
     157           0 :   return InlineMergeFromCodedStream(input, this);
     158             : }
     159             : 
     160           0 : bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) {
     161           0 :   return InlineParseFromCodedStream(input, this);
     162             : }
     163             : 
     164           0 : bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) {
     165           0 :   return InlineParsePartialFromCodedStream(input, this);
     166             : }
     167             : 
     168           0 : bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
     169           0 :   io::CodedInputStream decoder(input);
     170           0 :   return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage();
     171             : }
     172             : 
     173           0 : bool MessageLite::ParsePartialFromZeroCopyStream(
     174             :     io::ZeroCopyInputStream* input) {
     175           0 :   io::CodedInputStream decoder(input);
     176           0 :   return ParsePartialFromCodedStream(&decoder) &&
     177           0 :          decoder.ConsumedEntireMessage();
     178             : }
     179             : 
     180           0 : bool MessageLite::ParseFromBoundedZeroCopyStream(
     181             :     io::ZeroCopyInputStream* input, int size) {
     182           0 :   io::CodedInputStream decoder(input);
     183           0 :   decoder.PushLimit(size);
     184           0 :   return ParseFromCodedStream(&decoder) &&
     185           0 :          decoder.ConsumedEntireMessage() &&
     186           0 :          decoder.BytesUntilLimit() == 0;
     187             : }
     188             : 
     189           0 : bool MessageLite::ParsePartialFromBoundedZeroCopyStream(
     190             :     io::ZeroCopyInputStream* input, int size) {
     191           0 :   io::CodedInputStream decoder(input);
     192           0 :   decoder.PushLimit(size);
     193           0 :   return ParsePartialFromCodedStream(&decoder) &&
     194           0 :          decoder.ConsumedEntireMessage() &&
     195           0 :          decoder.BytesUntilLimit() == 0;
     196             : }
     197             : 
     198           0 : bool MessageLite::ParseFromString(const string& data) {
     199           0 :   return InlineParseFromArray(data.data(), data.size(), this);
     200             : }
     201             : 
     202           0 : bool MessageLite::ParsePartialFromString(const string& data) {
     203           0 :   return InlineParsePartialFromArray(data.data(), data.size(), this);
     204             : }
     205             : 
     206           6 : bool MessageLite::ParseFromArray(const void* data, int size) {
     207           6 :   return InlineParseFromArray(data, size, this);
     208             : }
     209             : 
     210           0 : bool MessageLite::ParsePartialFromArray(const void* data, int size) {
     211           0 :   return InlineParsePartialFromArray(data, size, this);
     212             : }
     213             : 
     214             : 
     215             : // ===================================================================
     216             : 
     217           0 : uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const {
     218             :   // We only optimize this when using optimize_for = SPEED.  In other cases
     219             :   // we just use the CodedOutputStream path.
     220           0 :   int size = GetCachedSize();
     221           0 :   io::ArrayOutputStream out(target, size);
     222           0 :   io::CodedOutputStream coded_out(&out);
     223           0 :   SerializeWithCachedSizes(&coded_out);
     224           0 :   GOOGLE_CHECK(!coded_out.HadError());
     225           0 :   return target + size;
     226             : }
     227             : 
     228           0 : bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const {
     229           0 :   GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
     230           0 :   return SerializePartialToCodedStream(output);
     231             : }
     232             : 
     233           0 : bool MessageLite::SerializePartialToCodedStream(
     234             :     io::CodedOutputStream* output) const {
     235           0 :   const int size = ByteSize();  // Force size to be cached.
     236           0 :   uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size);
     237           0 :   if (buffer != NULL) {
     238           0 :     uint8* end = SerializeWithCachedSizesToArray(buffer);
     239           0 :     if (end - buffer != size) {
     240           0 :       ByteSizeConsistencyError(size, ByteSize(), end - buffer);
     241             :     }
     242           0 :     return true;
     243             :   } else {
     244           0 :     int original_byte_count = output->ByteCount();
     245           0 :     SerializeWithCachedSizes(output);
     246           0 :     if (output->HadError()) {
     247           0 :       return false;
     248             :     }
     249           0 :     int final_byte_count = output->ByteCount();
     250             : 
     251           0 :     if (final_byte_count - original_byte_count != size) {
     252           0 :       ByteSizeConsistencyError(size, ByteSize(),
     253           0 :                                final_byte_count - original_byte_count);
     254             :     }
     255             : 
     256           0 :     return true;
     257             :   }
     258             : }
     259             : 
     260           0 : bool MessageLite::SerializeToZeroCopyStream(
     261             :     io::ZeroCopyOutputStream* output) const {
     262           0 :   io::CodedOutputStream encoder(output);
     263           0 :   return SerializeToCodedStream(&encoder);
     264             : }
     265             : 
     266           0 : bool MessageLite::SerializePartialToZeroCopyStream(
     267             :     io::ZeroCopyOutputStream* output) const {
     268           0 :   io::CodedOutputStream encoder(output);
     269           0 :   return SerializePartialToCodedStream(&encoder);
     270             : }
     271             : 
     272           0 : bool MessageLite::AppendToString(string* output) const {
     273           0 :   GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
     274           0 :   return AppendPartialToString(output);
     275             : }
     276             : 
     277           0 : bool MessageLite::AppendPartialToString(string* output) const {
     278           0 :   int old_size = output->size();
     279           0 :   int byte_size = ByteSize();
     280           0 :   STLStringResizeUninitialized(output, old_size + byte_size);
     281             :   uint8* start =
     282           0 :       reinterpret_cast<uint8*>(io::mutable_string_data(output) + old_size);
     283           0 :   uint8* end = SerializeWithCachedSizesToArray(start);
     284           0 :   if (end - start != byte_size) {
     285           0 :     ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
     286             :   }
     287           0 :   return true;
     288             : }
     289             : 
     290           0 : bool MessageLite::SerializeToString(string* output) const {
     291           0 :   output->clear();
     292           0 :   return AppendToString(output);
     293             : }
     294             : 
     295           0 : bool MessageLite::SerializePartialToString(string* output) const {
     296           0 :   output->clear();
     297           0 :   return AppendPartialToString(output);
     298             : }
     299             : 
     300           0 : bool MessageLite::SerializeToArray(void* data, int size) const {
     301           0 :   GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
     302           0 :   return SerializePartialToArray(data, size);
     303             : }
     304             : 
     305           0 : bool MessageLite::SerializePartialToArray(void* data, int size) const {
     306           0 :   int byte_size = ByteSize();
     307           0 :   if (size < byte_size) return false;
     308           0 :   uint8* start = reinterpret_cast<uint8*>(data);
     309           0 :   uint8* end = SerializeWithCachedSizesToArray(start);
     310           0 :   if (end - start != byte_size) {
     311           0 :     ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
     312             :   }
     313           0 :   return true;
     314             : }
     315             : 
     316           0 : string MessageLite::SerializeAsString() const {
     317             :   // If the compiler implements the (Named) Return Value Optimization,
     318             :   // the local variable 'result' will not actually reside on the stack
     319             :   // of this function, but will be overlaid with the object that the
     320             :   // caller supplied for the return value to be constructed in.
     321           0 :   string output;
     322           0 :   if (!AppendToString(&output))
     323           0 :     output.clear();
     324           0 :   return output;
     325             : }
     326             : 
     327           0 : string MessageLite::SerializePartialAsString() const {
     328           0 :   string output;
     329           0 :   if (!AppendPartialToString(&output))
     330           0 :     output.clear();
     331           0 :   return output;
     332             : }
     333             : 
     334             : }  // namespace protobuf
     335             : }  // namespace google

Generated by: LCOV version 1.13