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
22namespace android {
23namespace pdx {
24namespace 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.
40enum 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.
95enum 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.
109typedef std::uint8_t EncodingType;
110
111// Extension encoding types defined by this library.
112enum 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.
119inline 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
129inline 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
138inline 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
149inline 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
159inline 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
171inline 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
182inline 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
195inline 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
207inline 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
221inline 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
234inline 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
243inline 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
252inline 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
261inline 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
274inline constexpr bool IsFloat32Encoding(EncodingType encoding) {
275  switch (encoding) {
276    case ENCODING_TYPE_FLOAT32:
277      return true;
278    default:
279      return false;
280  }
281}
282
283inline 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
293inline 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
303inline constexpr std::size_t GetFixstrSize(EncodingType encoding) {
304  return encoding & ENCODING_TYPE_FIXSTR_MASK;
305}
306
307inline constexpr std::size_t GetFixarraySize(EncodingType encoding) {
308  return encoding & ENCODING_TYPE_FIXARRAY_MASK;
309}
310
311inline constexpr std::size_t GetFixmapSize(EncodingType encoding) {
312  return encoding & ENCODING_TYPE_FIXMAP_MASK;
313}
314
315inline 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.
333inline 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
397inline 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
406inline 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
415inline 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
426inline 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
435inline 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.
440template <typename... Types>
441inline EncodingType EncodeType(const Variant<Types...>& /*variant*/) {
442  return EncodeMapType(1);
443}
444
445template <typename T>
446inline constexpr EncodingType EncodeType(const StringWrapper<T>& value) {
447  return EncodeStringType(value.length());
448}
449
450inline constexpr EncodingType EncodeType(const std::string& value) {
451  return EncodeStringType(value.length());
452}
453
454template <typename T, std::size_t Size>
455inline constexpr EncodingType EncodeType(const std::array<T, Size>& /*value*/) {
456  return EncodeArrayType(Size);
457}
458
459template <typename T>
460inline constexpr EncodingType EncodeType(const ArrayWrapper<T>& value) {
461  return EncodeArrayType(value.size());
462}
463
464template <typename T, typename Allocator>
465inline constexpr EncodingType EncodeType(
466    const std::vector<T, Allocator>& value) {
467  return EncodeArrayType(value.size());
468}
469
470template <typename Key, typename T, typename Compare, typename Allocator>
471inline constexpr EncodingType EncodeType(
472    const std::map<Key, T, Compare, Allocator>& value) {
473  return EncodeMapType(value.size());
474}
475
476template <typename Key, typename T, typename Hash, typename KeyEqual,
477          typename Allocator>
478inline constexpr EncodingType EncodeType(
479    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& value) {
480  return EncodeMapType(value.size());
481}
482
483template <typename T>
484inline 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
490template <typename T, typename U>
491inline constexpr EncodingType EncodeType(const std::pair<T, U>& /*value*/) {
492  return EncodeArrayType(2);
493}
494
495template <typename... T>
496inline 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.
503template <FileHandleMode Mode>
504inline 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.
511template <ChannelHandleMode Mode>
512inline constexpr EncodingType EncodeType(
513    const ChannelHandle<Mode>& /*handle*/) {
514  return ENCODING_TYPE_FIXEXT4;
515}
516
517inline 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.
524inline 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
531inline constexpr EncodingType EncodeType(const uint8_t& value) {
532  if (value < (1U << 7))
533    return value;
534  else
535    return ENCODING_TYPE_UINT8;
536}
537inline constexpr EncodingType EncodeType(const int8_t& value) {
538  if (value >= -32)
539    return value;
540  else
541    return ENCODING_TYPE_INT8;
542}
543inline 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}
551inline 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}
559inline 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}
569inline 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}
579inline 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}
591inline 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
604inline constexpr EncodingType EncodeType(const float& /*value*/) {
605  return ENCODING_TYPE_FLOAT32;
606}
607
608inline 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