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