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_TYPE_HANDLER_H__ 32 #define GOOGLE_PROTOBUF_TYPE_HANDLER_H__ 33 34 #include <google/protobuf/arena.h> 35 #include <google/protobuf/generated_message_util.h> 36 #include <google/protobuf/wire_format_lite_inl.h> 37 38 namespace google { 39 namespace protobuf { 40 namespace internal { 41 42 // Used for compile time type selection. MapIf::type will be TrueType if Flag is 43 // true and FalseType otherwise. 44 template<bool Flag, typename TrueType, typename FalseType> 45 struct MapIf; 46 47 template<typename TrueType, typename FalseType> 48 struct MapIf<true, TrueType, FalseType> { 49 typedef TrueType type; 50 }; 51 52 template<typename TrueType, typename FalseType> 53 struct MapIf<false, TrueType, FalseType> { 54 typedef FalseType type; 55 }; 56 57 // In proto2 Map, enum needs to be initialized to given default value, while 58 // other types' default value can be inferred from the type. 59 template <bool IsEnum, typename Type> 60 class MapValueInitializer { 61 public: 62 static inline void Initialize(Type& type, int default_enum_value); 63 }; 64 65 template <typename Type> 66 class MapValueInitializer<true, Type> { 67 public: 68 static inline void Initialize(Type& value, int default_enum_value) { 69 value = static_cast<Type>(default_enum_value); 70 } 71 }; 72 73 template <typename Type> 74 class MapValueInitializer<false, Type> { 75 public: 76 static inline void Initialize(Type& value, int default_enum_value) {} 77 }; 78 79 template <typename Type, bool is_arena_constructable> 80 class MapArenaMessageCreator { 81 public: 82 // Use arena to create message if Type is arena constructable. Otherwise, 83 // create the message on heap. 84 static inline Type* CreateMessage(Arena* arena); 85 }; 86 template <typename Type> 87 class MapArenaMessageCreator<Type, true> { 88 public: 89 static inline Type* CreateMessage(Arena* arena) { 90 return Arena::CreateMessage<Type>(arena); 91 } 92 }; 93 template <typename Type> 94 class MapArenaMessageCreator<Type, false> { 95 public: 96 static inline Type* CreateMessage(Arena* arena) { 97 return Arena::Create<Type>(arena); 98 } 99 }; 100 101 // Define constants for given wire field type 102 template <WireFormatLite::FieldType field_type, typename Type> 103 class MapWireFieldTypeTraits {}; 104 105 #define TYPE_TRAITS(FieldType, CType, WireFormatType, IsMessage, IsEnum) \ 106 template <typename Type> \ 107 class MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, Type> { \ 108 public: \ 109 static const bool kIsMessage = IsMessage; \ 110 static const bool kIsEnum = IsEnum; \ 111 typedef typename MapIf<kIsMessage, Type*, CType>::type TypeOnMemory; \ 112 typedef typename MapIf<kIsEnum, int, Type>::type MapEntryAccessorType; \ 113 static const WireFormatLite::WireType kWireType = \ 114 WireFormatLite::WIRETYPE_##WireFormatType; \ 115 }; 116 117 TYPE_TRAITS(MESSAGE , Type, LENGTH_DELIMITED, true, false) 118 TYPE_TRAITS(STRING , ArenaStringPtr, LENGTH_DELIMITED, false, false) 119 TYPE_TRAITS(BYTES , ArenaStringPtr , LENGTH_DELIMITED, false, false) 120 TYPE_TRAITS(INT64 , int64 , VARINT , false, false) 121 TYPE_TRAITS(UINT64 , uint64 , VARINT , false, false) 122 TYPE_TRAITS(INT32 , int32 , VARINT , false, false) 123 TYPE_TRAITS(UINT32 , uint32 , VARINT , false, false) 124 TYPE_TRAITS(SINT64 , int64 , VARINT , false, false) 125 TYPE_TRAITS(SINT32 , int32 , VARINT , false, false) 126 TYPE_TRAITS(ENUM , int , VARINT , false, true ) 127 TYPE_TRAITS(DOUBLE , double , FIXED64, false, false) 128 TYPE_TRAITS(FLOAT , float , FIXED32, false, false) 129 TYPE_TRAITS(FIXED64 , uint64 , FIXED64, false, false) 130 TYPE_TRAITS(FIXED32 , uint32 , FIXED32, false, false) 131 TYPE_TRAITS(SFIXED64, int64 , FIXED64, false, false) 132 TYPE_TRAITS(SFIXED32, int32 , FIXED32, false, false) 133 TYPE_TRAITS(BOOL , bool , VARINT , false, false) 134 135 #undef TYPE_TRAITS 136 137 template <WireFormatLite::FieldType field_type, typename Type> 138 class MapTypeHandler {}; 139 140 template <typename Type> 141 class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> { 142 public: 143 // Enum type cannot be used for MapTypeHandler::Read. Define a type which will 144 // replace Enum with int. 145 typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, 146 Type>::MapEntryAccessorType MapEntryAccessorType; 147 // Internal stored type in MapEntryLite for given wire field type. 148 typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, 149 Type>::TypeOnMemory TypeOnMemory; 150 // Corresponding wire type for field type. 151 static const WireFormatLite::WireType kWireType = 152 MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kWireType; 153 // Whether wire type is for message. 154 static const bool kIsMessage = 155 MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kIsMessage; 156 // Whether wire type is for enum. 157 static const bool kIsEnum = 158 MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kIsEnum; 159 160 // Functions used in parsing and serialization. =================== 161 static inline int ByteSize(const MapEntryAccessorType& value); 162 static inline int GetCachedSize(const MapEntryAccessorType& value); 163 static inline bool Read(io::CodedInputStream* input, 164 MapEntryAccessorType* value); 165 static inline void Write(int field, const MapEntryAccessorType& value, 166 io::CodedOutputStream* output); 167 static inline uint8* WriteToArray(int field, 168 const MapEntryAccessorType& value, 169 uint8* output); 170 171 // Functions to manipulate data on memory. ======================== 172 static inline const Type& GetExternalReference(const Type* value); 173 static inline void DeleteNoArena(const Type* x); 174 static inline void Merge(const Type& from, Type** to, Arena* arena); 175 static inline void Clear(Type** value, Arena* arena); 176 static inline void ClearMaybeByDefaultEnum(Type** value, Arena* arena, 177 int default_enum_value); 178 static inline void Initialize(Type** x, Arena* arena); 179 180 static inline void InitializeMaybeByDefaultEnum(Type** x, 181 int default_enum_value, 182 Arena* arena); 183 static inline Type* EnsureMutable(Type** value, Arena* arena); 184 // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding 185 // those already calculate in sizeof(MapField). 186 static inline int SpaceUsedInMapEntry(const Type* value); 187 // Return bytes used by value in Map. 188 static inline int SpaceUsedInMap(const Type& value); 189 // Assign default value to given instance. 190 static inline void AssignDefaultValue(Type** value); 191 // Return default instance if value is not initialized when calling const 192 // reference accessor. 193 static inline const Type& DefaultIfNotInitialized( 194 const Type* value, const Type* default_value); 195 // Check if all required fields have values set. 196 static inline bool IsInitialized(Type* value); 197 }; 198 199 #define MAP_HANDLER(FieldType) \ 200 template <typename Type> \ 201 class MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type> { \ 202 public: \ 203 typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ 204 Type>::MapEntryAccessorType \ 205 MapEntryAccessorType; \ 206 typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ 207 Type>::TypeOnMemory TypeOnMemory; \ 208 static const WireFormatLite::WireType kWireType = \ 209 MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ 210 Type>::kWireType; \ 211 static const bool kIsMessage = \ 212 MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ 213 Type>::kIsMessage; \ 214 static const bool kIsEnum = \ 215 MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \ 216 Type>::kIsEnum; \ 217 static inline int ByteSize(const MapEntryAccessorType& value); \ 218 static inline int GetCachedSize(const MapEntryAccessorType& value); \ 219 static inline bool Read(io::CodedInputStream* input, \ 220 MapEntryAccessorType* value); \ 221 static inline void Write(int field, const MapEntryAccessorType& value, \ 222 io::CodedOutputStream* output); \ 223 static inline uint8* WriteToArray(int field, \ 224 const MapEntryAccessorType& value, \ 225 uint8* output); \ 226 static inline const MapEntryAccessorType& GetExternalReference( \ 227 const TypeOnMemory& value); \ 228 static inline void DeleteNoArena(const TypeOnMemory& x); \ 229 static inline void Merge(const MapEntryAccessorType& from, \ 230 TypeOnMemory* to, Arena* arena); \ 231 static inline void Clear(TypeOnMemory* value, Arena* arena); \ 232 static inline void ClearMaybeByDefaultEnum(TypeOnMemory* value, \ 233 Arena* arena, \ 234 int default_enum); \ 235 static inline int SpaceUsedInMapEntry(const TypeOnMemory& value); \ 236 static inline int SpaceUsedInMap(const TypeOnMemory& value); \ 237 static inline int SpaceUsedInMap(const string& value); \ 238 static inline void AssignDefaultValue(TypeOnMemory* value); \ 239 static inline const MapEntryAccessorType& DefaultIfNotInitialized( \ 240 const TypeOnMemory& value, const TypeOnMemory& default_value); \ 241 static inline bool IsInitialized(const TypeOnMemory& value); \ 242 static void DeleteNoArena(TypeOnMemory& value); \ 243 static inline void Initialize(TypeOnMemory* value, Arena* arena); \ 244 static inline void InitializeMaybeByDefaultEnum(TypeOnMemory* value, \ 245 int default_enum_value, \ 246 Arena* arena); \ 247 static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \ 248 Arena* arena); \ 249 }; 250 MAP_HANDLER(STRING) 251 MAP_HANDLER(BYTES) 252 MAP_HANDLER(INT64) 253 MAP_HANDLER(UINT64) 254 MAP_HANDLER(INT32) 255 MAP_HANDLER(UINT32) 256 MAP_HANDLER(SINT64) 257 MAP_HANDLER(SINT32) 258 MAP_HANDLER(ENUM) 259 MAP_HANDLER(DOUBLE) 260 MAP_HANDLER(FLOAT) 261 MAP_HANDLER(FIXED64) 262 MAP_HANDLER(FIXED32) 263 MAP_HANDLER(SFIXED64) 264 MAP_HANDLER(SFIXED32) 265 MAP_HANDLER(BOOL) 266 #undef MAP_HANDLER 267 268 template <typename Type> 269 inline int 270 MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::ByteSize( 271 const MapEntryAccessorType& value) { 272 return WireFormatLite::MessageSizeNoVirtual(value); 273 } 274 275 #define GOOGLE_PROTOBUF_BYTE_SIZE(FieldType, DeclaredType) \ 276 template <typename Type> \ 277 inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::ByteSize( \ 278 const MapEntryAccessorType& value) { \ 279 return WireFormatLite::DeclaredType##Size(value); \ 280 } 281 282 GOOGLE_PROTOBUF_BYTE_SIZE(STRING, String) 283 GOOGLE_PROTOBUF_BYTE_SIZE(BYTES , Bytes) 284 GOOGLE_PROTOBUF_BYTE_SIZE(INT64 , Int64) 285 GOOGLE_PROTOBUF_BYTE_SIZE(UINT64, UInt64) 286 GOOGLE_PROTOBUF_BYTE_SIZE(INT32 , Int32) 287 GOOGLE_PROTOBUF_BYTE_SIZE(UINT32, UInt32) 288 GOOGLE_PROTOBUF_BYTE_SIZE(SINT64, SInt64) 289 GOOGLE_PROTOBUF_BYTE_SIZE(SINT32, SInt32) 290 GOOGLE_PROTOBUF_BYTE_SIZE(ENUM , Enum) 291 292 #undef GOOGLE_PROTOBUF_BYTE_SIZE 293 294 #define FIXED_BYTE_SIZE(FieldType, DeclaredType) \ 295 template <typename Type> \ 296 inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::ByteSize( \ 297 const MapEntryAccessorType& value) { \ 298 return WireFormatLite::k##DeclaredType##Size; \ 299 } 300 301 FIXED_BYTE_SIZE(DOUBLE , Double) 302 FIXED_BYTE_SIZE(FLOAT , Float) 303 FIXED_BYTE_SIZE(FIXED64 , Fixed64) 304 FIXED_BYTE_SIZE(FIXED32 , Fixed32) 305 FIXED_BYTE_SIZE(SFIXED64, SFixed64) 306 FIXED_BYTE_SIZE(SFIXED32, SFixed32) 307 FIXED_BYTE_SIZE(BOOL , Bool) 308 309 #undef FIXED_BYTE_SIZE 310 311 template <typename Type> 312 inline int 313 MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::GetCachedSize( 314 const MapEntryAccessorType& value) { 315 return WireFormatLite::LengthDelimitedSize(value.GetCachedSize()); 316 } 317 318 #define GET_CACHED_SIZE(FieldType, DeclaredType) \ 319 template <typename Type> \ 320 inline int \ 321 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::GetCachedSize( \ 322 const MapEntryAccessorType& value) { \ 323 return WireFormatLite::DeclaredType##Size(value); \ 324 } 325 326 GET_CACHED_SIZE(STRING, String) 327 GET_CACHED_SIZE(BYTES , Bytes) 328 GET_CACHED_SIZE(INT64 , Int64) 329 GET_CACHED_SIZE(UINT64, UInt64) 330 GET_CACHED_SIZE(INT32 , Int32) 331 GET_CACHED_SIZE(UINT32, UInt32) 332 GET_CACHED_SIZE(SINT64, SInt64) 333 GET_CACHED_SIZE(SINT32, SInt32) 334 GET_CACHED_SIZE(ENUM , Enum) 335 336 #undef GET_CACHED_SIZE 337 338 #define GET_FIXED_CACHED_SIZE(FieldType, DeclaredType) \ 339 template <typename Type> \ 340 inline int \ 341 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::GetCachedSize( \ 342 const MapEntryAccessorType& value) { \ 343 return WireFormatLite::k##DeclaredType##Size; \ 344 } 345 346 GET_FIXED_CACHED_SIZE(DOUBLE , Double) 347 GET_FIXED_CACHED_SIZE(FLOAT , Float) 348 GET_FIXED_CACHED_SIZE(FIXED64 , Fixed64) 349 GET_FIXED_CACHED_SIZE(FIXED32 , Fixed32) 350 GET_FIXED_CACHED_SIZE(SFIXED64, SFixed64) 351 GET_FIXED_CACHED_SIZE(SFIXED32, SFixed32) 352 GET_FIXED_CACHED_SIZE(BOOL , Bool) 353 354 #undef GET_FIXED_CACHED_SIZE 355 356 template <typename Type> 357 inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Write( 358 int field, const MapEntryAccessorType& value, 359 io::CodedOutputStream* output) { 360 WireFormatLite::WriteMessageMaybeToArray(field, value, output); 361 } 362 363 template <typename Type> 364 inline uint8* 365 MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::WriteToArray( 366 int field, const MapEntryAccessorType& value, uint8* output) { 367 return WireFormatLite::WriteMessageToArray(field, value, output); 368 } 369 370 #define WRITE_METHOD(FieldType, DeclaredType) \ 371 template <typename Type> \ 372 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Write( \ 373 int field, const MapEntryAccessorType& value, \ 374 io::CodedOutputStream* output) { \ 375 return WireFormatLite::Write##DeclaredType(field, value, output); \ 376 } \ 377 template <typename Type> \ 378 inline uint8* \ 379 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::WriteToArray( \ 380 int field, const MapEntryAccessorType& value, uint8* output) { \ 381 return WireFormatLite::Write##DeclaredType##ToArray(field, value, output); \ 382 } 383 384 WRITE_METHOD(STRING , String) 385 WRITE_METHOD(BYTES , Bytes) 386 WRITE_METHOD(INT64 , Int64) 387 WRITE_METHOD(UINT64 , UInt64) 388 WRITE_METHOD(INT32 , Int32) 389 WRITE_METHOD(UINT32 , UInt32) 390 WRITE_METHOD(SINT64 , SInt64) 391 WRITE_METHOD(SINT32 , SInt32) 392 WRITE_METHOD(ENUM , Enum) 393 WRITE_METHOD(DOUBLE , Double) 394 WRITE_METHOD(FLOAT , Float) 395 WRITE_METHOD(FIXED64 , Fixed64) 396 WRITE_METHOD(FIXED32 , Fixed32) 397 WRITE_METHOD(SFIXED64, SFixed64) 398 WRITE_METHOD(SFIXED32, SFixed32) 399 WRITE_METHOD(BOOL , Bool) 400 401 #undef WRITE_METHOD 402 403 template <typename Type> 404 inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Read( 405 io::CodedInputStream* input, MapEntryAccessorType* value) { 406 return WireFormatLite::ReadMessageNoVirtual(input, value); 407 } 408 409 template <typename Type> 410 inline bool MapTypeHandler<WireFormatLite::TYPE_STRING, Type>::Read( 411 io::CodedInputStream* input, MapEntryAccessorType* value) { 412 return WireFormatLite::ReadString(input, value); 413 } 414 415 template <typename Type> 416 inline bool MapTypeHandler<WireFormatLite::TYPE_BYTES, Type>::Read( 417 io::CodedInputStream* input, MapEntryAccessorType* value) { 418 return WireFormatLite::ReadBytes(input, value); 419 } 420 421 #define READ_METHOD(FieldType) \ 422 template <typename Type> \ 423 inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Read( \ 424 io::CodedInputStream* input, MapEntryAccessorType* value) { \ 425 return WireFormatLite::ReadPrimitive<TypeOnMemory, \ 426 WireFormatLite::TYPE_##FieldType>( \ 427 input, value); \ 428 } 429 430 READ_METHOD(INT64) 431 READ_METHOD(UINT64) 432 READ_METHOD(INT32) 433 READ_METHOD(UINT32) 434 READ_METHOD(SINT64) 435 READ_METHOD(SINT32) 436 READ_METHOD(ENUM) 437 READ_METHOD(DOUBLE) 438 READ_METHOD(FLOAT) 439 READ_METHOD(FIXED64) 440 READ_METHOD(FIXED32) 441 READ_METHOD(SFIXED64) 442 READ_METHOD(SFIXED32) 443 READ_METHOD(BOOL) 444 445 #undef READ_METHOD 446 447 // Definition for message handler 448 449 template <typename Type> 450 inline const Type& 451 MapTypeHandler<WireFormatLite::TYPE_MESSAGE, 452 Type>::GetExternalReference(const Type* value) { 453 return *value; 454 } 455 456 template <typename Type> 457 inline int 458 MapTypeHandler<WireFormatLite::TYPE_MESSAGE, 459 Type>::SpaceUsedInMapEntry(const Type* value) { 460 return value->SpaceUsed(); 461 } 462 463 template <typename Type> 464 int MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::SpaceUsedInMap( 465 const Type& value) { 466 return value.SpaceUsed(); 467 } 468 469 template <typename Type> 470 inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Clear( 471 Type** value, Arena* arena) { 472 if (*value != NULL) (*value)->Clear(); 473 } 474 template <typename Type> 475 inline void 476 MapTypeHandler<WireFormatLite::TYPE_MESSAGE, 477 Type>::ClearMaybeByDefaultEnum(Type** value, 478 Arena* arena, 479 int default_enum_value) { 480 if (*value != NULL) (*value)->Clear(); 481 } 482 template <typename Type> 483 inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Merge( 484 const Type& from, Type** to, Arena* arena) { 485 (*to)->MergeFrom(from); 486 } 487 488 template <typename Type> 489 void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::DeleteNoArena( 490 const Type* ptr) { 491 delete ptr; 492 } 493 494 template <typename Type> 495 inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, 496 Type>::AssignDefaultValue(Type** value) { 497 *value = const_cast<Type*>(&Type::default_instance()); 498 } 499 500 template <typename Type> 501 inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, 502 Type>::Initialize(Type** x, 503 Arena* arena) { 504 *x = NULL; 505 } 506 507 template <typename Type> 508 inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>:: 509 InitializeMaybeByDefaultEnum(Type** x, int default_enum_value, 510 Arena* arena) { 511 *x = NULL; 512 } 513 514 template <typename Type> 515 inline Type* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, 516 Type>::EnsureMutable(Type** value, 517 Arena* arena) { 518 if (*value == NULL) { 519 *value = 520 MapArenaMessageCreator<Type, Arena::is_arena_constructable<Type>:: 521 type::value>::CreateMessage(arena); 522 } 523 return *value; 524 } 525 526 template <typename Type> 527 inline const Type& MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>:: 528 DefaultIfNotInitialized(const Type* value, const Type* default_value) { 529 return value != NULL ? *value : *default_value; 530 } 531 532 template <typename Type> 533 inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE, 534 Type>::IsInitialized(Type* value) { 535 return value->IsInitialized(); 536 } 537 538 // Definition for string/bytes handler 539 540 #define STRING_OR_BYTES_HANDLER_FUNCTIONS(FieldType) \ 541 template <typename Type> \ 542 inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 543 Type>::MapEntryAccessorType& \ 544 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 545 Type>::GetExternalReference(const TypeOnMemory& value) { \ 546 return value.Get(&::google::protobuf::internal::GetEmptyString()); \ 547 } \ 548 template <typename Type> \ 549 inline int \ 550 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapEntry( \ 551 const TypeOnMemory& value) { \ 552 return sizeof(value); \ 553 } \ 554 template <typename Type> \ 555 inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 556 Type>::SpaceUsedInMap(const TypeOnMemory& value) { \ 557 return sizeof(value); \ 558 } \ 559 template <typename Type> \ 560 inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 561 Type>::SpaceUsedInMap(const string& value) { \ 562 return sizeof(value); \ 563 } \ 564 template <typename Type> \ 565 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \ 566 TypeOnMemory* value, Arena* arena) { \ 567 value->ClearToEmpty(&::google::protobuf::internal::GetEmptyString(), arena); \ 568 } \ 569 template <typename Type> \ 570 inline void \ 571 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 572 Type>::ClearMaybeByDefaultEnum(TypeOnMemory* value, \ 573 Arena* arena, \ 574 int default_enum) { \ 575 Clear(value, arena); \ 576 } \ 577 template <typename Type> \ 578 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \ 579 const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) { \ 580 to->Set(&::google::protobuf::internal::GetEmptyString(), from, arena); \ 581 } \ 582 template <typename Type> \ 583 void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::DeleteNoArena( \ 584 TypeOnMemory& value) { \ 585 value.DestroyNoArena(&::google::protobuf::internal::GetEmptyString()); \ 586 } \ 587 template <typename Type> \ 588 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 589 Type>::AssignDefaultValue(TypeOnMemory* value) {} \ 590 template <typename Type> \ 591 inline void \ 592 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize( \ 593 TypeOnMemory* value, Arena* arena) { \ 594 value->UnsafeSetDefault(&::google::protobuf::internal::GetEmptyString()); \ 595 } \ 596 template <typename Type> \ 597 inline void \ 598 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 599 Type>::InitializeMaybeByDefaultEnum(TypeOnMemory* value, \ 600 int default_enum_value, \ 601 Arena* arena) { \ 602 Initialize(value, arena); \ 603 } \ 604 template <typename Type> \ 605 inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 606 Type>::MapEntryAccessorType* \ 607 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \ 608 TypeOnMemory* value, Arena* arena) { \ 609 return value->Mutable(&::google::protobuf::internal::GetEmptyString(), arena); \ 610 } \ 611 template <typename Type> \ 612 inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 613 Type>::MapEntryAccessorType& \ 614 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 615 Type>::DefaultIfNotInitialized(const TypeOnMemory& value, \ 616 const TypeOnMemory& \ 617 default_value) { \ 618 return value.Get(&::google::protobuf::internal::GetEmptyString()); \ 619 } \ 620 template <typename Type> \ 621 inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 622 Type>::IsInitialized(const TypeOnMemory& value) { \ 623 return true; \ 624 } 625 STRING_OR_BYTES_HANDLER_FUNCTIONS(STRING) 626 STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES) 627 #undef STRING_OR_BYTES_HANDLER_FUNCTIONS 628 629 #define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \ 630 template <typename Type> \ 631 inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 632 Type>::MapEntryAccessorType& \ 633 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 634 Type>::GetExternalReference(const TypeOnMemory& value) { \ 635 return value; \ 636 } \ 637 template <typename Type> \ 638 inline int \ 639 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapEntry( \ 640 const TypeOnMemory& value) { \ 641 return 0; \ 642 } \ 643 template <typename Type> \ 644 inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 645 Type>::SpaceUsedInMap(const TypeOnMemory& value) { \ 646 return sizeof(Type); \ 647 } \ 648 template <typename Type> \ 649 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \ 650 TypeOnMemory* value, Arena* arena) { \ 651 *value = 0; \ 652 } \ 653 template <typename Type> \ 654 inline void \ 655 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 656 Type>::ClearMaybeByDefaultEnum(TypeOnMemory* value, \ 657 Arena* arena, \ 658 int default_enum_value) { \ 659 *value = static_cast<TypeOnMemory>(default_enum_value); \ 660 } \ 661 template <typename Type> \ 662 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \ 663 const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) { \ 664 *to = from; \ 665 } \ 666 template <typename Type> \ 667 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 668 Type>::DeleteNoArena(TypeOnMemory& x) {} \ 669 template <typename Type> \ 670 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 671 Type>::AssignDefaultValue(TypeOnMemory* value) {} \ 672 template <typename Type> \ 673 inline void \ 674 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize( \ 675 TypeOnMemory* value, Arena* arena) { \ 676 *value = 0; \ 677 } \ 678 template <typename Type> \ 679 inline void \ 680 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 681 Type>::InitializeMaybeByDefaultEnum(TypeOnMemory* value, \ 682 int default_enum_value, \ 683 Arena* arena) { \ 684 *value = static_cast<TypeOnMemory>(default_enum_value); \ 685 } \ 686 template <typename Type> \ 687 inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 688 Type>::MapEntryAccessorType* \ 689 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \ 690 TypeOnMemory* value, Arena* arena) { \ 691 return value; \ 692 } \ 693 template <typename Type> \ 694 inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 695 Type>::MapEntryAccessorType& \ 696 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 697 Type>::DefaultIfNotInitialized(const TypeOnMemory& value, \ 698 const TypeOnMemory& \ 699 default_value) { \ 700 return value; \ 701 } \ 702 template <typename Type> \ 703 inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType, \ 704 Type>::IsInitialized(const TypeOnMemory& value) { \ 705 return true; \ 706 } 707 PRIMITIVE_HANDLER_FUNCTIONS(INT64) 708 PRIMITIVE_HANDLER_FUNCTIONS(UINT64) 709 PRIMITIVE_HANDLER_FUNCTIONS(INT32) 710 PRIMITIVE_HANDLER_FUNCTIONS(UINT32) 711 PRIMITIVE_HANDLER_FUNCTIONS(SINT64) 712 PRIMITIVE_HANDLER_FUNCTIONS(SINT32) 713 PRIMITIVE_HANDLER_FUNCTIONS(ENUM) 714 PRIMITIVE_HANDLER_FUNCTIONS(DOUBLE) 715 PRIMITIVE_HANDLER_FUNCTIONS(FLOAT) 716 PRIMITIVE_HANDLER_FUNCTIONS(FIXED64) 717 PRIMITIVE_HANDLER_FUNCTIONS(FIXED32) 718 PRIMITIVE_HANDLER_FUNCTIONS(SFIXED64) 719 PRIMITIVE_HANDLER_FUNCTIONS(SFIXED32) 720 PRIMITIVE_HANDLER_FUNCTIONS(BOOL) 721 #undef PRIMITIVE_HANDLER_FUNCTIONS 722 723 } // namespace internal 724 } // namespace protobuf 725 726 } // namespace google 727 #endif // GOOGLE_PROTOBUF_TYPE_HANDLER_H__ 728