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