1 #ifndef ANDROID_PDX_RPC_ENCODING_H_
2 #define ANDROID_PDX_RPC_ENCODING_H_
3
4 #include <array>
5 #include <cstdint>
6 #include <cstring>
7 #include <map>
8 #include <numeric>
9 #include <string>
10 #include <tuple>
11 #include <unordered_map>
12 #include <vector>
13
14 #include <pdx/channel_handle.h>
15 #include <pdx/file_handle.h>
16
17 #include "array_wrapper.h"
18 #include "buffer_wrapper.h"
19 #include "string_wrapper.h"
20 #include "variant.h"
21
22 namespace android {
23 namespace pdx {
24 namespace rpc {
25
26 // This library uses a subset, or profile, of MessagePack (http://msgpack.org)
27 // to encode supported data types during serialization and to verify the
28 // expected data types during deserialization. One notable deviation from the
29 // MessagePack specification is that little-endian byte order is used for
30 // multi-byte numeric types to avoid unnecessary conversion on nearly all
31 // relevant architectures.
32 //
33 // Some data types, integers for example, support multiple encoding strategies.
34 // This library attempts to optimize for space based on the value of such types.
35 // However, during decode all valid encodings for a given type are accepted.
36
37 // Prefix byte for type encodings. This is the complete list of prefix bytes
38 // from the MessagePack specification, even though not all types are used by
39 // this library.
40 enum EncodingPrefix {
41 ENCODING_TYPE_POSITIVE_FIXINT = 0x00,
42 ENCODING_TYPE_POSITIVE_FIXINT_MIN = 0x00,
43 ENCODING_TYPE_POSITIVE_FIXINT_MAX = 0x7f,
44 ENCODING_TYPE_POSITIVE_FIXINT_MASK = 0x7f,
45 ENCODING_TYPE_FIXMAP = 0x80,
46 ENCODING_TYPE_FIXMAP_MIN = 0x80,
47 ENCODING_TYPE_FIXMAP_MAX = 0x8f,
48 ENCODING_TYPE_FIXMAP_MASK = 0x0f,
49 ENCODING_TYPE_FIXARRAY = 0x90,
50 ENCODING_TYPE_FIXARRAY_MIN = 0x90,
51 ENCODING_TYPE_FIXARRAY_MAX = 0x9f,
52 ENCODING_TYPE_FIXARRAY_MASK = 0x0f,
53 ENCODING_TYPE_FIXSTR = 0xa0,
54 ENCODING_TYPE_FIXSTR_MIN = 0xa0,
55 ENCODING_TYPE_FIXSTR_MAX = 0xbf,
56 ENCODING_TYPE_FIXSTR_MASK = 0x1f,
57 ENCODING_TYPE_NIL = 0xc0,
58 ENCODING_TYPE_RESERVED = 0xc1,
59 ENCODING_TYPE_FALSE = 0xc2,
60 ENCODING_TYPE_TRUE = 0xc3,
61 ENCODING_TYPE_BIN8 = 0xc4,
62 ENCODING_TYPE_BIN16 = 0xc5,
63 ENCODING_TYPE_BIN32 = 0xc6,
64 ENCODING_TYPE_EXT8 = 0xc7,
65 ENCODING_TYPE_EXT16 = 0xc8,
66 ENCODING_TYPE_EXT32 = 0xc9,
67 ENCODING_TYPE_FLOAT32 = 0xca,
68 ENCODING_TYPE_FLOAT64 = 0xcb,
69 ENCODING_TYPE_UINT8 = 0xcc,
70 ENCODING_TYPE_UINT16 = 0xcd,
71 ENCODING_TYPE_UINT32 = 0xce,
72 ENCODING_TYPE_UINT64 = 0xcf,
73 ENCODING_TYPE_INT8 = 0xd0,
74 ENCODING_TYPE_INT16 = 0xd1,
75 ENCODING_TYPE_INT32 = 0xd2,
76 ENCODING_TYPE_INT64 = 0xd3,
77 ENCODING_TYPE_FIXEXT1 = 0xd4,
78 ENCODING_TYPE_FIXEXT2 = 0xd5,
79 ENCODING_TYPE_FIXEXT4 = 0xd6,
80 ENCODING_TYPE_FIXEXT8 = 0xd7,
81 ENCODING_TYPE_FIXEXT16 = 0xd8,
82 ENCODING_TYPE_STR8 = 0xd9,
83 ENCODING_TYPE_STR16 = 0xda,
84 ENCODING_TYPE_STR32 = 0xdb,
85 ENCODING_TYPE_ARRAY16 = 0xdc,
86 ENCODING_TYPE_ARRAY32 = 0xdd,
87 ENCODING_TYPE_MAP16 = 0xde,
88 ENCODING_TYPE_MAP32 = 0xdf,
89 ENCODING_TYPE_NEGATIVE_FIXINT = 0xe0,
90 ENCODING_TYPE_NEGATIVE_FIXINT_MIN = 0xe0,
91 ENCODING_TYPE_NEGATIVE_FIXINT_MAX = 0xff,
92 };
93
94 // Base encoding classes grouping multi-strategy encodings.
95 enum EncodingClass {
96 ENCODING_CLASS_BOOL,
97 ENCODING_CLASS_NIL,
98 ENCODING_CLASS_INT,
99 ENCODING_CLASS_UINT,
100 ENCODING_CLASS_FLOAT,
101 ENCODING_CLASS_ARRAY,
102 ENCODING_CLASS_MAP,
103 ENCODING_CLASS_STRING,
104 ENCODING_CLASS_BINARY,
105 ENCODING_CLASS_EXTENSION,
106 };
107
108 // Encoding prefixes are unsigned bytes.
109 typedef std::uint8_t EncodingType;
110
111 // Extension encoding types defined by this library.
112 enum EncodingExtType : int8_t {
113 ENCODING_EXT_TYPE_FILE_DESCRIPTOR,
114 ENCODING_EXT_TYPE_CHANNEL_HANDLE,
115 };
116
117 // Encoding predicates. Determines whether the given encoding is of a specific
118 // type.
IsFixintEncoding(EncodingType encoding)119 inline constexpr bool IsFixintEncoding(EncodingType encoding) {
120 switch (encoding) {
121 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
122 case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
123 return true;
124 default:
125 return false;
126 }
127 }
128
IsUnsignedFixintEncoding(EncodingType encoding)129 inline constexpr bool IsUnsignedFixintEncoding(EncodingType encoding) {
130 switch (encoding) {
131 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
132 return true;
133 default:
134 return false;
135 }
136 }
137
IsInt8Encoding(EncodingType encoding)138 inline constexpr bool IsInt8Encoding(EncodingType encoding) {
139 switch (encoding) {
140 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
141 case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
142 case ENCODING_TYPE_INT8:
143 return true;
144 default:
145 return false;
146 }
147 }
148
IsUInt8Encoding(EncodingType encoding)149 inline constexpr bool IsUInt8Encoding(EncodingType encoding) {
150 switch (encoding) {
151 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
152 case ENCODING_TYPE_UINT8:
153 return true;
154 default:
155 return false;
156 }
157 }
158
IsInt16Encoding(EncodingType encoding)159 inline constexpr bool IsInt16Encoding(EncodingType encoding) {
160 switch (encoding) {
161 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
162 case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
163 case ENCODING_TYPE_INT8:
164 case ENCODING_TYPE_INT16:
165 return true;
166 default:
167 return false;
168 }
169 }
170
IsUInt16Encoding(EncodingType encoding)171 inline constexpr bool IsUInt16Encoding(EncodingType encoding) {
172 switch (encoding) {
173 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
174 case ENCODING_TYPE_UINT8:
175 case ENCODING_TYPE_UINT16:
176 return true;
177 default:
178 return false;
179 }
180 }
181
IsInt32Encoding(EncodingType encoding)182 inline constexpr bool IsInt32Encoding(EncodingType encoding) {
183 switch (encoding) {
184 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
185 case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
186 case ENCODING_TYPE_INT8:
187 case ENCODING_TYPE_INT16:
188 case ENCODING_TYPE_INT32:
189 return true;
190 default:
191 return false;
192 }
193 }
194
IsUInt32Encoding(EncodingType encoding)195 inline constexpr bool IsUInt32Encoding(EncodingType encoding) {
196 switch (encoding) {
197 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
198 case ENCODING_TYPE_UINT8:
199 case ENCODING_TYPE_UINT16:
200 case ENCODING_TYPE_UINT32:
201 return true;
202 default:
203 return false;
204 }
205 }
206
IsInt64Encoding(EncodingType encoding)207 inline constexpr bool IsInt64Encoding(EncodingType encoding) {
208 switch (encoding) {
209 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
210 case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
211 case ENCODING_TYPE_INT8:
212 case ENCODING_TYPE_INT16:
213 case ENCODING_TYPE_INT32:
214 case ENCODING_TYPE_INT64:
215 return true;
216 default:
217 return false;
218 }
219 }
220
IsUInt64Encoding(EncodingType encoding)221 inline constexpr bool IsUInt64Encoding(EncodingType encoding) {
222 switch (encoding) {
223 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
224 case ENCODING_TYPE_UINT8:
225 case ENCODING_TYPE_UINT16:
226 case ENCODING_TYPE_UINT32:
227 case ENCODING_TYPE_UINT64:
228 return true;
229 default:
230 return false;
231 }
232 }
233
IsFixmapEncoding(EncodingType encoding)234 inline constexpr bool IsFixmapEncoding(EncodingType encoding) {
235 switch (encoding) {
236 case ENCODING_TYPE_FIXMAP_MIN ... ENCODING_TYPE_FIXMAP_MAX:
237 return true;
238 default:
239 return false;
240 }
241 }
242
IsFixarrayEncoding(EncodingType encoding)243 inline constexpr bool IsFixarrayEncoding(EncodingType encoding) {
244 switch (encoding) {
245 case ENCODING_TYPE_FIXARRAY_MIN ... ENCODING_TYPE_FIXARRAY_MAX:
246 return true;
247 default:
248 return false;
249 }
250 }
251
IsFixstrEncoding(EncodingType encoding)252 inline constexpr bool IsFixstrEncoding(EncodingType encoding) {
253 switch (encoding) {
254 case ENCODING_TYPE_FIXSTR_MIN ... ENCODING_TYPE_FIXSTR_MAX:
255 return true;
256 default:
257 return false;
258 }
259 }
260
IsFixextEncoding(EncodingType encoding)261 inline constexpr bool IsFixextEncoding(EncodingType encoding) {
262 switch (encoding) {
263 case ENCODING_TYPE_FIXEXT1:
264 case ENCODING_TYPE_FIXEXT2:
265 case ENCODING_TYPE_FIXEXT4:
266 case ENCODING_TYPE_FIXEXT8:
267 case ENCODING_TYPE_FIXEXT16:
268 return true;
269 default:
270 return false;
271 }
272 }
273
IsFloat32Encoding(EncodingType encoding)274 inline constexpr bool IsFloat32Encoding(EncodingType encoding) {
275 switch (encoding) {
276 case ENCODING_TYPE_FLOAT32:
277 return true;
278 default:
279 return false;
280 }
281 }
282
IsFloat64Encoding(EncodingType encoding)283 inline constexpr bool IsFloat64Encoding(EncodingType encoding) {
284 switch (encoding) {
285 case ENCODING_TYPE_FLOAT32:
286 case ENCODING_TYPE_FLOAT64:
287 return true;
288 default:
289 return false;
290 }
291 }
292
IsBoolEncoding(EncodingType encoding)293 inline constexpr bool IsBoolEncoding(EncodingType encoding) {
294 switch (encoding) {
295 case ENCODING_TYPE_FALSE:
296 case ENCODING_TYPE_TRUE:
297 return true;
298 default:
299 return false;
300 }
301 }
302
GetFixstrSize(EncodingType encoding)303 inline constexpr std::size_t GetFixstrSize(EncodingType encoding) {
304 return encoding & ENCODING_TYPE_FIXSTR_MASK;
305 }
306
GetFixarraySize(EncodingType encoding)307 inline constexpr std::size_t GetFixarraySize(EncodingType encoding) {
308 return encoding & ENCODING_TYPE_FIXARRAY_MASK;
309 }
310
GetFixmapSize(EncodingType encoding)311 inline constexpr std::size_t GetFixmapSize(EncodingType encoding) {
312 return encoding & ENCODING_TYPE_FIXMAP_MASK;
313 }
314
GetFixextSize(EncodingType encoding)315 inline constexpr std::size_t GetFixextSize(EncodingType encoding) {
316 switch (encoding) {
317 case ENCODING_TYPE_FIXEXT1:
318 return 1;
319 case ENCODING_TYPE_FIXEXT2:
320 return 2;
321 case ENCODING_TYPE_FIXEXT4:
322 return 4;
323 case ENCODING_TYPE_FIXEXT8:
324 return 8;
325 case ENCODING_TYPE_FIXEXT16:
326 return 16;
327 default:
328 return 0; // Invalid fixext size.
329 }
330 }
331
332 // Gets the size of the encoding in bytes, not including external payload data.
GetEncodingSize(EncodingType encoding)333 inline constexpr std::size_t GetEncodingSize(EncodingType encoding) {
334 switch (encoding) {
335 // Encoding is fully contained within the type value.
336 case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
337 case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
338 case ENCODING_TYPE_FIXMAP_MIN ... ENCODING_TYPE_FIXMAP_MAX:
339 case ENCODING_TYPE_FIXARRAY_MIN ... ENCODING_TYPE_FIXARRAY_MAX:
340 case ENCODING_TYPE_FIXSTR_MIN ... ENCODING_TYPE_FIXSTR_MAX:
341 case ENCODING_TYPE_NIL:
342 case ENCODING_TYPE_RESERVED:
343 case ENCODING_TYPE_FALSE:
344 case ENCODING_TYPE_TRUE:
345 return 1;
346
347 // Encoding type followed by one-byte size or immediate value.
348 case ENCODING_TYPE_BIN8:
349 case ENCODING_TYPE_EXT8:
350 case ENCODING_TYPE_UINT8:
351 case ENCODING_TYPE_INT8:
352 case ENCODING_TYPE_STR8:
353 // Encoding type followed by one-byte extension type.
354 case ENCODING_TYPE_FIXEXT1:
355 case ENCODING_TYPE_FIXEXT2:
356 case ENCODING_TYPE_FIXEXT4:
357 case ENCODING_TYPE_FIXEXT8:
358 case ENCODING_TYPE_FIXEXT16:
359 return 2;
360
361 // Encoding type followed by two-byte size or immediate value.
362 case ENCODING_TYPE_BIN16:
363 case ENCODING_TYPE_EXT16:
364 case ENCODING_TYPE_UINT16:
365 case ENCODING_TYPE_INT16:
366 case ENCODING_TYPE_STR16:
367 case ENCODING_TYPE_ARRAY16:
368 case ENCODING_TYPE_MAP16:
369 return 3;
370
371 // Encoding type followed by four-byte size or immediate value.
372 case ENCODING_TYPE_BIN32:
373 case ENCODING_TYPE_EXT32:
374 case ENCODING_TYPE_FLOAT32:
375 case ENCODING_TYPE_UINT32:
376 case ENCODING_TYPE_INT32:
377 case ENCODING_TYPE_STR32:
378 case ENCODING_TYPE_ARRAY32:
379 case ENCODING_TYPE_MAP32:
380 return 5;
381
382 // Encoding type followed by eight-byte immediate value.
383 case ENCODING_TYPE_FLOAT64:
384 case ENCODING_TYPE_UINT64:
385 case ENCODING_TYPE_INT64:
386 return 9;
387
388 default:
389 return 0;
390 }
391 }
392
393 // Encoding for standard types. Each supported data type has an associated
394 // encoding or set of encodings. These functions determine the MessagePack
395 // encoding based on the data type, value, and size of their arguments.
396
EncodeArrayType(std::size_t size)397 inline constexpr EncodingType EncodeArrayType(std::size_t size) {
398 if (size < (1U << 4))
399 return ENCODING_TYPE_FIXARRAY | (size & ENCODING_TYPE_FIXARRAY_MASK);
400 else if (size < (1U << 16))
401 return ENCODING_TYPE_ARRAY16;
402 else
403 return ENCODING_TYPE_ARRAY32;
404 }
405
EncodeMapType(std::size_t size)406 inline constexpr EncodingType EncodeMapType(std::size_t size) {
407 if (size < (1U << 4))
408 return ENCODING_TYPE_FIXMAP | (size & ENCODING_TYPE_FIXMAP_MASK);
409 else if (size < (1U << 16))
410 return ENCODING_TYPE_MAP16;
411 else
412 return ENCODING_TYPE_MAP32;
413 }
414
EncodeStringType(std::size_t size)415 inline constexpr EncodingType EncodeStringType(std::size_t size) {
416 if (size < (1U << 5))
417 return ENCODING_TYPE_FIXSTR | (size & ENCODING_TYPE_FIXSTR_MASK);
418 else if (size < (1U << 8))
419 return ENCODING_TYPE_STR8;
420 else if (size < (1U << 16))
421 return ENCODING_TYPE_STR16;
422 else
423 return ENCODING_TYPE_STR32;
424 }
425
EncodeBinType(std::size_t size)426 inline constexpr EncodingType EncodeBinType(std::size_t size) {
427 if (size < (1U << 8))
428 return ENCODING_TYPE_BIN8;
429 else if (size < (1U << 16))
430 return ENCODING_TYPE_BIN16;
431 else
432 return ENCODING_TYPE_BIN32;
433 }
434
EncodeType(const EmptyVariant &)435 inline EncodingType EncodeType(const EmptyVariant& /*empty*/) {
436 return ENCODING_TYPE_NIL;
437 }
438
439 // Variant is encoded as a single-element map, with the type index as the key.
440 template <typename... Types>
EncodeType(const Variant<Types...> &)441 inline EncodingType EncodeType(const Variant<Types...>& /*variant*/) {
442 return EncodeMapType(1);
443 }
444
445 template <typename T>
EncodeType(const StringWrapper<T> & value)446 inline constexpr EncodingType EncodeType(const StringWrapper<T>& value) {
447 return EncodeStringType(value.length());
448 }
449
EncodeType(const std::string & value)450 inline constexpr EncodingType EncodeType(const std::string& value) {
451 return EncodeStringType(value.length());
452 }
453
454 template <typename T, std::size_t Size>
EncodeType(const std::array<T,Size> &)455 inline constexpr EncodingType EncodeType(const std::array<T, Size>& /*value*/) {
456 return EncodeArrayType(Size);
457 }
458
459 template <typename T>
EncodeType(const ArrayWrapper<T> & value)460 inline constexpr EncodingType EncodeType(const ArrayWrapper<T>& value) {
461 return EncodeArrayType(value.size());
462 }
463
464 template <typename T, typename Allocator>
EncodeType(const std::vector<T,Allocator> & value)465 inline constexpr EncodingType EncodeType(
466 const std::vector<T, Allocator>& value) {
467 return EncodeArrayType(value.size());
468 }
469
470 template <typename Key, typename T, typename Compare, typename Allocator>
EncodeType(const std::map<Key,T,Compare,Allocator> & value)471 inline constexpr EncodingType EncodeType(
472 const std::map<Key, T, Compare, Allocator>& value) {
473 return EncodeMapType(value.size());
474 }
475
476 template <typename Key, typename T, typename Hash, typename KeyEqual,
477 typename Allocator>
EncodeType(const std::unordered_map<Key,T,Hash,KeyEqual,Allocator> & value)478 inline constexpr EncodingType EncodeType(
479 const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& value) {
480 return EncodeMapType(value.size());
481 }
482
483 template <typename T>
EncodeType(const BufferWrapper<T> & value)484 inline constexpr EncodingType EncodeType(const BufferWrapper<T>& value) {
485 // BIN size is in bytes.
486 return EncodeBinType(value.size() *
487 sizeof(typename BufferWrapper<T>::value_type));
488 }
489
490 template <typename T, typename U>
EncodeType(const std::pair<T,U> &)491 inline constexpr EncodingType EncodeType(const std::pair<T, U>& /*value*/) {
492 return EncodeArrayType(2);
493 }
494
495 template <typename... T>
EncodeType(const std::tuple<T...> &)496 inline constexpr EncodingType EncodeType(const std::tuple<T...>& /*value*/) {
497 return EncodeArrayType(sizeof...(T));
498 }
499
500 // FileHandle is encoded as a FIXEXT2 with a type code for "FileDescriptor"
501 // and a signed 16-bit index into the pushed fd array. Empty file descriptor
502 // have an array index of -1.
503 template <FileHandleMode Mode>
EncodeType(const FileHandle<Mode> &)504 inline constexpr EncodingType EncodeType(const FileHandle<Mode>& /*fd*/) {
505 return ENCODING_TYPE_FIXEXT2;
506 }
507
508 // ChannelHandle is encoded as a FIXEXT4 with a type of
509 // ENCODING_EXT_TYPE_CHANNEL_HANDLE and a signed 32-bit value representing
510 // a client channel in a remote process. Empty handle has a value of -1.
511 template <ChannelHandleMode Mode>
EncodeType(const ChannelHandle<Mode> &)512 inline constexpr EncodingType EncodeType(
513 const ChannelHandle<Mode>& /*handle*/) {
514 return ENCODING_TYPE_FIXEXT4;
515 }
516
EncodeType(const bool & value)517 inline constexpr EncodingType EncodeType(const bool& value) {
518 return value ? ENCODING_TYPE_TRUE : ENCODING_TYPE_FALSE;
519 }
520
521 // Type 'char' is a little bit special in that it is distinct from 'signed char'
522 // and 'unsigned char'. Treating it as an unsigned 8-bit value is safe for
523 // encoding purposes and nicely handles 7-bit ASCII encodings as FIXINT.
EncodeType(const char & value)524 inline constexpr EncodingType EncodeType(const char& value) {
525 if (value < static_cast<char>(1 << 7))
526 return value;
527 else
528 return ENCODING_TYPE_UINT8;
529 }
530
EncodeType(const uint8_t & value)531 inline constexpr EncodingType EncodeType(const uint8_t& value) {
532 if (value < (1U << 7))
533 return value;
534 else
535 return ENCODING_TYPE_UINT8;
536 }
EncodeType(const int8_t & value)537 inline constexpr EncodingType EncodeType(const int8_t& value) {
538 if (value >= -32)
539 return value;
540 else
541 return ENCODING_TYPE_INT8;
542 }
EncodeType(const uint16_t & value)543 inline constexpr EncodingType EncodeType(const uint16_t& value) {
544 if (value < (1U << 7))
545 return static_cast<EncodingType>(value);
546 else if (value < (1U << 8))
547 return ENCODING_TYPE_UINT8;
548 else
549 return ENCODING_TYPE_UINT16;
550 }
EncodeType(const int16_t & value)551 inline constexpr EncodingType EncodeType(const int16_t& value) {
552 if (value >= -32 && value <= 127)
553 return static_cast<EncodingType>(value);
554 else if (value >= -128 && value <= 127)
555 return ENCODING_TYPE_INT8;
556 else
557 return ENCODING_TYPE_INT16;
558 }
EncodeType(const uint32_t & value)559 inline constexpr EncodingType EncodeType(const uint32_t& value) {
560 if (value < (1U << 7))
561 return static_cast<EncodingType>(value);
562 else if (value < (1U << 8))
563 return ENCODING_TYPE_UINT8;
564 else if (value < (1U << 16))
565 return ENCODING_TYPE_UINT16;
566 else
567 return ENCODING_TYPE_UINT32;
568 }
EncodeType(const int32_t & value)569 inline constexpr EncodingType EncodeType(const int32_t& value) {
570 if (value >= -32 && value <= 127)
571 return static_cast<EncodingType>(value);
572 else if (value >= -128 && value <= 127)
573 return ENCODING_TYPE_INT8;
574 else if (value >= -32768 && value <= 32767)
575 return ENCODING_TYPE_INT16;
576 else
577 return ENCODING_TYPE_INT32;
578 }
EncodeType(const uint64_t & value)579 inline constexpr EncodingType EncodeType(const uint64_t& value) {
580 if (value < (1ULL << 7))
581 return static_cast<EncodingType>(value);
582 else if (value < (1ULL << 8))
583 return ENCODING_TYPE_UINT8;
584 else if (value < (1ULL << 16))
585 return ENCODING_TYPE_UINT16;
586 else if (value < (1ULL << 32))
587 return ENCODING_TYPE_UINT32;
588 else
589 return ENCODING_TYPE_UINT64;
590 }
EncodeType(const int64_t & value)591 inline constexpr EncodingType EncodeType(const int64_t& value) {
592 if (value >= -32 && value <= 127)
593 return static_cast<EncodingType>(value);
594 else if (value >= -128 && value <= 127) // Effectively [-128, -32).
595 return ENCODING_TYPE_INT8;
596 else if (value >= -32768 && value <= 32767)
597 return ENCODING_TYPE_INT16;
598 else if (value >= -2147483648 && value <= 2147483647)
599 return ENCODING_TYPE_INT32;
600 else
601 return ENCODING_TYPE_INT64;
602 }
603
EncodeType(const float &)604 inline constexpr EncodingType EncodeType(const float& /*value*/) {
605 return ENCODING_TYPE_FLOAT32;
606 }
607
EncodeType(const double &)608 inline constexpr EncodingType EncodeType(const double& /*value*/) {
609 return ENCODING_TYPE_FLOAT64;
610 }
611
612 } // namespace rpc
613 } // namespace pdx
614 } // namespace android
615
616 #endif // ANDROID_PDX_RPC_ENCODING_H_
617