Home | History | Annotate | Download | only in rpc
      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.
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    303 inline constexpr std::size_t GetFixstrSize(EncodingType encoding) {
    304   return encoding & ENCODING_TYPE_FIXSTR_MASK;
    305 }
    306 
    307 inline constexpr std::size_t GetFixarraySize(EncodingType encoding) {
    308   return encoding & ENCODING_TYPE_FIXARRAY_MASK;
    309 }
    310 
    311 inline constexpr std::size_t GetFixmapSize(EncodingType encoding) {
    312   return encoding & ENCODING_TYPE_FIXMAP_MASK;
    313 }
    314 
    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.
    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 
    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 
    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 
    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 
    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 
    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>
    441 inline EncodingType EncodeType(const Variant<Types...>& /*variant*/) {
    442   return EncodeMapType(1);
    443 }
    444 
    445 template <typename T>
    446 inline constexpr EncodingType EncodeType(const StringWrapper<T>& value) {
    447   return EncodeStringType(value.length());
    448 }
    449 
    450 inline constexpr EncodingType EncodeType(const std::string& value) {
    451   return EncodeStringType(value.length());
    452 }
    453 
    454 template <typename T, std::size_t Size>
    455 inline constexpr EncodingType EncodeType(const std::array<T, Size>& /*value*/) {
    456   return EncodeArrayType(Size);
    457 }
    458 
    459 template <typename T>
    460 inline constexpr EncodingType EncodeType(const ArrayWrapper<T>& value) {
    461   return EncodeArrayType(value.size());
    462 }
    463 
    464 template <typename T, typename Allocator>
    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>
    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>
    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>
    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>
    491 inline constexpr EncodingType EncodeType(const std::pair<T, U>& /*value*/) {
    492   return EncodeArrayType(2);
    493 }
    494 
    495 template <typename... 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>
    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>
    512 inline constexpr EncodingType EncodeType(
    513     const ChannelHandle<Mode>& /*handle*/) {
    514   return ENCODING_TYPE_FIXEXT4;
    515 }
    516 
    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.
    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 
    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 }
    537 inline constexpr EncodingType EncodeType(const int8_t& value) {
    538   if (value >= -32)
    539     return value;
    540   else
    541     return ENCODING_TYPE_INT8;
    542 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 
    604 inline constexpr EncodingType EncodeType(const float& /*value*/) {
    605   return ENCODING_TYPE_FLOAT32;
    606 }
    607 
    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