diff options
Diffstat (limited to 'src/google/protobuf/map_field_inl.h')
-rw-r--r-- | src/google/protobuf/map_field_inl.h | 231 |
1 files changed, 204 insertions, 27 deletions
diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h index 5b4305f9..1a4ce937 100644 --- a/src/google/protobuf/map_field_inl.h +++ b/src/google/protobuf/map_field_inl.h @@ -36,12 +36,128 @@ #include <google/protobuf/stubs/shared_ptr.h> #endif +#include <google/protobuf/map.h> #include <google/protobuf/map_field.h> #include <google/protobuf/map_type_handler.h> namespace google { namespace protobuf { namespace internal { +// UnwrapMapKey template +template<typename T> +T UnwrapMapKey(const MapKey& map_key); +template<> +inline int32 UnwrapMapKey<int32>(const MapKey& map_key) { + return map_key.GetInt32Value(); +} +template<> +inline uint32 UnwrapMapKey<uint32>(const MapKey& map_key) { + return map_key.GetUInt32Value(); +} +template<> +inline int64 UnwrapMapKey<int64>(const MapKey& map_key) { + return map_key.GetInt64Value(); +} +template<> +inline uint64 UnwrapMapKey<uint64>(const MapKey& map_key) { + return map_key.GetUInt64Value(); +} +template<> +inline bool UnwrapMapKey<bool>(const MapKey& map_key) { + return map_key.GetBoolValue(); +} +template<> +inline string UnwrapMapKey<string>(const MapKey& map_key) { + return map_key.GetStringValue(); +} + +// SetMapKey template +template<typename T> +inline void SetMapKey(MapKey* map_key, const T& value); +template<> +inline void SetMapKey<int32>(MapKey* map_key, const int32& value) { + map_key->SetInt32Value(value); +} +template<> +inline void SetMapKey<uint32>(MapKey* map_key, const uint32& value) { + map_key->SetUInt32Value(value); +} +template<> +inline void SetMapKey<int64>(MapKey* map_key, const int64& value) { + map_key->SetInt64Value(value); +} +template<> +inline void SetMapKey<uint64>(MapKey* map_key, const uint64& value) { + map_key->SetUInt64Value(value); +} +template<> +inline void SetMapKey<bool>(MapKey* map_key, const bool& value) { + map_key->SetBoolValue(value); +} +template<> +inline void SetMapKey<string>(MapKey* map_key, const string& value) { + map_key->SetStringValue(value); +} + +// ------------------------TypeDefinedMapFieldBase--------------- +template <typename Key, typename T> +typename Map<Key, T>::const_iterator& +TypeDefinedMapFieldBase<Key, T>::InternalGetIterator( + const MapIterator* map_iter) const { + return *reinterpret_cast<typename Map<Key, T>::const_iterator *>( + map_iter->iter_); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::MapBegin(MapIterator* map_iter) const { + InternalGetIterator(map_iter) = GetMap().begin(); + SetMapIteratorValue(map_iter); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::MapEnd(MapIterator* map_iter) const { + InternalGetIterator(map_iter) = GetMap().end(); +} + +template <typename Key, typename T> +bool TypeDefinedMapFieldBase<Key, T>::EqualIterator(const MapIterator& a, + const MapIterator& b) + const { + return InternalGetIterator(&a) == InternalGetIterator(&b); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::IncreaseIterator(MapIterator* map_iter) + const { + ++InternalGetIterator(map_iter); + SetMapIteratorValue(map_iter); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::InitializeIterator( + MapIterator* map_iter) const { + map_iter->iter_ = new typename Map<Key, T>::const_iterator; + GOOGLE_CHECK(map_iter->iter_ != NULL); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::DeleteIterator(MapIterator* map_iter) + const { + delete reinterpret_cast<typename Map<Key, T>::const_iterator *>( + map_iter->iter_); +} + +template <typename Key, typename T> +void TypeDefinedMapFieldBase<Key, T>::CopyIterator( + MapIterator* this_iter, + const MapIterator& that_iter) const { + InternalGetIterator(this_iter) = InternalGetIterator(&that_iter); + this_iter->key_.SetType(that_iter.key_.type()); + this_iter->value_.SetType(that_iter.value_.type()); + SetMapIteratorValue(this_iter); +} + +// ---------------------------------------------------------------------- template <typename Key, typename T, WireFormatLite::FieldType kKeyFieldType, @@ -56,7 +172,7 @@ template <typename Key, typename T, int default_enum_value> MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField( Arena* arena) - : MapFieldBase(arena), + : TypeDefinedMapFieldBase<Key, T>(arena), MapFieldLite<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>( arena), default_entry_(NULL) {} @@ -75,7 +191,7 @@ template <typename Key, typename T, int default_enum_value> MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField( Arena* arena, const Message* default_entry) - : MapFieldBase(arena), + : TypeDefinedMapFieldBase<Key, T>(arena), MapFieldLite<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>( arena), default_entry_(down_cast<const EntryType*>(default_entry)) {} @@ -94,7 +210,7 @@ template <typename Key, typename T, int MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::size() const { - SyncMapWithRepeatedField(); + MapFieldBase::SyncMapWithRepeatedField(); return MapFieldLiteType::GetInternalMap().size(); } @@ -105,9 +221,65 @@ template <typename Key, typename T, void MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::Clear() { - SyncMapWithRepeatedField(); + MapFieldBase::SyncMapWithRepeatedField(); MapFieldLiteType::MutableInternalMap()->clear(); - SetMapDirty(); + MapFieldBase::SetMapDirty(); +} + +template <typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType, + int default_enum_value> +void MapField<Key, T, kKeyFieldType, kValueFieldType, + default_enum_value>::SetMapIteratorValue( + MapIterator* map_iter) const { + const Map<Key, T>& map = GetMap(); + typename Map<Key, T>::const_iterator iter = + TypeDefinedMapFieldBase<Key, T>::InternalGetIterator(map_iter); + if (iter == map.end()) return; + SetMapKey(&map_iter->key_, iter->first); + map_iter->value_.SetValue(&iter->second); +} + +template <typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType, + int default_enum_value> +bool MapField<Key, T, kKeyFieldType, kValueFieldType, + default_enum_value>::ContainsMapKey( + const MapKey& map_key) const { + const Map<Key, T>& map = GetMap(); + const Key& key = UnwrapMapKey<Key>(map_key); + typename Map<Key, T>::const_iterator iter = map.find(key); + return iter != map.end(); +} + +template <typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType, + int default_enum_value> +bool MapField<Key, T, kKeyFieldType, kValueFieldType, + default_enum_value>::InsertMapValue(const MapKey& map_key, + MapValueRef* val) { + Map<Key, T>* map = MutableMap(); + bool result = false; + const Key& key = UnwrapMapKey<Key>(map_key); + if (map->end() == map->find(key)) { + result = true; + } + val->SetValue(&((*map)[key])); + return result; +} + +template <typename Key, typename T, + WireFormatLite::FieldType kKeyFieldType, + WireFormatLite::FieldType kValueFieldType, + int default_enum_value> +bool MapField<Key, T, kKeyFieldType, kValueFieldType, + default_enum_value>::DeleteMapValue( + const MapKey& map_key) { + const Key& key = UnwrapMapKey<Key>(map_key); + return MutableMap()->erase(key); } template <typename Key, typename T, @@ -117,7 +289,7 @@ template <typename Key, typename T, const Map<Key, T>& MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::GetMap() const { - SyncMapWithRepeatedField(); + MapFieldBase::SyncMapWithRepeatedField(); return MapFieldLiteType::GetInternalMap(); } @@ -128,9 +300,9 @@ template <typename Key, typename T, Map<Key, T>* MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MutableMap() { - SyncMapWithRepeatedField(); + MapFieldBase::SyncMapWithRepeatedField(); Map<Key, T>* result = MapFieldLiteType::MutableInternalMap(); - SetMapDirty(); + MapFieldBase::SetMapDirty(); return result; } @@ -143,10 +315,10 @@ MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MergeFrom( const MapFieldLiteType& other) { const MapField& down_other = down_cast<const MapField&>(other); - SyncMapWithRepeatedField(); + MapFieldBase::SyncMapWithRepeatedField(); down_other.SyncMapWithRepeatedField(); MapFieldLiteType::MergeFrom(other); - SetMapDirty(); + MapFieldBase::SetMapDirty(); } template <typename Key, typename T, @@ -158,9 +330,9 @@ MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::Swap( MapFieldLiteType* other) { MapField* down_other = down_cast<MapField*>(other); - std::swap(repeated_field_, down_other->repeated_field_); + std::swap(MapFieldBase::repeated_field_, down_other->repeated_field_); MapFieldLiteType::Swap(other); - std::swap(state_, down_other->state_); + std::swap(MapFieldBase::state_, down_other->state_); } template <typename Key, typename T, @@ -171,7 +343,7 @@ void MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::SetEntryDescriptor( const Descriptor** descriptor) { - entry_descriptor_ = descriptor; + MapFieldBase::entry_descriptor_ = descriptor; } template <typename Key, typename T, @@ -181,7 +353,7 @@ template <typename Key, typename T, void MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::SetAssignDescriptorCallback(void (*callback)()) { - assign_descriptor_callback_ = callback; + MapFieldBase::assign_descriptor_callback_ = callback; } template <typename Key, typename T, @@ -211,17 +383,19 @@ template <typename Key, typename T, void MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::SyncRepeatedFieldWithMapNoLock() const { - if (repeated_field_ == NULL) { + if (MapFieldBase::repeated_field_ == NULL) { if (MapFieldBase::arena_ == NULL) { - repeated_field_ = new RepeatedPtrField<Message>(); + MapFieldBase::repeated_field_ = new RepeatedPtrField<Message>(); } else { - repeated_field_ = Arena::CreateMessage<RepeatedPtrField<Message> >( - MapFieldBase::arena_); + MapFieldBase::repeated_field_ = + Arena::CreateMessage<RepeatedPtrField<Message> >( + MapFieldBase::arena_); } } const Map<Key, T>& map = GetInternalMap(); RepeatedPtrField<EntryType>* repeated_field = - reinterpret_cast<RepeatedPtrField<EntryType>*>(repeated_field_); + reinterpret_cast<RepeatedPtrField<EntryType>*>( + MapFieldBase::repeated_field_); repeated_field->Clear(); @@ -246,7 +420,9 @@ MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::SyncMapWithRepeatedFieldNoLock() const { Map<Key, T>* map = const_cast<MapField*>(this)->MutableInternalMap(); RepeatedPtrField<EntryType>* repeated_field = - reinterpret_cast<RepeatedPtrField<EntryType>*>(repeated_field_); + reinterpret_cast<RepeatedPtrField<EntryType>*>( + MapFieldBase::repeated_field_); + GOOGLE_CHECK(MapFieldBase::repeated_field_ != NULL); map->clear(); for (typename RepeatedPtrField<EntryType>::iterator it = repeated_field->begin(); it != repeated_field->end(); ++it) { @@ -267,15 +443,15 @@ int MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::SpaceUsedExcludingSelfNoLock() const { int size = 0; - if (repeated_field_ != NULL) { - size += repeated_field_->SpaceUsedExcludingSelf(); + if (MapFieldBase::repeated_field_ != NULL) { + size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelf(); } Map<Key, T>* map = const_cast<MapField*>(this)->MutableInternalMap(); size += sizeof(*map); for (typename Map<Key, T>::iterator it = map->begin(); it != map->end(); ++it) { - size += KeyHandler::SpaceUsedInMap(it->first); - size += ValHandler::SpaceUsedInMap(it->second); + size += KeyTypeHandler::SpaceUsedInMap(it->first); + size += ValueTypeHandler::SpaceUsedInMap(it->second); } return size; } @@ -289,10 +465,11 @@ MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::InitDefaultEntryOnce() const { if (default_entry_ == NULL) { - InitMetadataOnce(); - GOOGLE_CHECK(*entry_descriptor_ != NULL); + MapFieldBase::InitMetadataOnce(); + GOOGLE_CHECK(*MapFieldBase::entry_descriptor_ != NULL); default_entry_ = down_cast<const EntryType*>( - MessageFactory::generated_factory()->GetPrototype(*entry_descriptor_)); + MessageFactory::generated_factory()->GetPrototype( + *MapFieldBase::entry_descriptor_)); } } |