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