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 37namespace google { 38namespace protobuf { 39namespace 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. 44template <typename Key, typename T, 45 WireFormatLite::FieldType key_wire_type, 46 WireFormatLite::FieldType value_wire_type, 47 int default_enum_value = 0> 48class 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 94template <typename Key, typename T, 95 WireFormatLite::FieldType key_wire_type, 96 WireFormatLite::FieldType value_wire_type, 97 int default_enum_value> 98MapFieldLite<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 105template <typename Key, typename T, 106 WireFormatLite::FieldType key_wire_type, 107 WireFormatLite::FieldType value_wire_type, 108 int default_enum_value> 109MapFieldLite<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 116template <typename Key, typename T, 117 WireFormatLite::FieldType key_wire_type, 118 WireFormatLite::FieldType value_wire_type, 119 int default_enum_value> 120MapFieldLite<Key, T, key_wire_type, value_wire_type, 121 default_enum_value>::~MapFieldLite() { 122 delete map_; 123} 124 125template <typename Key, typename T, 126 WireFormatLite::FieldType key_wire_type, 127 WireFormatLite::FieldType value_wire_type, 128 int default_enum_value> 129const Map<Key, T>& 130MapFieldLite<Key, T, key_wire_type, value_wire_type, 131 default_enum_value>::GetMap() const { 132 return *map_; 133} 134 135template <typename Key, typename T, 136 WireFormatLite::FieldType key_wire_type, 137 WireFormatLite::FieldType value_wire_type, 138 int default_enum_value> 139Map<Key, T>* 140MapFieldLite<Key, T, key_wire_type, value_wire_type, 141 default_enum_value>::MutableMap() { 142 return map_; 143} 144 145template <typename Key, typename T, 146 WireFormatLite::FieldType key_wire_type, 147 WireFormatLite::FieldType value_wire_type, 148 int default_enum_value> 149int 150MapFieldLite<Key, T, key_wire_type, value_wire_type, 151 default_enum_value>::size() const { 152 return map_->size(); 153} 154 155template <typename Key, typename T, 156 WireFormatLite::FieldType key_wire_type, 157 WireFormatLite::FieldType value_wire_type, 158 int default_enum_value> 159void 160MapFieldLite<Key, T, key_wire_type, value_wire_type, 161 default_enum_value>::Clear() { 162 map_->clear(); 163} 164 165template <typename Key, typename T, 166 WireFormatLite::FieldType key_wire_type, 167 WireFormatLite::FieldType value_wire_type, 168 int default_enum_value> 169void 170MapFieldLite<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 179template <typename Key, typename T, 180 WireFormatLite::FieldType key_wire_type, 181 WireFormatLite::FieldType value_wire_type, 182 int default_enum_value> 183void 184MapFieldLite<Key, T, key_wire_type, value_wire_type, 185 default_enum_value>::Swap( 186 MapFieldLite* other) { 187 std::swap(map_, other->map_); 188} 189 190template <typename Key, typename T, 191 WireFormatLite::FieldType key_wire_type, 192 WireFormatLite::FieldType value_wire_type, 193 int default_enum_value> 194void 195MapFieldLite<Key, T, key_wire_type, value_wire_type, 196 default_enum_value>::SetDefaultEnumValue() { 197 MutableInternalMap()->SetDefaultEnumValue(default_enum_value); 198} 199 200template <typename Key, typename T, 201 WireFormatLite::FieldType key_wire_type, 202 WireFormatLite::FieldType value_wire_type, 203 int default_enum_value> 204const Map<Key, T>& 205MapFieldLite<Key, T, key_wire_type, value_wire_type, 206 default_enum_value>::GetInternalMap() const { 207 return *map_; 208} 209 210template <typename Key, typename T, 211 WireFormatLite::FieldType key_wire_type, 212 WireFormatLite::FieldType value_wire_type, 213 int default_enum_value> 214Map<Key, T>* 215MapFieldLite<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 223template <typename Key, typename T, 224 WireFormatLite::FieldType key_wire_type, 225 WireFormatLite::FieldType value_wire_type, 226 int default_enum_value> 227EntryType* 228MapFieldLite<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 237template <typename Key, typename T, 238 WireFormatLite::FieldType key_wire_type, 239 WireFormatLite::FieldType value_wire_type, 240 int default_enum_value> 241EntryType* 242MapFieldLite<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 248template <typename Key, typename T, 249 WireFormatLite::FieldType key_wire_type, 250 WireFormatLite::FieldType value_wire_type, 251 int default_enum_value> 252EntryType* 253MapFieldLite<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. 265template <typename Key, typename T> 266bool 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