LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - map_field.h (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 25 0.0 %
Date: 2015-10-10 Functions: 0 6 0.0 %

          Line data    Source code
       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_H__
      32             : #define GOOGLE_PROTOBUF_MAP_FIELD_H__
      33             : 
      34             : #include <google/protobuf/stubs/atomicops.h>
      35             : #include <google/protobuf/stubs/mutex.h>
      36             : #include <google/protobuf/stubs/common.h>
      37             : #include <google/protobuf/generated_message_reflection.h>
      38             : #include <google/protobuf/arena.h>
      39             : #include <google/protobuf/map_entry.h>
      40             : #include <google/protobuf/map_field_lite.h>
      41             : #include <google/protobuf/map_type_handler.h>
      42             : #include <google/protobuf/message.h>
      43             : #include <google/protobuf/repeated_field.h>
      44             : #include <google/protobuf/unknown_field_set.h>
      45             : 
      46             : 
      47             : namespace google {
      48             : namespace protobuf {
      49             : class DynamicMessage;
      50             : class MapKey;
      51             : namespace internal {
      52             : 
      53             : class ContendedMapCleanTest;
      54             : class GeneratedMessageReflection;
      55             : class MapFieldAccessor;
      56             : 
      57             : // This class provides accesss to map field using reflection, which is the same
      58             : // as those provided for RepeatedPtrField<Message>. It is used for internal
      59             : // reflection implentation only. Users should never use this directly.
      60             : class LIBPROTOBUF_EXPORT MapFieldBase {
      61             :  public:
      62             :   MapFieldBase()
      63             :       : arena_(NULL),
      64             :         repeated_field_(NULL),
      65             :         entry_descriptor_(NULL),
      66             :         assign_descriptor_callback_(NULL),
      67           0 :         state_(STATE_MODIFIED_MAP) {}
      68           0 :   explicit MapFieldBase(Arena* arena)
      69             :       : arena_(arena),
      70             :         repeated_field_(NULL),
      71             :         entry_descriptor_(NULL),
      72             :         assign_descriptor_callback_(NULL),
      73           0 :         state_(STATE_MODIFIED_MAP) {
      74             :     // Mutex's destructor needs to be called explicitly to release resources
      75             :     // acquired in its constructor.
      76           0 :     arena->OwnDestructor(&mutex_);
      77           0 :   }
      78             :   virtual ~MapFieldBase();
      79             : 
      80             :   // Returns reference to internal repeated field. Data written using
      81             :   // google::protobuf::Map's api prior to calling this function is guarantted to be
      82             :   // included in repeated field.
      83             :   const RepeatedPtrFieldBase& GetRepeatedField() const;
      84             : 
      85             :   // Like above. Returns mutable pointer to the internal repeated field.
      86             :   RepeatedPtrFieldBase* MutableRepeatedField();
      87             : 
      88             :   // Pure virtual map APIs for Map Reflection.
      89             :   virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
      90             :   virtual bool InsertMapValue(const MapKey& map_key, MapValueRef* val) = 0;
      91             :   virtual bool DeleteMapValue(const MapKey& map_key) = 0;
      92             :   virtual bool EqualIterator(const MapIterator& a,
      93             :                              const MapIterator& b) const = 0;
      94             :   virtual void MapBegin(MapIterator* map_iter) const = 0;
      95             :   virtual void MapEnd(MapIterator* map_iter) const = 0;
      96             :   // Sync Map with repeated field and returns the size of map.
      97             :   virtual int size() const = 0;
      98             : 
      99             :   // Returns the number of bytes used by the repeated field, excluding
     100             :   // sizeof(*this)
     101             :   int SpaceUsedExcludingSelf() const;
     102             : 
     103             :  protected:
     104             :   // Gets the size of space used by map field.
     105             :   virtual int SpaceUsedExcludingSelfNoLock() const;
     106             : 
     107             :   // Synchronizes the content in Map to RepeatedPtrField if there is any change
     108             :   // to Map after last synchronization.
     109             :   void SyncRepeatedFieldWithMap() const;
     110             :   virtual void SyncRepeatedFieldWithMapNoLock() const;
     111             : 
     112             :   // Synchronizes the content in RepeatedPtrField to Map if there is any change
     113             :   // to RepeatedPtrField after last synchronization.
     114             :   void SyncMapWithRepeatedField() const;
     115           0 :   virtual void SyncMapWithRepeatedFieldNoLock() const {}
     116             : 
     117             :   // Tells MapFieldBase that there is new change to Map.
     118             :   void SetMapDirty();
     119             : 
     120             :   // Tells MapFieldBase that there is new change to RepeatedPTrField.
     121             :   void SetRepeatedDirty();
     122             : 
     123             :   // Provides derived class the access to repeated field.
     124             :   void* MutableRepeatedPtrField() const;
     125             : 
     126             :   // Creates descriptor for only one time.
     127             :   void InitMetadataOnce() const;
     128             : 
     129             :   enum State {
     130             :     STATE_MODIFIED_MAP = 0,       // map has newly added data that has not been
     131             :                                   // synchronized to repeated field
     132             :     STATE_MODIFIED_REPEATED = 1,  // repeated field has newly added data that
     133             :                                   // has not been synchronized to map
     134             :     CLEAN = 2,  // data in map and repeated field are same
     135             :   };
     136             : 
     137             :   Arena* arena_;
     138             :   mutable RepeatedPtrField<Message>* repeated_field_;
     139             :   // MapEntry can only be created from MapField. To create MapEntry, MapField
     140             :   // needs to know its descriptor, because MapEntry is not generated class which
     141             :   // cannot initialize its own descriptor by calling generated
     142             :   // descriptor-assign-function. Thus, we need to register a callback to
     143             :   // initialize MapEntry's descriptor.
     144             :   const Descriptor** entry_descriptor_;
     145             :   void (*assign_descriptor_callback_)();
     146             : 
     147             :   mutable Mutex mutex_;  // The thread to synchronize map and repeated field
     148             :                          // needs to get lock first;
     149             :   mutable volatile Atomic32 state_;  // 0: STATE_MODIFIED_MAP
     150             :                                      // 1: STATE_MODIFIED_REPEATED
     151             :                                      // 2: CLEAN
     152             : 
     153             :  private:
     154             :   friend class ContendedMapCleanTest;
     155             :   friend class GeneratedMessageReflection;
     156             :   friend class MapFieldAccessor;
     157             :   friend class ::google::protobuf::DynamicMessage;
     158             : 
     159             :   // Virtual helper methods for MapIterator. MapIterator doesn't have the
     160             :   // type helper for key and value. Call these help methods to deal with
     161             :   // different types. Real helper methods are implemented in
     162             :   // TypeDefinedMapFieldBase.
     163             :   friend class ::google::protobuf::MapIterator;
     164             :   // Allocate map<...>::iterator for MapIterator.
     165             :   virtual void InitializeIterator(MapIterator* map_iter) const = 0;
     166             : 
     167             :   // DeleteIterator() is called by the destructor of MapIterator only.
     168             :   // It deletes map<...>::iterator for MapIterator.
     169             :   virtual void DeleteIterator(MapIterator* map_iter) const = 0;
     170             : 
     171             :   // Copy the map<...>::iterator from other_iterator to
     172             :   // this_iterator.
     173             :   virtual void CopyIterator(MapIterator* this_iterator,
     174             :                             const MapIterator& other_iterator) const = 0;
     175             : 
     176             :   // IncreaseIterator() is called by operator++() of MapIterator only.
     177             :   // It implements the ++ operator of MapIterator.
     178             :   virtual void IncreaseIterator(MapIterator* map_iter) const = 0;
     179             : };
     180             : 
     181             : // This class provides common Map Reflection implementations for generated
     182             : // message and dynamic message.
     183             : template<typename Key, typename T>
     184             : class TypeDefinedMapFieldBase : public MapFieldBase {
     185             :  public:
     186           0 :   TypeDefinedMapFieldBase() {}
     187           0 :   explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
     188           0 :   ~TypeDefinedMapFieldBase() {}
     189           0 :   void MapBegin(MapIterator* map_iter) const;
     190           0 :   void MapEnd(MapIterator* map_iter) const;
     191           0 :   bool EqualIterator(const MapIterator& a, const MapIterator& b) const;
     192             : 
     193             :   virtual const Map<Key, T>& GetMap() const = 0;
     194             :   virtual Map<Key, T>* MutableMap() = 0;
     195             : 
     196             :  protected:
     197             :   typename Map<Key, T>::const_iterator& InternalGetIterator(
     198             :       const MapIterator* map_iter) const;
     199             : 
     200             :  private:
     201             :   void InitializeIterator(MapIterator* map_iter) const;
     202             :   void DeleteIterator(MapIterator* map_iter) const;
     203           0 :   void CopyIterator(MapIterator* this_iteratorm,
     204           0 :                     const MapIterator& that_iterator) const;
     205           0 :   void IncreaseIterator(MapIterator* map_iter) const;
     206             : 
     207             :   virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
     208             : };
     209             : 
     210             : // This class provides accesss to map field using generated api. It is used for
     211             : // internal generated message implentation only. Users should never use this
     212             : // directly.
     213             : template <typename Key, typename T,
     214             :           WireFormatLite::FieldType kKeyFieldType,
     215             :           WireFormatLite::FieldType kValueFieldType,
     216             :           int default_enum_value = 0>
     217             : class MapField : public TypeDefinedMapFieldBase<Key, T>,
     218             :                  public MapFieldLite<Key, T, kKeyFieldType, kValueFieldType,
     219             :                                      default_enum_value> {
     220             :   // Provide utilities to parse/serialize key/value.  Provide utilities to
     221             :   // manipulate internal stored type.
     222             :   typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
     223             :   typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler;
     224             : 
     225             :   // Define message type for internal repeated field.
     226             :   typedef MapEntry<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>
     227             :       EntryType;
     228             :   typedef MapEntryLite<Key, T, kKeyFieldType, kValueFieldType,
     229             :                        default_enum_value> EntryLiteType;
     230             : 
     231             :   // Define abbreviation for parent MapFieldLite
     232             :   typedef MapFieldLite<Key, T, kKeyFieldType, kValueFieldType,
     233             :                        default_enum_value> MapFieldLiteType;
     234             : 
     235             :   // Enum needs to be handled differently from other types because it has
     236             :   // different exposed type in google::protobuf::Map's api and repeated field's api. For
     237             :   // details see the comment in the implementation of
     238             :   // SyncMapWithRepeatedFieldNoLock.
     239             :   static const bool kIsValueEnum = ValueTypeHandler::kIsEnum;
     240             :   typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
     241             : 
     242             :  public:
     243             :   MapField();
     244             :   explicit MapField(Arena* arena);
     245             :   // MapField doesn't own the default_entry, which means default_entry must
     246             :   // outlive the lifetime of MapField.
     247             :   MapField(const Message* default_entry);
     248             :   // For tests only.
     249             :   MapField(Arena* arena, const Message* default_entry);
     250             :   ~MapField();
     251             : 
     252             :   // Implement MapFieldBase
     253             :   bool ContainsMapKey(const MapKey& map_key) const;
     254             :   bool InsertMapValue(const MapKey& map_key, MapValueRef* val);
     255             :   bool DeleteMapValue(const MapKey& map_key);
     256             : 
     257             :   // Accessors
     258             :   const Map<Key, T>& GetMap() const;
     259             :   Map<Key, T>* MutableMap();
     260             : 
     261             :   // Convenient methods for generated message implementation.
     262             :   int size() const;
     263             :   void Clear();
     264             :   void MergeFrom(const MapFieldLiteType& other);
     265             :   void Swap(MapFieldLiteType* other);
     266             : 
     267             :   // Allocates metadata only if this MapField is part of a generated message.
     268             :   void SetEntryDescriptor(const Descriptor** descriptor);
     269             :   void SetAssignDescriptorCallback(void (*callback)());
     270             : 
     271             :  private:
     272             :   typedef void InternalArenaConstructable_;
     273             :   typedef void DestructorSkippable_;
     274             : 
     275             :   // MapField needs MapEntry's default instance to create new MapEntry.
     276             :   void InitDefaultEntryOnce() const;
     277             : 
     278             :   // Manually set default entry instance. For test only.
     279             :   void SetDefaultEntryOnce(const EntryType* default_entry) const;
     280             : 
     281             :   // Convenient methods to get internal google::protobuf::Map
     282             :   const Map<Key, T>& GetInternalMap() const;
     283             :   Map<Key, T>* MutableInternalMap();
     284             : 
     285             :   // Implements MapFieldBase
     286             :   void SyncRepeatedFieldWithMapNoLock() const;
     287             :   void SyncMapWithRepeatedFieldNoLock() const;
     288             :   int SpaceUsedExcludingSelfNoLock() const;
     289             : 
     290             :   void SetMapIteratorValue(MapIterator* map_iter) const;
     291             : 
     292             :   mutable const EntryType* default_entry_;
     293             : 
     294             :   friend class ::google::protobuf::Arena;
     295             : };
     296             : 
     297             : class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase<MapKey, MapValueRef> {
     298             :  public:
     299             :   explicit DynamicMapField(const Message* default_entry);
     300             :   DynamicMapField(const Message* default_entry, Arena* arena);
     301             :   ~DynamicMapField();
     302             : 
     303             :   // Implement MapFieldBase
     304             :   bool ContainsMapKey(const MapKey& map_key) const;
     305             :   bool InsertMapValue(const MapKey& map_key, MapValueRef* val);
     306             :   bool DeleteMapValue(const MapKey& map_key);
     307             : 
     308             :   const Map<MapKey, MapValueRef>& GetMap() const;
     309             :   Map<MapKey, MapValueRef>* MutableMap();
     310             : 
     311             :   int size() const;
     312             : 
     313             :  private:
     314             :   Map<MapKey, MapValueRef> map_;
     315             :   const Message* default_entry_;
     316             : 
     317             :   // Implements MapFieldBase
     318             :   void SyncRepeatedFieldWithMapNoLock() const;
     319             :   void SyncMapWithRepeatedFieldNoLock() const;
     320             :   int SpaceUsedExcludingSelfNoLock() const;
     321             :   void SetMapIteratorValue(MapIterator* map_iter) const;
     322             : };
     323             : 
     324             : }  // namespace internal
     325             : 
     326             : class LIBPROTOBUF_EXPORT MapIterator {
     327             :  public:
     328           0 :   MapIterator(Message* message, const FieldDescriptor* field) {
     329           0 :     const Reflection* reflection = message->GetReflection();
     330           0 :     map_ = reflection->MapData(message, field);
     331           0 :     key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type());
     332           0 :     value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type());
     333           0 :     map_->InitializeIterator(this);
     334           0 :   }
     335             :   MapIterator(const MapIterator& other) {
     336             :     map_ = other.map_;
     337             :     map_->InitializeIterator(this);
     338             :     map_->CopyIterator(this, other);
     339             :   }
     340           0 :   ~MapIterator() {
     341           0 :     map_->DeleteIterator(this);
     342           0 :   }
     343             :   friend bool operator==(const MapIterator& a, const MapIterator& b) {
     344             :     return a.map_->EqualIterator(a, b);
     345             :   }
     346             :   friend bool operator!=(const MapIterator& a, const MapIterator& b) {
     347             :     return !a.map_->EqualIterator(a, b);
     348             :   }
     349             :   MapIterator& operator++() {
     350             :     map_->IncreaseIterator(this);
     351             :     return *this;
     352             :   }
     353             :   MapIterator operator++(int) {
     354             :     // iter_ is copied from Map<...>::iterator, no need to
     355             :     // copy from its self again. Use the same implementation
     356             :     // with operator++()
     357             :     map_->IncreaseIterator(this);
     358             :     return *this;
     359             :   }
     360             :   const MapKey& GetKey() {
     361             :     return key_;
     362             :   }
     363             :   const MapValueRef& GetValueRef() {
     364             :     return value_;
     365             :   }
     366             :   MapValueRef* MutableValueRef() {
     367             :     map_->SetMapDirty();
     368             :     return &value_;
     369             :   }
     370             : 
     371             :  private:
     372             :   template <typename Key, typename T>
     373             :   friend class internal::TypeDefinedMapFieldBase;
     374             :   friend class internal::DynamicMapField;
     375             :   template <typename Key, typename T,
     376             :             internal::WireFormatLite::FieldType kKeyFieldType,
     377             :             internal::WireFormatLite::FieldType kValueFieldType,
     378             :             int default_enum_value>
     379             :   friend class internal::MapField;
     380             : 
     381             :   // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns
     382             :   // the iterator. It is allocated by MapField<...>::InitializeIterator() called
     383             :   // in constructor and deleted by MapField<...>::DeleteIterator() called in
     384             :   // destructor.
     385             :   void* iter_;
     386             :   // Point to a MapField to call helper methods implemented in MapField.
     387             :   // MapIterator does not own this object.
     388             :   internal::MapFieldBase* map_;
     389             :   MapKey key_;
     390             :   MapValueRef value_;
     391             : };
     392             : 
     393             : }  // namespace protobuf
     394             : 
     395             : }  // namespace google
     396             : #endif  // GOOGLE_PROTOBUF_MAP_FIELD_H__

Generated by: LCOV version 1.10