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_INL_H__ |
32 | #define GOOGLE_PROTOBUF_MAP_FIELD_INL_H__ |
33 | |
34 | #include <memory> |
35 | |
36 | #include <google/protobuf/stubs/casts.h> |
37 | #include <google/protobuf/map.h> |
38 | #include <google/protobuf/map_field.h> |
39 | #include <google/protobuf/map_type_handler.h> |
40 | |
41 | #ifdef SWIG |
42 | #error "You cannot SWIG proto headers" |
43 | #endif |
44 | |
45 | namespace google { |
46 | namespace protobuf { |
47 | namespace internal { |
48 | // UnwrapMapKey template |
49 | template <typename T> |
50 | T UnwrapMapKey(const MapKey& map_key); |
51 | template <> |
52 | inline int32_t UnwrapMapKey<int32_t>(const MapKey& map_key) { |
53 | return map_key.GetInt32Value(); |
54 | } |
55 | template <> |
56 | inline uint32_t UnwrapMapKey<uint32_t>(const MapKey& map_key) { |
57 | return map_key.GetUInt32Value(); |
58 | } |
59 | template <> |
60 | inline int64_t UnwrapMapKey<int64_t>(const MapKey& map_key) { |
61 | return map_key.GetInt64Value(); |
62 | } |
63 | template <> |
64 | inline uint64_t UnwrapMapKey<uint64_t>(const MapKey& map_key) { |
65 | return map_key.GetUInt64Value(); |
66 | } |
67 | template <> |
68 | inline bool UnwrapMapKey<bool>(const MapKey& map_key) { |
69 | return map_key.GetBoolValue(); |
70 | } |
71 | template <> |
72 | inline std::string UnwrapMapKey<std::string>(const MapKey& map_key) { |
73 | return map_key.GetStringValue(); |
74 | } |
75 | |
76 | // SetMapKey template |
77 | template <typename T> |
78 | inline void SetMapKey(MapKey* map_key, const T& value); |
79 | template <> |
80 | inline void SetMapKey<int32_t>(MapKey* map_key, const int32_t& value) { |
81 | map_key->SetInt32Value(value); |
82 | } |
83 | template <> |
84 | inline void SetMapKey<uint32_t>(MapKey* map_key, const uint32_t& value) { |
85 | map_key->SetUInt32Value(value); |
86 | } |
87 | template <> |
88 | inline void SetMapKey<int64_t>(MapKey* map_key, const int64_t& value) { |
89 | map_key->SetInt64Value(value); |
90 | } |
91 | template <> |
92 | inline void SetMapKey<uint64_t>(MapKey* map_key, const uint64_t& value) { |
93 | map_key->SetUInt64Value(value); |
94 | } |
95 | template <> |
96 | inline void SetMapKey<bool>(MapKey* map_key, const bool& value) { |
97 | map_key->SetBoolValue(value); |
98 | } |
99 | template <> |
100 | inline void SetMapKey<std::string>(MapKey* map_key, const std::string& value) { |
101 | map_key->SetStringValue(value); |
102 | } |
103 | |
104 | // ------------------------TypeDefinedMapFieldBase--------------- |
105 | template <typename Key, typename T> |
106 | typename Map<Key, T>::const_iterator& |
107 | TypeDefinedMapFieldBase<Key, T>::InternalGetIterator( |
108 | const MapIterator* map_iter) const { |
109 | return *reinterpret_cast<typename Map<Key, T>::const_iterator*>( |
110 | map_iter->iter_); |
111 | } |
112 | |
113 | template <typename Key, typename T> |
114 | void TypeDefinedMapFieldBase<Key, T>::MapBegin(MapIterator* map_iter) const { |
115 | InternalGetIterator(map_iter) = GetMap().begin(); |
116 | SetMapIteratorValue(map_iter); |
117 | } |
118 | |
119 | template <typename Key, typename T> |
120 | void TypeDefinedMapFieldBase<Key, T>::MapEnd(MapIterator* map_iter) const { |
121 | InternalGetIterator(map_iter) = GetMap().end(); |
122 | } |
123 | |
124 | template <typename Key, typename T> |
125 | bool TypeDefinedMapFieldBase<Key, T>::EqualIterator( |
126 | const MapIterator& a, const MapIterator& b) const { |
127 | return InternalGetIterator(map_iter: &a) == InternalGetIterator(map_iter: &b); |
128 | } |
129 | |
130 | template <typename Key, typename T> |
131 | void TypeDefinedMapFieldBase<Key, T>::IncreaseIterator( |
132 | MapIterator* map_iter) const { |
133 | ++InternalGetIterator(map_iter); |
134 | SetMapIteratorValue(map_iter); |
135 | } |
136 | |
137 | template <typename Key, typename T> |
138 | void TypeDefinedMapFieldBase<Key, T>::InitializeIterator( |
139 | MapIterator* map_iter) const { |
140 | map_iter->iter_ = new typename Map<Key, T>::const_iterator; |
141 | GOOGLE_CHECK(map_iter->iter_ != nullptr); |
142 | } |
143 | |
144 | template <typename Key, typename T> |
145 | void TypeDefinedMapFieldBase<Key, T>::DeleteIterator( |
146 | MapIterator* map_iter) const { |
147 | delete reinterpret_cast<typename Map<Key, T>::const_iterator*>( |
148 | map_iter->iter_); |
149 | } |
150 | |
151 | template <typename Key, typename T> |
152 | void TypeDefinedMapFieldBase<Key, T>::CopyIterator( |
153 | MapIterator* this_iter, const MapIterator& that_iter) const { |
154 | InternalGetIterator(map_iter: this_iter) = InternalGetIterator(map_iter: &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 | |
165 | template <typename Derived, typename Key, typename T, |
166 | WireFormatLite::FieldType kKeyFieldType, |
167 | WireFormatLite::FieldType kValueFieldType> |
168 | int MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::size() const { |
169 | MapFieldBase::SyncMapWithRepeatedField(); |
170 | return static_cast<int>(impl_.GetMap().size()); |
171 | } |
172 | |
173 | template <typename Derived, typename Key, typename T, |
174 | WireFormatLite::FieldType kKeyFieldType, |
175 | WireFormatLite::FieldType kValueFieldType> |
176 | void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::Clear() { |
177 | if (this->MapFieldBase::repeated_field_ != nullptr) { |
178 | RepeatedPtrField<EntryType>* repeated_field = |
179 | reinterpret_cast<RepeatedPtrField<EntryType>*>( |
180 | this->MapFieldBase::repeated_field_); |
181 | repeated_field->Clear(); |
182 | } |
183 | |
184 | impl_.MutableMap()->clear(); |
185 | // Data in map and repeated field are both empty, but we can't set status |
186 | // CLEAN. Because clear is a generated API, we cannot invalidate previous |
187 | // reference to map. |
188 | MapFieldBase::SetMapDirty(); |
189 | } |
190 | |
191 | template <typename Derived, typename Key, typename T, |
192 | WireFormatLite::FieldType kKeyFieldType, |
193 | WireFormatLite::FieldType kValueFieldType> |
194 | void MapField<Derived, Key, T, kKeyFieldType, |
195 | kValueFieldType>::SetMapIteratorValue(MapIterator* map_iter) |
196 | const { |
197 | const Map<Key, T>& map = impl_.GetMap(); |
198 | typename Map<Key, T>::const_iterator iter = |
199 | TypeDefinedMapFieldBase<Key, T>::InternalGetIterator(map_iter); |
200 | if (iter == map.end()) return; |
201 | SetMapKey(&map_iter->key_, iter->first); |
202 | map_iter->value_.SetValue(&iter->second); |
203 | } |
204 | |
205 | template <typename Derived, typename Key, typename T, |
206 | WireFormatLite::FieldType kKeyFieldType, |
207 | WireFormatLite::FieldType kValueFieldType> |
208 | bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::ContainsMapKey( |
209 | const MapKey& map_key) const { |
210 | const Map<Key, T>& map = impl_.GetMap(); |
211 | const Key& key = UnwrapMapKey<Key>(map_key); |
212 | typename Map<Key, T>::const_iterator iter = map.find(key); |
213 | return iter != map.end(); |
214 | } |
215 | |
216 | template <typename Derived, typename Key, typename T, |
217 | WireFormatLite::FieldType kKeyFieldType, |
218 | WireFormatLite::FieldType kValueFieldType> |
219 | bool MapField<Derived, Key, T, kKeyFieldType, |
220 | kValueFieldType>::InsertOrLookupMapValue(const MapKey& map_key, |
221 | MapValueRef* val) { |
222 | // Always use mutable map because users may change the map value by |
223 | // MapValueRef. |
224 | Map<Key, T>* map = MutableMap(); |
225 | const Key& key = UnwrapMapKey<Key>(map_key); |
226 | typename Map<Key, T>::iterator iter = map->find(key); |
227 | if (map->end() == iter) { |
228 | val->SetValue(&((*map)[key])); |
229 | return true; |
230 | } |
231 | // Key is already in the map. Make sure (*map)[key] is not called. |
232 | // [] may reorder the map and iterators. |
233 | val->SetValue(&(iter->second)); |
234 | return false; |
235 | } |
236 | |
237 | template <typename Derived, typename Key, typename T, |
238 | WireFormatLite::FieldType kKeyFieldType, |
239 | WireFormatLite::FieldType kValueFieldType> |
240 | bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::LookupMapValue( |
241 | const MapKey& map_key, MapValueConstRef* val) const { |
242 | const Map<Key, T>& map = GetMap(); |
243 | const Key& key = UnwrapMapKey<Key>(map_key); |
244 | typename Map<Key, T>::const_iterator iter = map.find(key); |
245 | if (map.end() == iter) { |
246 | return false; |
247 | } |
248 | // Key is already in the map. Make sure (*map)[key] is not called. |
249 | // [] may reorder the map and iterators. |
250 | val->SetValue(&(iter->second)); |
251 | return true; |
252 | } |
253 | |
254 | template <typename Derived, typename Key, typename T, |
255 | WireFormatLite::FieldType kKeyFieldType, |
256 | WireFormatLite::FieldType kValueFieldType> |
257 | bool MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::DeleteMapValue( |
258 | const MapKey& map_key) { |
259 | const Key& key = UnwrapMapKey<Key>(map_key); |
260 | return MutableMap()->erase(key); |
261 | } |
262 | |
263 | template <typename Derived, typename Key, typename T, |
264 | WireFormatLite::FieldType kKeyFieldType, |
265 | WireFormatLite::FieldType kValueFieldType> |
266 | void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::MergeFrom( |
267 | const MapFieldBase& other) { |
268 | MapFieldBase::SyncMapWithRepeatedField(); |
269 | const MapField& other_field = static_cast<const MapField&>(other); |
270 | other_field.SyncMapWithRepeatedField(); |
271 | impl_.MergeFrom(other_field.impl_); |
272 | MapFieldBase::SetMapDirty(); |
273 | } |
274 | |
275 | template <typename Derived, typename Key, typename T, |
276 | WireFormatLite::FieldType kKeyFieldType, |
277 | WireFormatLite::FieldType kValueFieldType> |
278 | void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::Swap( |
279 | MapFieldBase* other) { |
280 | MapFieldBase::Swap(other); |
281 | MapField* other_field = down_cast<MapField*>(other); |
282 | impl_.Swap(&other_field->impl_); |
283 | } |
284 | |
285 | template <typename Derived, typename Key, typename T, |
286 | WireFormatLite::FieldType kKeyFieldType, |
287 | WireFormatLite::FieldType kValueFieldType> |
288 | void MapField<Derived, Key, T, kKeyFieldType, |
289 | kValueFieldType>::UnsafeShallowSwap(MapFieldBase* other) { |
290 | InternalSwap(other: down_cast<MapField*>(other)); |
291 | } |
292 | |
293 | template <typename Derived, typename Key, typename T, |
294 | WireFormatLite::FieldType kKeyFieldType, |
295 | WireFormatLite::FieldType kValueFieldType> |
296 | void MapField<Derived, Key, T, kKeyFieldType, kValueFieldType>::InternalSwap( |
297 | MapField* other) { |
298 | MapFieldBase::InternalSwap(other); |
299 | impl_.InternalSwap(&other->impl_); |
300 | } |
301 | |
302 | template <typename Derived, typename Key, typename T, |
303 | WireFormatLite::FieldType kKeyFieldType, |
304 | WireFormatLite::FieldType kValueFieldType> |
305 | void MapField<Derived, Key, T, kKeyFieldType, |
306 | kValueFieldType>::SyncRepeatedFieldWithMapNoLock() const { |
307 | if (this->MapFieldBase::repeated_field_ == nullptr) { |
308 | this->MapFieldBase::repeated_field_ = |
309 | Arena::CreateMessage<RepeatedPtrField<Message> >( |
310 | this->MapFieldBase::arena_); |
311 | } |
312 | const Map<Key, T>& map = impl_.GetMap(); |
313 | RepeatedPtrField<EntryType>* repeated_field = |
314 | reinterpret_cast<RepeatedPtrField<EntryType>*>( |
315 | this->MapFieldBase::repeated_field_); |
316 | |
317 | repeated_field->Clear(); |
318 | |
319 | // The only way we can get at this point is through reflection and the |
320 | // only way we can get the reflection object is by having called GetReflection |
321 | // on the encompassing field. So that type must have existed and hence we |
322 | // know that this MapEntry default_type has also already been constructed. |
323 | // So it's safe to just call internal_default_instance(). |
324 | const Message* default_entry = Derived::internal_default_instance(); |
325 | for (typename Map<Key, T>::const_iterator it = map.begin(); it != map.end(); |
326 | ++it) { |
327 | EntryType* new_entry = |
328 | down_cast<EntryType*>(default_entry->New(this->MapFieldBase::arena_)); |
329 | repeated_field->AddAllocated(new_entry); |
330 | (*new_entry->mutable_key()) = it->first; |
331 | (*new_entry->mutable_value()) = it->second; |
332 | } |
333 | } |
334 | |
335 | template <typename Derived, typename Key, typename T, |
336 | WireFormatLite::FieldType kKeyFieldType, |
337 | WireFormatLite::FieldType kValueFieldType> |
338 | void MapField<Derived, Key, T, kKeyFieldType, |
339 | kValueFieldType>::SyncMapWithRepeatedFieldNoLock() const { |
340 | Map<Key, T>* map = const_cast<MapField*>(this)->impl_.MutableMap(); |
341 | RepeatedPtrField<EntryType>* repeated_field = |
342 | reinterpret_cast<RepeatedPtrField<EntryType>*>( |
343 | this->MapFieldBase::repeated_field_); |
344 | GOOGLE_CHECK(this->MapFieldBase::repeated_field_ != nullptr); |
345 | map->clear(); |
346 | for (typename RepeatedPtrField<EntryType>::iterator it = |
347 | repeated_field->begin(); |
348 | it != repeated_field->end(); ++it) { |
349 | // Cast is needed because Map's api and internal storage is different when |
350 | // value is enum. For enum, we cannot cast an int to enum. Thus, we have to |
351 | // copy value. For other types, they have same exposed api type and internal |
352 | // stored type. We should not introduce value copy for them. We achieve this |
353 | // by casting to value for enum while casting to reference for other types. |
354 | (*map)[it->key()] = static_cast<CastValueType>(it->value()); |
355 | } |
356 | } |
357 | |
358 | template <typename Derived, typename Key, typename T, |
359 | WireFormatLite::FieldType kKeyFieldType, |
360 | WireFormatLite::FieldType kValueFieldType> |
361 | size_t MapField<Derived, Key, T, kKeyFieldType, |
362 | kValueFieldType>::SpaceUsedExcludingSelfNoLock() const { |
363 | size_t size = 0; |
364 | if (this->MapFieldBase::repeated_field_ != nullptr) { |
365 | size += this->MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong(); |
366 | } |
367 | size += impl_.GetMap().SpaceUsedExcludingSelfLong(); |
368 | |
369 | return size; |
370 | } |
371 | } // namespace internal |
372 | } // namespace protobuf |
373 | } // namespace google |
374 | |
375 | #endif // GOOGLE_PROTOBUF_MAP_FIELD_INL_H__ |
376 | |