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/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 void DeleteDefaultUnknownFieldSet() { 55 delete default_unknown_field_set_instance_; 56 } 57 58 void InitDefaultUnknownFieldSet() { 59 default_unknown_field_set_instance_ = new UnknownFieldSet(); 60 internal::OnShutdown(&DeleteDefaultUnknownFieldSet); 61 } 62 63 GOOGLE_PROTOBUF_DECLARE_ONCE(default_unknown_field_set_once_init_); 64 } 65 66 const UnknownFieldSet* UnknownFieldSet::default_instance() { 67 ::google::protobuf::GoogleOnceInit(&default_unknown_field_set_once_init_, 68 &InitDefaultUnknownFieldSet); 69 return default_unknown_field_set_instance_; 70 } 71 72 UnknownFieldSet::UnknownFieldSet() 73 : fields_(NULL) {} 74 75 UnknownFieldSet::~UnknownFieldSet() { 76 Clear(); 77 delete fields_; 78 } 79 80 void UnknownFieldSet::ClearFallback() { 81 if (fields_ != NULL) { 82 for (int i = 0; i < fields_->size(); i++) { 83 (*fields_)[i].Delete(); 84 } 85 delete fields_; 86 fields_ = NULL; 87 } 88 } 89 90 void UnknownFieldSet::ClearAndFreeMemory() { 91 if (fields_ != NULL) { 92 Clear(); 93 } 94 } 95 96 void UnknownFieldSet::InternalMergeFrom(const UnknownFieldSet& other) { 97 int other_field_count = other.field_count(); 98 if (other_field_count > 0) { 99 fields_ = new vector<UnknownField>(); 100 for (int i = 0; i < other_field_count; i++) { 101 fields_->push_back((*other.fields_)[i]); 102 fields_->back().DeepCopy((*other.fields_)[i]); 103 } 104 } 105 } 106 107 void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) { 108 int other_field_count = other.field_count(); 109 if (other_field_count > 0) { 110 if (fields_ == NULL) fields_ = new vector<UnknownField>(); 111 for (int i = 0; i < other_field_count; i++) { 112 fields_->push_back((*other.fields_)[i]); 113 fields_->back().DeepCopy((*other.fields_)[i]); 114 } 115 } 116 } 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 void UnknownFieldSet::MergeFromAndDestroy(UnknownFieldSet* other) { 121 int other_field_count = other->field_count(); 122 if (other_field_count > 0) { 123 if (fields_ == NULL) fields_ = new vector<UnknownField>(); 124 for (int i = 0; i < other_field_count; i++) { 125 fields_->push_back((*other->fields_)[i]); 126 (*other->fields_)[i].Reset(); 127 } 128 } 129 delete other->fields_; 130 other->fields_ = NULL; 131 } 132 133 int UnknownFieldSet::SpaceUsedExcludingSelf() const { 134 if (fields_ == NULL) return 0; 135 136 int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size(); 137 138 for (int i = 0; i < fields_->size(); i++) { 139 const UnknownField& field = (*fields_)[i]; 140 switch (field.type()) { 141 case UnknownField::TYPE_LENGTH_DELIMITED: 142 total_size += sizeof(*field.length_delimited_.string_value_) + 143 internal::StringSpaceUsedExcludingSelf( 144 *field.length_delimited_.string_value_); 145 break; 146 case UnknownField::TYPE_GROUP: 147 total_size += field.group_->SpaceUsed(); 148 break; 149 default: 150 break; 151 } 152 } 153 return total_size; 154 } 155 156 int UnknownFieldSet::SpaceUsed() const { 157 return sizeof(*this) + SpaceUsedExcludingSelf(); 158 } 159 160 void UnknownFieldSet::AddVarint(int number, uint64 value) { 161 UnknownField field; 162 field.number_ = number; 163 field.SetType(UnknownField::TYPE_VARINT); 164 field.varint_ = value; 165 if (fields_ == NULL) fields_ = new vector<UnknownField>(); 166 fields_->push_back(field); 167 } 168 169 void UnknownFieldSet::AddFixed32(int number, uint32 value) { 170 UnknownField field; 171 field.number_ = number; 172 field.SetType(UnknownField::TYPE_FIXED32); 173 field.fixed32_ = value; 174 if (fields_ == NULL) fields_ = new vector<UnknownField>(); 175 fields_->push_back(field); 176 } 177 178 void UnknownFieldSet::AddFixed64(int number, uint64 value) { 179 UnknownField field; 180 field.number_ = number; 181 field.SetType(UnknownField::TYPE_FIXED64); 182 field.fixed64_ = value; 183 if (fields_ == NULL) fields_ = new vector<UnknownField>(); 184 fields_->push_back(field); 185 } 186 187 string* UnknownFieldSet::AddLengthDelimited(int number) { 188 UnknownField field; 189 field.number_ = number; 190 field.SetType(UnknownField::TYPE_LENGTH_DELIMITED); 191 field.length_delimited_.string_value_ = new string; 192 if (fields_ == NULL) fields_ = new vector<UnknownField>(); 193 fields_->push_back(field); 194 return field.length_delimited_.string_value_; 195 } 196 197 198 UnknownFieldSet* UnknownFieldSet::AddGroup(int number) { 199 UnknownField field; 200 field.number_ = number; 201 field.SetType(UnknownField::TYPE_GROUP); 202 field.group_ = new UnknownFieldSet; 203 if (fields_ == NULL) fields_ = new vector<UnknownField>(); 204 fields_->push_back(field); 205 return field.group_; 206 } 207 208 void UnknownFieldSet::AddField(const UnknownField& field) { 209 if (fields_ == NULL) fields_ = new vector<UnknownField>(); 210 fields_->push_back(field); 211 fields_->back().DeepCopy(field); 212 } 213 214 void UnknownFieldSet::DeleteSubrange(int start, int num) { 215 // Delete the specified fields. 216 for (int i = 0; i < num; ++i) { 217 (*fields_)[i + start].Delete(); 218 } 219 // Slide down the remaining fields. 220 for (int i = start + num; i < fields_->size(); ++i) { 221 (*fields_)[i - num] = (*fields_)[i]; 222 } 223 // Pop off the # of deleted fields. 224 for (int i = 0; i < num; ++i) { 225 fields_->pop_back(); 226 } 227 if (fields_ && fields_->size() == 0) { 228 // maintain invariant: never hold fields_ if empty. 229 delete fields_; 230 fields_ = NULL; 231 } 232 } 233 234 void UnknownFieldSet::DeleteByNumber(int number) { 235 if (fields_ == NULL) return; 236 int left = 0; // The number of fields left after deletion. 237 for (int i = 0; i < fields_->size(); ++i) { 238 UnknownField* field = &(*fields_)[i]; 239 if (field->number() == number) { 240 field->Delete(); 241 } else { 242 if (i != left) { 243 (*fields_)[left] = (*fields_)[i]; 244 } 245 ++left; 246 } 247 } 248 fields_->resize(left); 249 if (left == 0) { 250 // maintain invariant: never hold fields_ if empty. 251 delete fields_; 252 fields_ = NULL; 253 } 254 } 255 256 bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) { 257 UnknownFieldSet other; 258 if (internal::WireFormat::SkipMessage(input, &other) && 259 input->ConsumedEntireMessage()) { 260 MergeFromAndDestroy(&other); 261 return true; 262 } else { 263 return false; 264 } 265 } 266 267 bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) { 268 Clear(); 269 return MergeFromCodedStream(input); 270 } 271 272 bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { 273 io::CodedInputStream coded_input(input); 274 return (ParseFromCodedStream(&coded_input) && 275 coded_input.ConsumedEntireMessage()); 276 } 277 278 bool UnknownFieldSet::ParseFromArray(const void* data, int size) { 279 io::ArrayInputStream input(data, size); 280 return ParseFromZeroCopyStream(&input); 281 } 282 283 void UnknownField::Delete() { 284 switch (type()) { 285 case UnknownField::TYPE_LENGTH_DELIMITED: 286 delete length_delimited_.string_value_; 287 break; 288 case UnknownField::TYPE_GROUP: 289 delete group_; 290 break; 291 default: 292 break; 293 } 294 } 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 void UnknownField::Reset() { 299 switch (type()) { 300 case UnknownField::TYPE_LENGTH_DELIMITED: 301 length_delimited_.string_value_ = NULL; 302 break; 303 case UnknownField::TYPE_GROUP: { 304 group_ = NULL; 305 break; 306 } 307 default: 308 break; 309 } 310 } 311 312 void UnknownField::DeepCopy(const UnknownField& other) { 313 switch (type()) { 314 case UnknownField::TYPE_LENGTH_DELIMITED: 315 length_delimited_.string_value_ = new string( 316 *length_delimited_.string_value_); 317 break; 318 case UnknownField::TYPE_GROUP: { 319 UnknownFieldSet* group = new UnknownFieldSet(); 320 group->InternalMergeFrom(*group_); 321 group_ = group; 322 break; 323 } 324 default: 325 break; 326 } 327 } 328 329 330 void UnknownField::SerializeLengthDelimitedNoTag( 331 io::CodedOutputStream* output) const { 332 GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); 333 const string& data = *length_delimited_.string_value_; 334 output->WriteVarint32(data.size()); 335 output->WriteRawMaybeAliased(data.data(), data.size()); 336 } 337 338 uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const { 339 GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); 340 const string& data = *length_delimited_.string_value_; 341 target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); 342 target = io::CodedOutputStream::WriteStringToArray(data, target); 343 return target; 344 } 345 346 } // namespace protobuf 347 } // namespace google 348