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 #ifndef GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
     32 #define GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
     33 
     34 #include <google/protobuf/map.h>
     35 #include <google/protobuf/map_entry_lite.h>
     36 
     37 namespace google {
     38 namespace protobuf {
     39 namespace internal {
     40 
     41 // This class provides accesss to map field using generated api. It is used for
     42 // internal generated message implentation only. Users should never use this
     43 // directly.
     44 template <typename Key, typename T,
     45           WireFormatLite::FieldType key_wire_type,
     46           WireFormatLite::FieldType value_wire_type,
     47           int default_enum_value = 0>
     48 class MapFieldLite {
     49   // Define message type for internal repeated field.
     50   typedef MapEntryLite<Key, T, key_wire_type, value_wire_type,
     51                        default_enum_value> EntryType;
     52 
     53  public:
     54   MapFieldLite();
     55   explicit MapFieldLite(Arena* arena);
     56   virtual ~MapFieldLite();
     57 
     58   // Accessors
     59   virtual const Map<Key, T>& GetMap() const;
     60   virtual Map<Key, T>* MutableMap();
     61 
     62   // Convenient methods for generated message implementation.
     63   virtual int size() const;
     64   virtual void Clear();
     65   virtual void MergeFrom(const MapFieldLite& other);
     66   virtual void Swap(MapFieldLite* other);
     67 
     68   // Set default enum value only for proto2 map field whose value is enum type.
     69   void SetDefaultEnumValue();
     70 
     71   // Used in the implementation of parsing. Caller should take the ownership.
     72   EntryType* NewEntry() const;
     73   // Used in the implementation of serializing enum value type. Caller should
     74   // take the ownership.
     75   EntryType* NewEnumEntryWrapper(const Key& key, const T t) const;
     76   // Used in the implementation of serializing other value types. Caller should
     77   // take the ownership.
     78   EntryType* NewEntryWrapper(const Key& key, const T& t) const;
     79 
     80  protected:
     81   // Convenient methods to get internal google::protobuf::Map
     82   virtual const Map<Key, T>& GetInternalMap() const;
     83   virtual Map<Key, T>* MutableInternalMap();
     84 
     85  private:
     86   typedef void DestructorSkippable_;
     87 
     88   Arena* arena_;
     89   Map<Key, T>* map_;
     90 
     91   friend class ::google::protobuf::Arena;
     92 };
     93 
     94 template <typename Key, typename T,
     95           WireFormatLite::FieldType key_wire_type,
     96           WireFormatLite::FieldType value_wire_type,
     97           int default_enum_value>
     98 MapFieldLite<Key, T, key_wire_type, value_wire_type,
     99              default_enum_value>::MapFieldLite()
    100     : arena_(NULL) {
    101   map_ = new Map<Key, T>;
    102   SetDefaultEnumValue();
    103 }
    104 
    105 template <typename Key, typename T,
    106           WireFormatLite::FieldType key_wire_type,
    107           WireFormatLite::FieldType value_wire_type,
    108           int default_enum_value>
    109 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    110              default_enum_value>::MapFieldLite(Arena* arena)
    111   : arena_(arena) {
    112   map_ = Arena::CreateMessage<Map<Key, T> >(arena);
    113   SetDefaultEnumValue();
    114 }
    115 
    116 template <typename Key, typename T,
    117           WireFormatLite::FieldType key_wire_type,
    118           WireFormatLite::FieldType value_wire_type,
    119           int default_enum_value>
    120 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    121              default_enum_value>::~MapFieldLite() {
    122   delete map_;
    123 }
    124 
    125 template <typename Key, typename T,
    126           WireFormatLite::FieldType key_wire_type,
    127           WireFormatLite::FieldType value_wire_type,
    128           int default_enum_value>
    129 const Map<Key, T>&
    130 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    131              default_enum_value>::GetMap() const {
    132   return *map_;
    133 }
    134 
    135 template <typename Key, typename T,
    136           WireFormatLite::FieldType key_wire_type,
    137           WireFormatLite::FieldType value_wire_type,
    138           int default_enum_value>
    139 Map<Key, T>*
    140 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    141              default_enum_value>::MutableMap() {
    142   return map_;
    143 }
    144 
    145 template <typename Key, typename T,
    146           WireFormatLite::FieldType key_wire_type,
    147           WireFormatLite::FieldType value_wire_type,
    148           int default_enum_value>
    149 int
    150 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    151              default_enum_value>::size() const {
    152   return map_->size();
    153 }
    154 
    155 template <typename Key, typename T,
    156           WireFormatLite::FieldType key_wire_type,
    157           WireFormatLite::FieldType value_wire_type,
    158           int default_enum_value>
    159 void
    160 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    161              default_enum_value>::Clear() {
    162   map_->clear();
    163 }
    164 
    165 template <typename Key, typename T,
    166           WireFormatLite::FieldType key_wire_type,
    167           WireFormatLite::FieldType value_wire_type,
    168           int default_enum_value>
    169 void
    170 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    171              default_enum_value>::MergeFrom(
    172     const MapFieldLite& other) {
    173   for (typename Map<Key, T>::const_iterator it = other.map_->begin();
    174        it != other.map_->end(); ++it) {
    175     (*map_)[it->first] = it->second;
    176   }
    177 }
    178 
    179 template <typename Key, typename T,
    180           WireFormatLite::FieldType key_wire_type,
    181           WireFormatLite::FieldType value_wire_type,
    182           int default_enum_value>
    183 void
    184 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    185              default_enum_value>::Swap(
    186     MapFieldLite* other) {
    187   std::swap(map_, other->map_);
    188 }
    189 
    190 template <typename Key, typename T,
    191           WireFormatLite::FieldType key_wire_type,
    192           WireFormatLite::FieldType value_wire_type,
    193           int default_enum_value>
    194 void
    195 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    196              default_enum_value>::SetDefaultEnumValue() {
    197   MutableInternalMap()->SetDefaultEnumValue(default_enum_value);
    198 }
    199 
    200 template <typename Key, typename T,
    201           WireFormatLite::FieldType key_wire_type,
    202           WireFormatLite::FieldType value_wire_type,
    203           int default_enum_value>
    204 const Map<Key, T>&
    205 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    206              default_enum_value>::GetInternalMap() const {
    207   return *map_;
    208 }
    209 
    210 template <typename Key, typename T,
    211           WireFormatLite::FieldType key_wire_type,
    212           WireFormatLite::FieldType value_wire_type,
    213           int default_enum_value>
    214 Map<Key, T>*
    215 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    216              default_enum_value>::MutableInternalMap() {
    217   return map_;
    218 }
    219 
    220 #define EntryType \
    221   MapEntryLite<Key, T, key_wire_type, value_wire_type, default_enum_value>
    222 
    223 template <typename Key, typename T,
    224           WireFormatLite::FieldType key_wire_type,
    225           WireFormatLite::FieldType value_wire_type,
    226           int default_enum_value>
    227 EntryType*
    228 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    229              default_enum_value>::NewEntry() const {
    230   if (arena_ == NULL) {
    231     return new EntryType();
    232   } else {
    233     return Arena::CreateMessage<EntryType>(arena_);
    234   }
    235 }
    236 
    237 template <typename Key, typename T,
    238           WireFormatLite::FieldType key_wire_type,
    239           WireFormatLite::FieldType value_wire_type,
    240           int default_enum_value>
    241 EntryType*
    242 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    243              default_enum_value>::NewEnumEntryWrapper(const Key& key,
    244                                                       const T t) const {
    245   return EntryType::EnumWrap(key, t, arena_);
    246 }
    247 
    248 template <typename Key, typename T,
    249           WireFormatLite::FieldType key_wire_type,
    250           WireFormatLite::FieldType value_wire_type,
    251           int default_enum_value>
    252 EntryType*
    253 MapFieldLite<Key, T, key_wire_type, value_wire_type,
    254              default_enum_value>::NewEntryWrapper(const Key& key,
    255                                                   const T& t) const {
    256   return EntryType::Wrap(key, t, arena_);
    257 }
    258 
    259 #undef EntryType
    260 
    261 // True if IsInitialized() is true for value field in all elements of t. T is
    262 // expected to be message.  It's useful to have this helper here to keep the
    263 // protobuf compiler from ever having to emit loops in IsInitialized() methods.
    264 // We want the C++ compiler to inline this or not as it sees fit.
    265 template <typename Key, typename T>
    266 bool AllAreInitialized(const Map<Key, T>& t) {
    267   for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
    268        ++it) {
    269     if (!it->second.IsInitialized()) return false;
    270   }
    271   return true;
    272 }
    273 
    274 }  // namespace internal
    275 }  // namespace protobuf
    276 
    277 }  // namespace google
    278 #endif  // GOOGLE_PROTOBUF_MAP_FIELD_LITE_H__
    279