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 // Contains classes used to keep track of unrecognized fields seen while 36 // parsing a protocol message. 37 38 #ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ 39 #define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ 40 41 #include <assert.h> 42 #include <string> 43 #include <vector> 44 #include <google/protobuf/stubs/common.h> 45 46 namespace google { 47 namespace protobuf { 48 namespace io { 49 class CodedInputStream; // coded_stream.h 50 class CodedOutputStream; // coded_stream.h 51 class ZeroCopyInputStream; // zero_copy_stream.h 52 } 53 namespace internal { 54 class WireFormat; // wire_format.h 55 class MessageSetFieldSkipperUsingCord; 56 // extension_set_heavy.cc 57 } 58 59 class Message; // message.h 60 class UnknownField; // below 61 62 // An UnknownFieldSet contains fields that were encountered while parsing a 63 // message but were not defined by its type. Keeping track of these can be 64 // useful, especially in that they may be written if the message is serialized 65 // again without being cleared in between. This means that software which 66 // simply receives messages and forwards them to other servers does not need 67 // to be updated every time a new field is added to the message definition. 68 // 69 // To get the UnknownFieldSet attached to any message, call 70 // Reflection::GetUnknownFields(). 71 // 72 // This class is necessarily tied to the protocol buffer wire format, unlike 73 // the Reflection interface which is independent of any serialization scheme. 74 class LIBPROTOBUF_EXPORT UnknownFieldSet { 75 public: 76 UnknownFieldSet(); 77 ~UnknownFieldSet(); 78 79 // Remove all fields. 80 inline void Clear(); 81 82 // Remove all fields and deallocate internal data objects 83 void ClearAndFreeMemory(); 84 85 // Is this set empty? 86 inline bool empty() const; 87 88 // Merge the contents of some other UnknownFieldSet with this one. 89 void MergeFrom(const UnknownFieldSet& other); 90 91 // Swaps the contents of some other UnknownFieldSet with this one. 92 inline void Swap(UnknownFieldSet* x); 93 94 // Computes (an estimate of) the total number of bytes currently used for 95 // storing the unknown fields in memory. Does NOT include 96 // sizeof(*this) in the calculation. 97 int SpaceUsedExcludingSelf() const; 98 99 // Version of SpaceUsed() including sizeof(*this). 100 int SpaceUsed() const; 101 102 // Returns the number of fields present in the UnknownFieldSet. 103 inline int field_count() const; 104 // Get a field in the set, where 0 <= index < field_count(). The fields 105 // appear in the order in which they were added. 106 inline const UnknownField& field(int index) const; 107 // Get a mutable pointer to a field in the set, where 108 // 0 <= index < field_count(). The fields appear in the order in which 109 // they were added. 110 inline UnknownField* mutable_field(int index); 111 112 // Adding fields --------------------------------------------------- 113 114 void AddVarint(int number, uint64 value); 115 void AddFixed32(int number, uint32 value); 116 void AddFixed64(int number, uint64 value); 117 void AddLengthDelimited(int number, const string& value); 118 string* AddLengthDelimited(int number); 119 UnknownFieldSet* AddGroup(int number); 120 121 // Adds an unknown field from another set. 122 void AddField(const UnknownField& field); 123 124 // Delete fields with indices in the range [start .. start+num-1]. 125 // Caution: implementation moves all fields with indices [start+num .. ]. 126 void DeleteSubrange(int start, int num); 127 128 // Delete all fields with a specific field number. The order of left fields 129 // is preserved. 130 // Caution: implementation moves all fields after the first deleted field. 131 void DeleteByNumber(int number); 132 133 // Parsing helpers ------------------------------------------------- 134 // These work exactly like the similarly-named methods of Message. 135 136 bool MergeFromCodedStream(io::CodedInputStream* input); 137 bool ParseFromCodedStream(io::CodedInputStream* input); 138 bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); 139 bool ParseFromArray(const void* data, int size); 140 inline bool ParseFromString(const string& data) { 141 return ParseFromArray(data.data(), static_cast<int>(data.size())); 142 } 143 144 private: 145 146 void ClearFallback(); 147 148 std::vector<UnknownField>* fields_; 149 150 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet); 151 }; 152 153 // Represents one field in an UnknownFieldSet. 154 class LIBPROTOBUF_EXPORT UnknownField { 155 public: 156 enum Type { 157 TYPE_VARINT, 158 TYPE_FIXED32, 159 TYPE_FIXED64, 160 TYPE_LENGTH_DELIMITED, 161 TYPE_GROUP 162 }; 163 164 // The field's tag number, as seen on the wire. 165 inline int number() const; 166 167 // The field type. 168 inline Type type() const; 169 170 // Accessors ------------------------------------------------------- 171 // Each method works only for UnknownFields of the corresponding type. 172 173 inline uint64 varint() const; 174 inline uint32 fixed32() const; 175 inline uint64 fixed64() const; 176 inline const string& length_delimited() const; 177 inline const UnknownFieldSet& group() const; 178 179 inline void set_varint(uint64 value); 180 inline void set_fixed32(uint32 value); 181 inline void set_fixed64(uint64 value); 182 inline void set_length_delimited(const string& value); 183 inline string* mutable_length_delimited(); 184 inline UnknownFieldSet* mutable_group(); 185 186 // Serialization API. 187 // These methods can take advantage of the underlying implementation and may 188 // archieve a better performance than using getters to retrieve the data and 189 // do the serialization yourself. 190 void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const; 191 uint8* SerializeLengthDelimitedNoTagToArray(uint8* target) const; 192 193 inline int GetLengthDelimitedSize() const; 194 195 private: 196 friend class UnknownFieldSet; 197 198 // If this UnknownField contains a pointer, delete it. 199 void Delete(); 200 201 // Make a deep copy of any pointers in this UnknownField. 202 void DeepCopy(); 203 204 // Set the wire type of this UnknownField. Should only be used when this 205 // UnknownField is being created. 206 inline void SetType(Type type); 207 208 uint32 number_; 209 uint32 type_; 210 union { 211 uint64 varint_; 212 uint32 fixed32_; 213 uint64 fixed64_; 214 mutable union { 215 string* string_value_; 216 } length_delimited_; 217 UnknownFieldSet* group_; 218 }; 219 }; 220 221 // =================================================================== 222 // inline implementations 223 224 inline void UnknownFieldSet::Clear() { 225 if (fields_ != NULL) { 226 ClearFallback(); 227 } 228 } 229 230 inline bool UnknownFieldSet::empty() const { 231 return fields_ == NULL || fields_->empty(); 232 } 233 234 inline void UnknownFieldSet::Swap(UnknownFieldSet* x) { 235 std::swap(fields_, x->fields_); 236 } 237 238 inline int UnknownFieldSet::field_count() const { 239 return (fields_ == NULL) ? 0 : static_cast<int>(fields_->size()); 240 } 241 inline const UnknownField& UnknownFieldSet::field(int index) const { 242 return (*fields_)[index]; 243 } 244 inline UnknownField* UnknownFieldSet::mutable_field(int index) { 245 return &(*fields_)[index]; 246 } 247 248 inline void UnknownFieldSet::AddLengthDelimited( 249 int number, const string& value) { 250 AddLengthDelimited(number)->assign(value); 251 } 252 253 254 inline int UnknownField::number() const { return number_; } 255 inline UnknownField::Type UnknownField::type() const { 256 return static_cast<Type>(type_); 257 } 258 259 inline uint64 UnknownField::varint() const { 260 assert(type() == TYPE_VARINT); 261 return varint_; 262 } 263 inline uint32 UnknownField::fixed32() const { 264 assert(type() == TYPE_FIXED32); 265 return fixed32_; 266 } 267 inline uint64 UnknownField::fixed64() const { 268 assert(type() == TYPE_FIXED64); 269 return fixed64_; 270 } 271 inline const string& UnknownField::length_delimited() const { 272 assert(type() == TYPE_LENGTH_DELIMITED); 273 return *length_delimited_.string_value_; 274 } 275 inline const UnknownFieldSet& UnknownField::group() const { 276 assert(type() == TYPE_GROUP); 277 return *group_; 278 } 279 280 inline void UnknownField::set_varint(uint64 value) { 281 assert(type() == TYPE_VARINT); 282 varint_ = value; 283 } 284 inline void UnknownField::set_fixed32(uint32 value) { 285 assert(type() == TYPE_FIXED32); 286 fixed32_ = value; 287 } 288 inline void UnknownField::set_fixed64(uint64 value) { 289 assert(type() == TYPE_FIXED64); 290 fixed64_ = value; 291 } 292 inline void UnknownField::set_length_delimited(const string& value) { 293 assert(type() == TYPE_LENGTH_DELIMITED); 294 length_delimited_.string_value_->assign(value); 295 } 296 inline string* UnknownField::mutable_length_delimited() { 297 assert(type() == TYPE_LENGTH_DELIMITED); 298 return length_delimited_.string_value_; 299 } 300 inline UnknownFieldSet* UnknownField::mutable_group() { 301 assert(type() == TYPE_GROUP); 302 return group_; 303 } 304 305 inline int UnknownField::GetLengthDelimitedSize() const { 306 GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); 307 return static_cast<int>(length_delimited_.string_value_->size()); 308 } 309 310 inline void UnknownField::SetType(Type type) { 311 type_ = type; 312 } 313 314 315 } // namespace protobuf 316 317 } // namespace google 318 #endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ 319