LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - unknown_field_set.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 114 174 65.5 %
Date: 2015-10-10 Functions: 20 29 69.0 %

          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/unknown_field_set.h>
      36             : 
      37             : #include <google/protobuf/stubs/logging.h>
      38             : #include <google/protobuf/stubs/common.h>
      39             : #include <google/protobuf/io/coded_stream.h>
      40             : #include <google/protobuf/io/zero_copy_stream.h>
      41             : #include <google/protobuf/io/zero_copy_stream_impl.h>
      42             : #include <google/protobuf/wire_format.h>
      43             : #include <google/protobuf/stubs/stl_util.h>
      44             : 
      45             : namespace google {
      46             : namespace protobuf {
      47             : 
      48             : namespace {
      49             : // This global instance is returned by unknown_fields() on any message class
      50             : // when the object has no unknown fields. This is necessary because we now
      51             : // instantiate the UnknownFieldSet dynamically only when required.
      52             : UnknownFieldSet* default_unknown_field_set_instance_ = NULL;
      53             : 
      54           0 : void DeleteDefaultUnknownFieldSet() {
      55           0 :   delete default_unknown_field_set_instance_;
      56           0 : }
      57             : 
      58           1 : void InitDefaultUnknownFieldSet() {
      59           1 :   default_unknown_field_set_instance_ = new UnknownFieldSet();
      60           1 :   internal::OnShutdown(&DeleteDefaultUnknownFieldSet);
      61           1 : }
      62             : 
      63             : GOOGLE_PROTOBUF_DECLARE_ONCE(default_unknown_field_set_once_init_);
      64             : }
      65             : 
      66         274 : const UnknownFieldSet* UnknownFieldSet::default_instance() {
      67             :   ::google::protobuf::GoogleOnceInit(&default_unknown_field_set_once_init_,
      68         274 :                  &InitDefaultUnknownFieldSet);
      69         274 :   return default_unknown_field_set_instance_;
      70             : }
      71             : 
      72        1037 : UnknownFieldSet::UnknownFieldSet()
      73        1037 :     : fields_(NULL) {}
      74             : 
      75        1036 : UnknownFieldSet::~UnknownFieldSet() {
      76             :   Clear();
      77        1036 :   delete fields_;
      78        1036 : }
      79             : 
      80         809 : void UnknownFieldSet::ClearFallback() {
      81        4495 :   if (fields_ != NULL) {
      82        6563 :     for (int i = 0; i < fields_->size(); i++) {
      83        2068 :       (*fields_)[i].Delete();
      84             :     }
      85        1618 :     delete fields_;
      86         809 :     fields_ = NULL;
      87             :   }
      88         809 : }
      89             : 
      90           0 : void UnknownFieldSet::ClearAndFreeMemory() {
      91           0 :   if (fields_ != NULL) {
      92             :     Clear();
      93             :   }
      94           0 : }
      95             : 
      96           2 : void UnknownFieldSet::InternalMergeFrom(const UnknownFieldSet& other) {
      97           2 :   int other_field_count = other.field_count();
      98           2 :   if (other_field_count > 0) {
      99           4 :     fields_ = new vector<UnknownField>();
     100           4 :     for (int i = 0; i < other_field_count; i++) {
     101           6 :       fields_->push_back((*other.fields_)[i]);
     102           8 :       fields_->back().DeepCopy((*other.fields_)[i]);
     103             :     }
     104             :   }
     105           2 : }
     106             : 
     107         617 : void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) {
     108         617 :   int other_field_count = other.field_count();
     109         617 :   if (other_field_count > 0) {
     110         731 :     if (fields_ == NULL) fields_ = new vector<UnknownField>();
     111         478 :     for (int i = 0; i < other_field_count; i++) {
     112        1434 :       fields_->push_back((*other.fields_)[i]);
     113        1912 :       fields_->back().DeepCopy((*other.fields_)[i]);
     114             :     }
     115             :   }
     116         617 : }
     117             : 
     118             : // A specialized MergeFrom for performance when we are merging from an UFS that
     119             : // is temporary and can be destroyed in the process.
     120          46 : void UnknownFieldSet::MergeFromAndDestroy(UnknownFieldSet* other) {
     121          46 :   int other_field_count = other->field_count();
     122          46 :   if (other_field_count > 0) {
     123          92 :     if (fields_ == NULL) fields_ = new vector<UnknownField>();
     124          46 :     for (int i = 0; i < other_field_count; i++) {
     125         138 :       fields_->push_back((*other->fields_)[i]);
     126         138 :       (*other->fields_)[i].Reset();
     127             :     }
     128             :   }
     129          92 :   delete other->fields_;
     130          46 :   other->fields_ = NULL;
     131          46 : }
     132             : 
     133           0 : int UnknownFieldSet::SpaceUsedExcludingSelf() const {
     134           0 :   if (fields_ == NULL) return 0;
     135             : 
     136           0 :   int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size();
     137             : 
     138           0 :   for (int i = 0; i < fields_->size(); i++) {
     139           0 :     const UnknownField& field = (*fields_)[i];
     140           0 :     switch (field.type()) {
     141             :       case UnknownField::TYPE_LENGTH_DELIMITED:
     142           0 :         total_size += sizeof(*field.length_delimited_.string_value_) +
     143             :                       internal::StringSpaceUsedExcludingSelf(
     144           0 :                           *field.length_delimited_.string_value_);
     145           0 :         break;
     146             :       case UnknownField::TYPE_GROUP:
     147           0 :         total_size += field.group_->SpaceUsed();
     148           0 :         break;
     149             :       default:
     150             :         break;
     151             :     }
     152             :   }
     153             :   return total_size;
     154             : }
     155             : 
     156           0 : int UnknownFieldSet::SpaceUsed() const {
     157           0 :   return sizeof(*this) + SpaceUsedExcludingSelf();
     158             : }
     159             : 
     160         361 : void UnknownFieldSet::AddVarint(int number, uint64 value) {
     161             :   UnknownField field;
     162         361 :   field.number_ = number;
     163         361 :   field.SetType(UnknownField::TYPE_VARINT);
     164         361 :   field.varint_ = value;
     165         709 :   if (fields_ == NULL) fields_ = new vector<UnknownField>();
     166         361 :   fields_->push_back(field);
     167         361 : }
     168             : 
     169          18 : void UnknownFieldSet::AddFixed32(int number, uint32 value) {
     170             :   UnknownField field;
     171          18 :   field.number_ = number;
     172          18 :   field.SetType(UnknownField::TYPE_FIXED32);
     173          18 :   field.fixed32_ = value;
     174          31 :   if (fields_ == NULL) fields_ = new vector<UnknownField>();
     175          18 :   fields_->push_back(field);
     176          18 : }
     177             : 
     178          18 : void UnknownFieldSet::AddFixed64(int number, uint64 value) {
     179             :   UnknownField field;
     180          18 :   field.number_ = number;
     181          18 :   field.SetType(UnknownField::TYPE_FIXED64);
     182          18 :   field.fixed64_ = value;
     183          29 :   if (fields_ == NULL) fields_ = new vector<UnknownField>();
     184          18 :   fields_->push_back(field);
     185          18 : }
     186             : 
     187         154 : string* UnknownFieldSet::AddLengthDelimited(int number) {
     188             :   UnknownField field;
     189         154 :   field.number_ = number;
     190         154 :   field.SetType(UnknownField::TYPE_LENGTH_DELIMITED);
     191         308 :   field.length_delimited_.string_value_ = new string;
     192         287 :   if (fields_ == NULL) fields_ = new vector<UnknownField>();
     193         154 :   fields_->push_back(field);
     194         154 :   return field.length_delimited_.string_value_;
     195             : }
     196             : 
     197             : 
     198           3 : UnknownFieldSet* UnknownFieldSet::AddGroup(int number) {
     199             :   UnknownField field;
     200           3 :   field.number_ = number;
     201           3 :   field.SetType(UnknownField::TYPE_GROUP);
     202           3 :   field.group_ = new UnknownFieldSet;
     203           5 :   if (fields_ == NULL) fields_ = new vector<UnknownField>();
     204           3 :   fields_->push_back(field);
     205           3 :   return field.group_;
     206             : }
     207             : 
     208           0 : void UnknownFieldSet::AddField(const UnknownField& field) {
     209           0 :   if (fields_ == NULL) fields_ = new vector<UnknownField>();
     210           0 :   fields_->push_back(field);
     211           0 :   fields_->back().DeepCopy(field);
     212           0 : }
     213             : 
     214           0 : void UnknownFieldSet::DeleteSubrange(int start, int num) {
     215             :   // Delete the specified fields.
     216           0 :   for (int i = 0; i < num; ++i) {
     217           0 :     (*fields_)[i + start].Delete();
     218             :   }
     219             :   // Slide down the remaining fields.
     220           0 :   for (int i = start + num; i < fields_->size(); ++i) {
     221           0 :     (*fields_)[i - num] = (*fields_)[i];
     222             :   }
     223             :   // Pop off the # of deleted fields.
     224           0 :   for (int i = 0; i < num; ++i) {
     225           0 :     fields_->pop_back();
     226             :   }
     227           0 :   if (fields_ && fields_->size() == 0) {
     228             :     // maintain invariant: never hold fields_ if empty.
     229           0 :     delete fields_;
     230           0 :     fields_ = NULL;
     231             :   }
     232           0 : }
     233             : 
     234           0 : void UnknownFieldSet::DeleteByNumber(int number) {
     235           0 :   if (fields_ == NULL) return;
     236             :   int left = 0;  // The number of fields left after deletion.
     237           0 :   for (int i = 0; i < fields_->size(); ++i) {
     238           0 :     UnknownField* field = &(*fields_)[i];
     239           0 :     if (field->number() == number) {
     240           0 :       field->Delete();
     241             :     } else {
     242           0 :       if (i != left) {
     243           0 :         (*fields_)[left] = (*fields_)[i];
     244             :       }
     245           0 :       ++left;
     246             :     }
     247             :   }
     248           0 :   fields_->resize(left);
     249           0 :   if (left == 0) {
     250             :     // maintain invariant: never hold fields_ if empty.
     251           0 :     delete fields_;
     252           0 :     fields_ = NULL;
     253             :   }
     254             : }
     255             : 
     256          92 : bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) {
     257          46 :   UnknownFieldSet other;
     258          92 :   if (internal::WireFormat::SkipMessage(input, &other) &&
     259          46 :       input->ConsumedEntireMessage()) {
     260          46 :     MergeFromAndDestroy(&other);
     261             :     return true;
     262             :   } else {
     263             :     return false;
     264          46 :   }
     265             : }
     266             : 
     267          46 : bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) {
     268             :   Clear();
     269          46 :   return MergeFromCodedStream(input);
     270             : }
     271             : 
     272          46 : bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
     273          46 :   io::CodedInputStream coded_input(input);
     274          92 :   return (ParseFromCodedStream(&coded_input) &&
     275          92 :           coded_input.ConsumedEntireMessage());
     276             : }
     277             : 
     278          46 : bool UnknownFieldSet::ParseFromArray(const void* data, int size) {
     279          46 :   io::ArrayInputStream input(data, size);
     280          46 :   return ParseFromZeroCopyStream(&input);
     281             : }
     282             : 
     283        1034 : void UnknownField::Delete() {
     284        1034 :   switch (type()) {
     285             :     case UnknownField::TYPE_LENGTH_DELIMITED:
     286         550 :       delete length_delimited_.string_value_;
     287             :       break;
     288             :     case UnknownField::TYPE_GROUP:
     289           5 :       delete group_;
     290             :       break;
     291             :     default:
     292             :       break;
     293             :   }
     294        1034 : }
     295             : 
     296             : // Reset all owned ptrs, a special function for performance, to avoid double
     297             : // owning the ptrs, when we merge from a temporary UnknownFieldSet objects.
     298          46 : void UnknownField::Reset() {
     299          46 :   switch (type()) {
     300             :     case UnknownField::TYPE_LENGTH_DELIMITED:
     301          21 :       length_delimited_.string_value_ = NULL;
     302          21 :       break;
     303             :     case UnknownField::TYPE_GROUP: {
     304           0 :       group_ = NULL;
     305           0 :       break;
     306             :     }
     307             :     default:
     308             :       break;
     309             :   }
     310          46 : }
     311             : 
     312         480 : void UnknownField::DeepCopy(const UnknownField& other) {
     313         480 :   switch (type()) {
     314             :     case UnknownField::TYPE_LENGTH_DELIMITED:
     315             :       length_delimited_.string_value_ = new string(
     316         121 :           *length_delimited_.string_value_);
     317         121 :       break;
     318             :     case UnknownField::TYPE_GROUP: {
     319           2 :       UnknownFieldSet* group = new UnknownFieldSet();
     320           2 :       group->InternalMergeFrom(*group_);
     321           2 :       group_ = group;
     322           2 :       break;
     323             :     }
     324             :     default:
     325             :       break;
     326             :   }
     327         480 : }
     328             : 
     329             : 
     330           0 : void UnknownField::SerializeLengthDelimitedNoTag(
     331             :     io::CodedOutputStream* output) const {
     332             :   GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
     333           0 :   const string& data = *length_delimited_.string_value_;
     334           0 :   output->WriteVarint32(data.size());
     335           0 :   output->WriteRawMaybeAliased(data.data(), data.size());
     336           0 : }
     337             : 
     338           0 : uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const {
     339             :   GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
     340           0 :   const string& data = *length_delimited_.string_value_;
     341           0 :   target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target);
     342           0 :   target = io::CodedOutputStream::WriteStringToArray(data, target);
     343           0 :   return target;
     344             : }
     345             : 
     346             : }  // namespace protobuf
     347             : }  // namespace google

Generated by: LCOV version 1.10