blob: f116697c4342c72d73d3e588a81ef9156de28467 [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// 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_INL_H__
32#define GOOGLE_PROTOBUF_MAP_FIELD_INL_H__
33
34#include <memory>
35#ifndef _SHARED_PTR_H
36#include <google/protobuf/stubs/shared_ptr.h>
37#endif
38
39#include <google/protobuf/map.h>
40#include <google/protobuf/map_field.h>
41#include <google/protobuf/map_type_handler.h>
42
43namespace google {
44namespace protobuf {
45namespace internal {
46// UnwrapMapKey template
47template<typename T>
48T UnwrapMapKey(const MapKey& map_key);
49template<>
50inline int32 UnwrapMapKey<int32>(const MapKey& map_key) {
51 return map_key.GetInt32Value();
52}
53template<>
54inline uint32 UnwrapMapKey<uint32>(const MapKey& map_key) {
55 return map_key.GetUInt32Value();
56}
57template<>
58inline int64 UnwrapMapKey<int64>(const MapKey& map_key) {
59 return map_key.GetInt64Value();
60}
61template<>
62inline uint64 UnwrapMapKey<uint64>(const MapKey& map_key) {
63 return map_key.GetUInt64Value();
64}
65template<>
66inline bool UnwrapMapKey<bool>(const MapKey& map_key) {
67 return map_key.GetBoolValue();
68}
69template<>
70inline string UnwrapMapKey<string>(const MapKey& map_key) {
71 return map_key.GetStringValue();
72}
73
74// SetMapKey template
75template<typename T>
76inline void SetMapKey(MapKey* map_key, const T& value);
77template<>
78inline void SetMapKey<int32>(MapKey* map_key, const int32& value) {
79 map_key->SetInt32Value(value);
80}
81template<>
82inline void SetMapKey<uint32>(MapKey* map_key, const uint32& value) {
83 map_key->SetUInt32Value(value);
84}
85template<>
86inline void SetMapKey<int64>(MapKey* map_key, const int64& value) {
87 map_key->SetInt64Value(value);
88}
89template<>
90inline void SetMapKey<uint64>(MapKey* map_key, const uint64& value) {
91 map_key->SetUInt64Value(value);
92}
93template<>
94inline void SetMapKey<bool>(MapKey* map_key, const bool& value) {
95 map_key->SetBoolValue(value);
96}
97template<>
98inline void SetMapKey<string>(MapKey* map_key, const string& value) {
99 map_key->SetStringValue(value);
100}
101
102// ------------------------TypeDefinedMapFieldBase---------------
103template <typename Key, typename T>
104typename Map<Key, T>::const_iterator&
105TypeDefinedMapFieldBase<Key, T>::InternalGetIterator(
106 const MapIterator* map_iter) const {
107 return *reinterpret_cast<typename Map<Key, T>::const_iterator *>(
108 map_iter->iter_);
109}
110
111template <typename Key, typename T>
112void TypeDefinedMapFieldBase<Key, T>::MapBegin(MapIterator* map_iter) const {
113 InternalGetIterator(map_iter) = GetMap().begin();
114 SetMapIteratorValue(map_iter);
115}
116
117template <typename Key, typename T>
118void TypeDefinedMapFieldBase<Key, T>::MapEnd(MapIterator* map_iter) const {
119 InternalGetIterator(map_iter) = GetMap().end();
120}
121
122template <typename Key, typename T>
123bool TypeDefinedMapFieldBase<Key, T>::EqualIterator(const MapIterator& a,
124 const MapIterator& b)
125 const {
126 return InternalGetIterator(&a) == InternalGetIterator(&b);
127}
128
129template <typename Key, typename T>
130void TypeDefinedMapFieldBase<Key, T>::IncreaseIterator(MapIterator* map_iter)
131 const {
132 ++InternalGetIterator(map_iter);
133 SetMapIteratorValue(map_iter);
134}
135
136template <typename Key, typename T>
137void TypeDefinedMapFieldBase<Key, T>::InitializeIterator(
138 MapIterator* map_iter) const {
139 map_iter->iter_ = new typename Map<Key, T>::const_iterator;
140 GOOGLE_CHECK(map_iter->iter_ != NULL);
141}
142
143template <typename Key, typename T>
144void TypeDefinedMapFieldBase<Key, T>::DeleteIterator(MapIterator* map_iter)
145 const {
146 delete reinterpret_cast<typename Map<Key, T>::const_iterator *>(
147 map_iter->iter_);
148}
149
150template <typename Key, typename T>
151void TypeDefinedMapFieldBase<Key, T>::CopyIterator(
152 MapIterator* this_iter,
153 const MapIterator& that_iter) const {
154 InternalGetIterator(this_iter) = InternalGetIterator(&that_iter);
155 this_iter->key_.SetType(that_iter.key_.type());
156 // MapValueRef::type() fails when containing data is null. However, if
157 // this_iter points to MapEnd, data can be null.
158 this_iter->value_.SetType(
159 static_cast<FieldDescriptor::CppType>(that_iter.value_.type_));
160 SetMapIteratorValue(this_iter);
161}
162
163// ----------------------------------------------------------------------
164
165template <typename Key, typename T,
166 WireFormatLite::FieldType kKeyFieldType,
167 WireFormatLite::FieldType kValueFieldType,
168 int default_enum_value>
169MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField()
170 : default_entry_(NULL) {}
171
172template <typename Key, typename T,
173 WireFormatLite::FieldType kKeyFieldType,
174 WireFormatLite::FieldType kValueFieldType,
175 int default_enum_value>
176MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField(
177 Arena* arena)
178 : TypeDefinedMapFieldBase<Key, T>(arena),
179 MapFieldLite<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>(
180 arena),
181 default_entry_(NULL) {}
182
183template <typename Key, typename T,
184 WireFormatLite::FieldType kKeyFieldType,
185 WireFormatLite::FieldType kValueFieldType,
186 int default_enum_value>
187MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField(
188 const Message* default_entry)
189 : default_entry_(down_cast<const EntryType*>(default_entry)) {}
190
191template <typename Key, typename T,
192 WireFormatLite::FieldType kKeyFieldType,
193 WireFormatLite::FieldType kValueFieldType,
194 int default_enum_value>
195MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField(
196 Arena* arena, const Message* default_entry)
197 : TypeDefinedMapFieldBase<Key, T>(arena),
198 MapFieldLite<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>(
199 arena),
200 default_entry_(down_cast<const EntryType*>(default_entry)) {}
201
202template <typename Key, typename T,
203 WireFormatLite::FieldType kKeyFieldType,
204 WireFormatLite::FieldType kValueFieldType,
205 int default_enum_value>
206MapField<Key, T, kKeyFieldType, kValueFieldType,
207 default_enum_value>::~MapField() {}
208
209template <typename Key, typename T,
210 WireFormatLite::FieldType kKeyFieldType,
211 WireFormatLite::FieldType kValueFieldType,
212 int default_enum_value>
213int
214MapField<Key, T, kKeyFieldType, kValueFieldType,
215 default_enum_value>::size() const {
216 MapFieldBase::SyncMapWithRepeatedField();
217 return MapFieldLiteType::GetInternalMap().size();
218}
219
220template <typename Key, typename T,
221 WireFormatLite::FieldType kKeyFieldType,
222 WireFormatLite::FieldType kValueFieldType,
223 int default_enum_value>
224void
225MapField<Key, T, kKeyFieldType, kValueFieldType,
226 default_enum_value>::Clear() {
227 MapFieldBase::SyncMapWithRepeatedField();
228 MapFieldLiteType::MutableInternalMap()->clear();
229 MapFieldBase::SetMapDirty();
230}
231
232template <typename Key, typename T,
233 WireFormatLite::FieldType kKeyFieldType,
234 WireFormatLite::FieldType kValueFieldType,
235 int default_enum_value>
236void MapField<Key, T, kKeyFieldType, kValueFieldType,
237 default_enum_value>::SetMapIteratorValue(
238 MapIterator* map_iter) const {
239 const Map<Key, T>& map = GetMap();
240 typename Map<Key, T>::const_iterator iter =
241 TypeDefinedMapFieldBase<Key, T>::InternalGetIterator(map_iter);
242 if (iter == map.end()) return;
243 SetMapKey(&map_iter->key_, iter->first);
244 map_iter->value_.SetValue(&iter->second);
245}
246
247template <typename Key, typename T,
248 WireFormatLite::FieldType kKeyFieldType,
249 WireFormatLite::FieldType kValueFieldType,
250 int default_enum_value>
251bool MapField<Key, T, kKeyFieldType, kValueFieldType,
252 default_enum_value>::ContainsMapKey(
253 const MapKey& map_key) const {
254 const Map<Key, T>& map = GetMap();
255 const Key& key = UnwrapMapKey<Key>(map_key);
256 typename Map<Key, T>::const_iterator iter = map.find(key);
257 return iter != map.end();
258}
259
260template <typename Key, typename T,
261 WireFormatLite::FieldType kKeyFieldType,
262 WireFormatLite::FieldType kValueFieldType,
263 int default_enum_value>
264bool MapField<Key, T, kKeyFieldType, kValueFieldType,
265 default_enum_value>::InsertMapValue(const MapKey& map_key,
266 MapValueRef* val) {
267 Map<Key, T>* map = MutableMap();
268 bool result = false;
269 const Key& key = UnwrapMapKey<Key>(map_key);
270 if (map->end() == map->find(key)) {
271 result = true;
272 }
273 val->SetValue(&((*map)[key]));
274 return result;
275}
276
277template <typename Key, typename T,
278 WireFormatLite::FieldType kKeyFieldType,
279 WireFormatLite::FieldType kValueFieldType,
280 int default_enum_value>
281bool MapField<Key, T, kKeyFieldType, kValueFieldType,
282 default_enum_value>::DeleteMapValue(
283 const MapKey& map_key) {
284 const Key& key = UnwrapMapKey<Key>(map_key);
285 return MutableMap()->erase(key);
286}
287
288template <typename Key, typename T,
289 WireFormatLite::FieldType kKeyFieldType,
290 WireFormatLite::FieldType kValueFieldType,
291 int default_enum_value>
292const Map<Key, T>&
293MapField<Key, T, kKeyFieldType, kValueFieldType,
294 default_enum_value>::GetMap() const {
295 MapFieldBase::SyncMapWithRepeatedField();
296 return MapFieldLiteType::GetInternalMap();
297}
298
299template <typename Key, typename T,
300 WireFormatLite::FieldType kKeyFieldType,
301 WireFormatLite::FieldType kValueFieldType,
302 int default_enum_value>
303Map<Key, T>*
304MapField<Key, T, kKeyFieldType, kValueFieldType,
305 default_enum_value>::MutableMap() {
306 MapFieldBase::SyncMapWithRepeatedField();
307 Map<Key, T>* result = MapFieldLiteType::MutableInternalMap();
308 MapFieldBase::SetMapDirty();
309 return result;
310}
311
312template <typename Key, typename T,
313 WireFormatLite::FieldType kKeyFieldType,
314 WireFormatLite::FieldType kValueFieldType,
315 int default_enum_value>
316void
317MapField<Key, T, kKeyFieldType, kValueFieldType,
318 default_enum_value>::MergeFrom(
319 const MapFieldLiteType& other) {
320 const MapField& down_other = down_cast<const MapField&>(other);
321 MapFieldBase::SyncMapWithRepeatedField();
322 down_other.SyncMapWithRepeatedField();
323 MapFieldLiteType::MergeFrom(other);
324 MapFieldBase::SetMapDirty();
325}
326
327template <typename Key, typename T,
328 WireFormatLite::FieldType kKeyFieldType,
329 WireFormatLite::FieldType kValueFieldType,
330 int default_enum_value>
331void
332MapField<Key, T, kKeyFieldType, kValueFieldType,
333 default_enum_value>::Swap(
334 MapFieldLiteType* other) {
335 MapField* down_other = down_cast<MapField*>(other);
336 std::swap(MapFieldBase::repeated_field_, down_other->repeated_field_);
337 MapFieldLiteType::Swap(other);
338 std::swap(MapFieldBase::state_, down_other->state_);
339}
340
341template <typename Key, typename T,
342 WireFormatLite::FieldType kKeyFieldType,
343 WireFormatLite::FieldType kValueFieldType,
344 int default_enum_value>
345void
346MapField<Key, T, kKeyFieldType, kValueFieldType,
347 default_enum_value>::SetEntryDescriptor(
348 const Descriptor** descriptor) {
349 MapFieldBase::entry_descriptor_ = descriptor;
350}
351
352template <typename Key, typename T,
353 WireFormatLite::FieldType kKeyFieldType,
354 WireFormatLite::FieldType kValueFieldType,
355 int default_enum_value>
356void
357MapField<Key, T, kKeyFieldType, kValueFieldType,
358 default_enum_value>::SetAssignDescriptorCallback(void (*callback)()) {
359 MapFieldBase::assign_descriptor_callback_ = callback;
360}
361
362template <typename Key, typename T,
363 WireFormatLite::FieldType kKeyFieldType,
364 WireFormatLite::FieldType kValueFieldType,
365 int default_enum_value>
366const Map<Key, T>&
367MapField<Key, T, kKeyFieldType, kValueFieldType,
368 default_enum_value>::GetInternalMap() const {
369 return MapFieldLiteType::GetInternalMap();
370}
371
372template <typename Key, typename T,
373 WireFormatLite::FieldType kKeyFieldType,
374 WireFormatLite::FieldType kValueFieldType,
375 int default_enum_value>
376Map<Key, T>*
377MapField<Key, T, kKeyFieldType, kValueFieldType,
378 default_enum_value>::MutableInternalMap() {
379 return MapFieldLiteType::MutableInternalMap();
380}
381
382template <typename Key, typename T,
383 WireFormatLite::FieldType kKeyFieldType,
384 WireFormatLite::FieldType kValueFieldType,
385 int default_enum_value>
386void
387MapField<Key, T, kKeyFieldType, kValueFieldType,
388 default_enum_value>::SyncRepeatedFieldWithMapNoLock() const {
389 if (MapFieldBase::repeated_field_ == NULL) {
390 if (MapFieldBase::arena_ == NULL) {
391 MapFieldBase::repeated_field_ = new RepeatedPtrField<Message>();
392 } else {
393 MapFieldBase::repeated_field_ =
394 Arena::CreateMessage<RepeatedPtrField<Message> >(
395 MapFieldBase::arena_);
396 }
397 }
398 const Map<Key, T>& map = GetInternalMap();
399 RepeatedPtrField<EntryType>* repeated_field =
400 reinterpret_cast<RepeatedPtrField<EntryType>*>(
401 MapFieldBase::repeated_field_);
402
403 repeated_field->Clear();
404
405 for (typename Map<Key, T>::const_iterator it = map.begin();
406 it != map.end(); ++it) {
407 InitDefaultEntryOnce();
408 GOOGLE_CHECK(default_entry_ != NULL);
409 EntryType* new_entry =
410 down_cast<EntryType*>(default_entry_->New(MapFieldBase::arena_));
411 repeated_field->AddAllocated(new_entry);
412 (*new_entry->mutable_key()) = it->first;
413 (*new_entry->mutable_value()) = it->second;
414 }
415}
416
417template <typename Key, typename T,
418 WireFormatLite::FieldType kKeyFieldType,
419 WireFormatLite::FieldType kValueFieldType,
420 int default_enum_value>
421void
422MapField<Key, T, kKeyFieldType, kValueFieldType,
423 default_enum_value>::SyncMapWithRepeatedFieldNoLock() const {
424 Map<Key, T>* map = const_cast<MapField*>(this)->MutableInternalMap();
425 RepeatedPtrField<EntryType>* repeated_field =
426 reinterpret_cast<RepeatedPtrField<EntryType>*>(
427 MapFieldBase::repeated_field_);
428 GOOGLE_CHECK(MapFieldBase::repeated_field_ != NULL);
429 map->clear();
430 for (typename RepeatedPtrField<EntryType>::iterator it =
431 repeated_field->begin(); it != repeated_field->end(); ++it) {
432 // Cast is needed because Map's api and internal storage is different when
433 // value is enum. For enum, we cannot cast an int to enum. Thus, we have to
434 // copy value. For other types, they have same exposed api type and internal
435 // stored type. We should not introduce value copy for them. We achieve this
436 // by casting to value for enum while casting to reference for other types.
437 (*map)[it->key()] = static_cast<CastValueType>(it->value());
438 }
439}
440
441template <typename Key, typename T,
442 WireFormatLite::FieldType kKeyFieldType,
443 WireFormatLite::FieldType kValueFieldType,
444 int default_enum_value>
445int
446MapField<Key, T, kKeyFieldType, kValueFieldType,
447 default_enum_value>::SpaceUsedExcludingSelfNoLock() const {
448 int size = 0;
449 if (MapFieldBase::repeated_field_ != NULL) {
450 size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelf();
451 }
452 Map<Key, T>* map = const_cast<MapField*>(this)->MutableInternalMap();
453 size += sizeof(*map);
454 for (typename Map<Key, T>::iterator it = map->begin();
455 it != map->end(); ++it) {
456 size += KeyTypeHandler::SpaceUsedInMap(it->first);
457 size += ValueTypeHandler::SpaceUsedInMap(it->second);
458 }
459 return size;
460}
461
462template <typename Key, typename T,
463 WireFormatLite::FieldType kKeyFieldType,
464 WireFormatLite::FieldType kValueFieldType,
465 int default_enum_value>
466void
467MapField<Key, T, kKeyFieldType, kValueFieldType,
468 default_enum_value>::InitDefaultEntryOnce()
469 const {
470 if (default_entry_ == NULL) {
471 MapFieldBase::InitMetadataOnce();
472 GOOGLE_CHECK(*MapFieldBase::entry_descriptor_ != NULL);
473 default_entry_ = down_cast<const EntryType*>(
474 MessageFactory::generated_factory()->GetPrototype(
475 *MapFieldBase::entry_descriptor_));
476 }
477}
478
479} // namespace internal
480} // namespace protobuf
481
482} // namespace google
483#endif // GOOGLE_PROTOBUF_MAP_FIELD_INL_H__