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