Home | History | Annotate | Download | only in protobuf
      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