1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_PDX_RPC_SERIALIZATION_H_
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_PDX_RPC_SERIALIZATION_H_
3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <cstdint>
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <cstring>
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <iterator>
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <map>
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <numeric>
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sstream>
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <string>
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <tuple>
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <type_traits>
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <unordered_map>
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <utility>
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <vector>
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/channel_handle.h>
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/file_handle.h>
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/message_reader.h>
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/message_writer.h>
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/trace.h>
22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/utility.h>
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "array_wrapper.h"
25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "default_initialization_allocator.h"
26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "encoding.h"
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "pointer_wrapper.h"
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "string_wrapper.h"
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "variant.h"
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx {
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace rpc {
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Automatic serialization/deserialization library based on MessagePack
36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// (http://msgpack.org). This library provides top level Serialize() and
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserialize() functions to encode/decode a variety of data types.
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// The following data types are supported:
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * Standard signed integer types: int8_t, int16_t, int32_t, and int64_t.
41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * Regular signed integer types equivalent to the standard types:
42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//     signed char, short, int, long, and long long.
43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * Standard unsigned integer types: uint8_t, uint16_t, uint32_t, and
44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//     uint64_t.
45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * Regular unsigned integer types equivalent to the standard types:
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//     unsigned char, unsigned short, unsigned int, unsigned long,
47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//     and unsigned long long.
48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * char without signed/unsigned qualifiers.
49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * bool.
50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * std::vector with value type of any supported type, including nesting.
51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * std::string.
52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * std::tuple with elements of any supported type, including nesting.
53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * std::pair with elements of any supported type, including nesting.
54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * std::map with keys and values of any supported type, including nesting.
55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * std::unordered_map with keys and values of any supported type, including
56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//     nesting.
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * std::array with values of any supported type, including nesting.
58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * ArrayWrapper of any supported basic type.
59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * BufferWrapper of any POD type.
60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * StringWrapper of any supported char type.
61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * User types with correctly defined SerializableMembers member type.
62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//
63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Planned support for:
64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//   * std::basic_string with all supported char types.
65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Counting template for managing template recursion.
67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <std::size_t N>
68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct Index {};
69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Forward declaration of traits type to access types with a SerializedMembers
71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// member type.
72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass SerializableTraits;
74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename... MemberPointers>
76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct SerializableMembersType;
77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility to deduce the template type from a derived type.
79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <template <typename...> class TT, typename... Ts>
80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::true_type DeduceTemplateType(const TT<Ts...>*);
81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <template <typename...> class TT>
82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::false_type DeduceTemplateType(...);
83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility determining whether template type TT<...> is a base of type T.
85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <template <typename...> class TT, typename T>
86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing IsTemplateBaseOf = decltype(DeduceTemplateType<TT>(std::declval<T*>()));
87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility type for SFINAE in HasHasSerializableMembers.
89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... Ts>
90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing TrySerializableMembersType = void;
91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Determines whether type T has a member type named SerializableMembers of
93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// template type SerializableMembersType.
94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename, typename = void>
95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct HasSerializableMembers : std::false_type {};
96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct HasSerializableMembers<
98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    T, TrySerializableMembersType<typename T::SerializableMembers>>
99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    : std::integral_constant<
100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          bool, IsTemplateBaseOf<SerializableMembersType,
101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                 typename T::SerializableMembers>::value> {};
102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility to simplify overload enable expressions for types with correctly
104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// defined SerializableMembers.
105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing EnableIfHasSerializableMembers =
107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    typename std::enable_if<HasSerializableMembers<T>::value>::type;
108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility to simplify overload enable expressions for enum types.
110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename ReturnType = void>
111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing EnableIfEnum =
112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    typename std::enable_if<std::is_enum<T>::value, ReturnType>::type;
113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Error Reporting //
116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Error codes returned by the deserialization code.
119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoenum class ErrorCode {
120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  NO_ERROR = 0,
121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  UNEXPECTED_ENCODING,
122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  UNEXPECTED_TYPE_SIZE,
123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  INSUFFICIENT_BUFFER,
124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  INSUFFICIENT_DESTINATION_SIZE,
125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  GET_FILE_DESCRIPTOR_FAILED,
126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  GET_CHANNEL_HANDLE_FAILED,
127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  INVALID_VARIANT_ELEMENT,
128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Type for errors returned by the deserialization code.
131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ErrorType {
132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public:
133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ErrorType() : error_code_(ErrorCode::NO_ERROR) {}
134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // ErrorType constructor for generic error codes. Explicitly not explicit,
136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // implicit conversion from ErrorCode to ErrorType is desirable behavior.
137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // NOLINTNEXTLINE(runtime/explicit)
138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ErrorType(ErrorCode error_code) : error_code_(error_code) {}
139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // ErrorType constructor for encoding type errors.
141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ErrorType(ErrorCode error_code, EncodingClass encoding_class,
142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            EncodingType encoding_type)
143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      : error_code_(error_code) {
144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    unexpected_encoding_.encoding_class = encoding_class;
145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    unexpected_encoding_.encoding_type = encoding_type;
146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Evaluates to true if the ErrorType represents an error.
149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  explicit operator bool() const { return error_code_ != ErrorCode::NO_ERROR; }
150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  operator ErrorCode() const { return error_code_; }
152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ErrorCode error_code() const { return error_code_; }
153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Accessors for extra info about unexpected encoding errors.
155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingClass encoding_class() const {
156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return unexpected_encoding_.encoding_class;
157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding_type() const {
159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return unexpected_encoding_.encoding_type;
160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  operator std::string() const {
163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::ostringstream stream;
164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    switch (error_code_) {
166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case ErrorCode::NO_ERROR:
167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return "NO_ERROR";
168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case ErrorCode::UNEXPECTED_ENCODING:
169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        stream << "UNEXPECTED_ENCODING: " << static_cast<int>(encoding_class())
170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               << ", " << static_cast<int>(encoding_type());
171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return stream.str();
172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case ErrorCode::UNEXPECTED_TYPE_SIZE:
173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return "UNEXPECTED_TYPE_SIZE";
174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case ErrorCode::INSUFFICIENT_BUFFER:
175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return "INSUFFICIENT_BUFFER";
176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case ErrorCode::INSUFFICIENT_DESTINATION_SIZE:
177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return "INSUFFICIENT_DESTINATION_SIZE";
178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      default:
179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return "[Unknown Error]";
180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ErrorCode error_code_;
185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Union of extra information for different error code types.
187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  union {
188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // UNEXPECTED_ENCODING.
189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    struct {
190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      EncodingClass encoding_class;
191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      EncodingType encoding_type;
192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    } unexpected_encoding_;
193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  };
194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Object Size //
198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const bool& b) {
201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(b));
202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overloads of GetSerializedSize() for standard integer types.
205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const char& c) {
206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(c));
207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const std::uint8_t& i) {
209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(i));
210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const std::int8_t& i) {
212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(i));
213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const std::uint16_t& i) {
215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(i));
216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const std::int16_t& i) {
218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(i));
219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const std::uint32_t& i) {
221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(i));
222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const std::int32_t& i) {
224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(i));
225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const std::uint64_t& i) {
227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(i));
228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const std::int64_t& i) {
230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(i));
231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const float& f) {
234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(f));
235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const double& d) {
237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(d));
238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for enum types.
241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline EnableIfEnum<T, std::size_t> GetSerializedSize(T v) {
243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetSerializedSize(static_cast<std::underlying_type_t<T>>(v));
244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Forward declaration for nested definitions.
247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const EmptyVariant&);
248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... Types>
249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const Variant<Types...>&);
250f6b5b93708333bf7ac746fa75f78d4b2acdf89c2Corey Tabakatemplate <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const T&);
252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const PointerWrapper<T>&);
254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const std::string&);
255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const StringWrapper<T>&);
257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const BufferWrapper<T>&);
259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <FileHandleMode Mode>
260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const FileHandle<Mode>&);
261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <ChannelHandleMode Mode>
262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const ChannelHandle<Mode>&);
263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const std::vector<T, Allocator>& v);
265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Compare, typename Allocator>
266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(
267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const std::map<Key, T, Compare, Allocator>& m);
268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Hash, typename KeyEqual,
269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          typename Allocator>
270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(
271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>&);
272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const ArrayWrapper<T>&);
274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, std::size_t Size>
275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const std::array<T, Size>& v);
276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename U>
277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const std::pair<T, U>& p);
278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const std::tuple<T...>& tuple);
280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for empty variant type.
282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const EmptyVariant& empty) {
283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(empty));
284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for Variant types.
287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... Types>
288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const Variant<Types...>& variant) {
289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(variant)) +
290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko         GetSerializedSize(variant.index()) +
291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko         variant.Visit(
292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko             [](const auto& value) { return GetSerializedSize(value); });
293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for structs/classes with SerializableMembers defined.
296f6b5b93708333bf7ac746fa75f78d4b2acdf89c2Corey Tabakatemplate <typename T, typename Enabled>
297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const T& value) {
298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return SerializableTraits<T>::GetSerializedSize(value);
299e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for PointerWrapper.
302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
303e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const PointerWrapper<T>& p) {
304e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetSerializedSize(p.Dereference());
305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for std::string.
308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const std::string& s) {
309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(s)) +
310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko         s.length() * sizeof(std::string::value_type);
311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for StringWrapper.
314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const StringWrapper<T>& s) {
316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(s)) +
317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko         s.length() * sizeof(typename StringWrapper<T>::value_type);
318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for BufferWrapper types.
321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const BufferWrapper<T>& b) {
323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(b)) +
324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko         b.size() * sizeof(typename BufferWrapper<T>::value_type);
325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for FileHandle. FileHandle is encoded as a FIXEXT2, with a type code
328e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// of "FileHandle" and a signed 16-bit offset into the pushed fd array. Empty
329e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// FileHandles are encoded with an array index of -1.
330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <FileHandleMode Mode>
331e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(const FileHandle<Mode>& fd) {
332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(fd)) + sizeof(std::int16_t);
333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for ChannelHandle. ChannelHandle is encoded as a FIXEXT4, with a
336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// type code of "ChannelHandle" and a signed 32-bit offset into the pushed
337e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// channel array. Empty ChannelHandles are encoded with an array index of -1.
338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <ChannelHandleMode Mode>
339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline constexpr std::size_t GetSerializedSize(
340e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const ChannelHandle<Mode>& channel_handle) {
341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(channel_handle)) + sizeof(std::int32_t);
342e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
343e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for standard vector types.
345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
346e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const std::vector<T, Allocator>& v) {
347e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                         [](const std::size_t& sum, const T& object) {
349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                           return sum + GetSerializedSize(object);
350e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                         });
351e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for standard map types.
354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Compare, typename Allocator>
355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(
356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const std::map<Key, T, Compare, Allocator>& v) {
357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return std::accumulate(
358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      [](const std::size_t& sum, const std::pair<Key, T>& object) {
360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return sum + GetSerializedSize(object.first) +
361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               GetSerializedSize(object.second);
362e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      });
363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
365e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for standard unordered_map types.
366e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Hash, typename KeyEqual,
367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          typename Allocator>
368e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(
369e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& v) {
370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return std::accumulate(
371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
372e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      [](const std::size_t& sum, const std::pair<Key, T>& object) {
373e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return sum + GetSerializedSize(object.first) +
374e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               GetSerializedSize(object.second);
375e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      });
376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
378e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for ArrayWrapper types.
379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
380e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const ArrayWrapper<T>& v) {
381e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
382e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                         [](const std::size_t& sum, const T& object) {
383e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                           return sum + GetSerializedSize(object);
384e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                         });
385e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
386e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
387e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for std::array types.
388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, std::size_t Size>
389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const std::array<T, Size>& v) {
390e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
391e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                         [](const std::size_t& sum, const T& object) {
392e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                           return sum + GetSerializedSize(object);
393e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                         });
394e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
395e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
396e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for std::pair.
397e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename U>
398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const std::pair<T, U>& p) {
399e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(p)) + GetSerializedSize(p.first) +
400e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko         GetSerializedSize(p.second);
401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
402e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
403e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Stops template recursion when the last tuple element is reached.
404e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
405e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetTupleSize(const std::tuple<T...>&, Index<0>) {
406e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return 0;
407e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
408e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
409e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Gets the size of each element in a tuple recursively.
410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T, std::size_t index>
411e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetTupleSize(const std::tuple<T...>& tuple, Index<index>) {
412e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetTupleSize(tuple, Index<index - 1>()) +
413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko         GetSerializedSize(std::get<index - 1>(tuple));
414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
415e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
416e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for tuple types. Gets the size of the tuple, recursing
417e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// through the elements.
418e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetSerializedSize(const std::tuple<T...>& tuple) {
420e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetEncodingSize(EncodeType(tuple)) +
421e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko         GetTupleSize(tuple, Index<sizeof...(T)>());
422e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
423e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
424e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Stops template recursion when the last member of a Serializable
425e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// type is reached.
426e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Members, typename T>
427e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetMemberSize(const T&, Index<0>) {
428e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return 0;
429e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
430e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
431e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Gets the size of each member of a Serializable type recursively.
432e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Members, typename T, std::size_t index>
433e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetMemberSize(const T& object, Index<index>) {
434e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetMemberSize<Members>(object, Index<index - 1>()) +
435e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko         GetSerializedSize(Members::template At<index - 1>::Resolve(object));
436e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
437e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
438e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Gets the size of a type using the given SerializableMembersType
439e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// type.
440e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Members, typename T>
441e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline std::size_t GetMembersSize(const T& object) {
442e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return GetMemberSize<Members>(object, Index<Members::MemberCount>());
443e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
444e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
446e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Object Serialization //
447e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
448e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
449e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//
450e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// SerializeRaw() converts a primitive array or type into a raw byte string.
451e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// These functions are named differently from SerializeObject() expressly to
452e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// avoid catch-all specialization of that template, which can be difficult to
453e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// detect otherwise.
454e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//
455e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
456e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void WriteRawData(void*& dest, const void* src, size_t size) {
457e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  memcpy(dest, src, size);
458e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  dest = static_cast<uint8_t*>(dest) + size;
459e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
460e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
461e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes a primitive array into a raw byte string.
462e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T,
463e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          typename = typename std::enable_if<std::is_pod<T>::value>::type>
464e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeRaw(const T& value, void*& buffer) {
465e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  WriteRawData(buffer, &value, sizeof(value));
466e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
467e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
468e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeEncoding(EncodingType encoding, void*& buffer) {
469e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeRaw(encoding, buffer);
470e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
471e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
472e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const bool& value, void*& buffer) {
473e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
474e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
475e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
476e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
477e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code, extended type code, and size for
478e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// extension types.
479e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeExtEncoding(EncodingType encoding,
480e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                 EncodingExtType ext_type, std::size_t size,
481e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                 void*& buffer) {
482e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
483e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_EXT8) {
484e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint8_t length = size;
485e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
486e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_EXT16) {
487e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint16_t length = size;
488e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
489e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_EXT32) {
490e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint32_t length = size;
491e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
492e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsFixextEncoding(encoding) */ {
493e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the fixext length, nothing else to do.
494e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
495e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeRaw(ext_type, buffer);
496e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
497e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
498e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for file descriptor types.
499e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <FileHandleMode Mode>
500e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const FileHandle<Mode>& value, void*& buffer) {
501e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeExtEncoding(EncodeType(value), ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 2,
502e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                       buffer);
503e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
504e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
505e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for channel handle types.
506e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <ChannelHandleMode Mode>
507e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const ChannelHandle<Mode>& handle, void*& buffer) {
508e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeExtEncoding(EncodeType(handle), ENCODING_EXT_TYPE_CHANNEL_HANDLE, 4,
509e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                       buffer);
510e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
511e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes type code for variant types.
513e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... Types>
514e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const Variant<Types...>& value, void*& buffer) {
515e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
516e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
517e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
518e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
519e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for string types.
520e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename StringType>
521e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeStringType(const StringType& value, void*& buffer) {
522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
523e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
524e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_STR8) {
525e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint8_t length = value.length();
526e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
527e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_STR16) {
528e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint16_t length = value.length();
529e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
530e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_STR32) {
531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint32_t length = value.length();
532e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
533e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsFixstrEncoding(encoding) */ {
534e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the fixstr length, nothing else to do.
535e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
536e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
537e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
538e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for std::string and StringWrapper. These types are
539e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// interchangeable and must serialize to the same format.
540e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const std::string& value, void*& buffer) {
541e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeStringType(value, buffer);
542e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
543e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const StringWrapper<T>& value, void*& buffer) {
545e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeStringType(value, buffer);
546e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
547e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
548e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for bin types.
549e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeBinEncoding(EncodingType encoding, std::size_t size,
550e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                 void*& buffer) {
551e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_BIN8) {
553e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint8_t length = size;
554e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
555e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_BIN16) {
556e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint16_t length = size;
557e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
558e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_BIN32) {
559e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint32_t length = size;
560e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
561e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
562e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Invalid encoding for BIN type.
563e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
564e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
565e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
566e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for BufferWrapper types.
567e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
568e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const BufferWrapper<T>& value, void*& buffer) {
569e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
570e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeBinEncoding(
571e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      encoding, value.size() * sizeof(typename BufferWrapper<T>::value_type),
572e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      buffer);
573e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
574e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
575e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the array encoding type and length.
576e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeArrayEncoding(EncodingType encoding, std::size_t size,
577e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   void*& buffer) {
578e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
579e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_ARRAY16) {
580e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint16_t length = size;
581e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
582e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_ARRAY32) {
583e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint32_t length = size;
584e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
585e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsFixarrayEncoding(encoding) */ {
586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the fixarray length, nothing else to do.
587e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
588e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
589e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the map encoding type and length.
591e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeMapEncoding(EncodingType encoding, std::size_t size,
592e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                 void*& buffer) {
593e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
594e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_MAP16) {
595e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint16_t length = size;
596e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
597e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_MAP32) {
598e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::uint32_t length = size;
599e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(length, buffer);
600e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsFixmapEncoding(encoding) */ {
601e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the fixmap length, nothing else to do.
602e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
603e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
604e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
605e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for array types.
606e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename ArrayType>
607e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeArrayType(const ArrayType& value, std::size_t size,
608e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                               void*& buffer) {
609e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
610e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeArrayEncoding(encoding, size, buffer);
611e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
612e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
613e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for map types.
614e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename MapType>
615e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeMapType(const MapType& value, std::size_t size,
616e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             void*& buffer) {
617e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
618e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeMapEncoding(encoding, size, buffer);
619e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
620e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
621e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for std::vector and ArrayWrapper. These types are
622e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// interchangeable and must serialize to the same format.
623e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
624e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const std::vector<T, Allocator>& value,
625e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                          void*& buffer) {
626e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeArrayType(value, value.size(), buffer);
627e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
628e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
629e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const ArrayWrapper<T>& value, void*& buffer) {
630e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeArrayType(value, value.size(), buffer);
631e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
632e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
633e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for std::array. This type serializes to the same
634e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// format as std::vector and ArrayWrapper and is interchangeable in certain
635e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// situations.
636e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, std::size_t Size>
637e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const std::array<T, Size>& value, void*& buffer) {
638e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeArrayType(value, Size, buffer);
639e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
640e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
641e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for std::map types.
642e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Compare, typename Allocator>
643e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const std::map<Key, T, Compare, Allocator>& value,
644e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                          void*& buffer) {
645e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeMapType(value, value.size(), buffer);
646e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
647e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
648e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for std::unordered_map types.
649e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Hash, typename KeyEqual,
650e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          typename Allocator>
651e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(
652e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& value,
653e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    void*& buffer) {
654e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeMapType(value, value.size(), buffer);
655e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
656e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
657e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for std::pair types.
658e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename U>
659e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const std::pair<T, U>& value, void*& buffer) {
660e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeArrayType(value, 2, buffer);
661e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
662e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
663e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the type code for std::tuple types.
664e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
665e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeType(const std::tuple<T...>& value, void*& buffer) {
666e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeArrayType(value, sizeof...(T), buffer);
667e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
668e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
669e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Specialization of SerializeObject for boolean type.
670e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const bool& value, MessageWriter* /*writer*/,
671e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
672e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(value, buffer);
673e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Encoding contains the boolean value, nothing else to do.
674e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
675e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
676e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overloads of SerializeObject for float and double types.
677e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const float& value, MessageWriter* /*writer*/,
678e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
679e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
680e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
681e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeRaw(value, buffer);
682e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
683e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
684e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const double& value, MessageWriter* /*writer*/,
685e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
686e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
687e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
688e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeRaw(value, buffer);
689e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
690e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
691e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overloads of SerializeObject() for standard integer types.
692e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const char& value, MessageWriter* /*writer*/,
693e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
694e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
695e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
696e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_UINT8) {
697e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(value, buffer);
698e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
699e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the value, nothing else to do.
700e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
701e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
702e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
703e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const int8_t& value, MessageWriter* /*writer*/,
704e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
705e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
706e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
707e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_INT8) {
708e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(value, buffer);
709e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsFixintEncoding(encoding) */ {
710e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the value, nothing else to do.
711e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
712e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
713e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
714e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const uint8_t& value, MessageWriter* /*writer*/,
715e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
716e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
717e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
718e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_UINT8) {
719e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(value, buffer);
720e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
721e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the value, nothing else to do.
722e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
723e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
724e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
725e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const int16_t& value, MessageWriter* /*writer*/,
726e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
727e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
728e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
729e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_INT8) {
730e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const int8_t byte = value;
731e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(byte, buffer);
732e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_INT16) {
733e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(value, buffer);
734e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsFixintEncoding(encoding) */ {
735e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the value, nothing else to do.
736e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
737e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
738e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
739e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const uint16_t& value, MessageWriter* /*writer*/,
740e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
741e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
742e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
743e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_UINT8) {
744e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const uint8_t byte = value;
745e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(byte, buffer);
746e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_UINT16) {
747e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(value, buffer);
748e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
749e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the value, nothing else to do.
750e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
751e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
752e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
753e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const int32_t& value, MessageWriter* /*writer*/,
754e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
755e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
756e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
757e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_INT8) {
758e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const int8_t byte = value;
759e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(byte, buffer);
760e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_INT16) {
761e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const int16_t half = value;
762e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(half, buffer);
763e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_INT32) {
764e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(value, buffer);
765e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsFixintEncoding(encoding) */ {
766e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the value, nothing else to do.
767e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
768e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
769e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
770e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const uint32_t& value, MessageWriter* /*writer*/,
771e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
772e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
773e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
774e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_UINT8) {
775e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const uint8_t byte = value;
776e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(byte, buffer);
777e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_UINT16) {
778e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const uint16_t half = value;
779e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(half, buffer);
780e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_UINT32) {
781e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(value, buffer);
782e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
783e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the value, nothing else to do.
784e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
785e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
786e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
787e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const int64_t& value, MessageWriter* /*writer*/,
788e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
789e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
790e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
791e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_INT8) {
792e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const int8_t byte = value;
793e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(byte, buffer);
794e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_INT16) {
795e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const int16_t half = value;
796e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(half, buffer);
797e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_INT32) {
798e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const int32_t word = value;
799e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(word, buffer);
800e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_INT64) {
801e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(value, buffer);
802e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsFixintEncoding(encoding) */ {
803e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the value, nothing else to do.
804e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
805e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
806e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
807e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const uint64_t& value, MessageWriter* /*writer*/,
808e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
809e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(value);
810e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
811e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (encoding == ENCODING_TYPE_UINT8) {
812e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const uint8_t byte = value;
813e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(byte, buffer);
814e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_UINT16) {
815e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const uint16_t half = value;
816e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(half, buffer);
817e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_UINT32) {
818e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const uint32_t word = value;
819e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(word, buffer);
820e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding == ENCODING_TYPE_UINT64) {
821e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeRaw(value, buffer);
822e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
823e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Encoding byte contains the value, nothing else to do.
824e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
825e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
826e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
827e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serialize enum types.
828e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
829e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline EnableIfEnum<T> SerializeObject(const T& value, MessageWriter* writer,
830e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                       void*& buffer) {
831e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeObject(static_cast<std::underlying_type_t<T>>(value), writer,
832e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                  buffer);
833e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
834e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
835e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Forward declaration for nested definitions.
836e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const EmptyVariant&, MessageWriter*, void*&);
837e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... Types>
838e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const Variant<Types...>&, MessageWriter*, void*&);
839f6b5b93708333bf7ac746fa75f78d4b2acdf89c2Corey Tabakatemplate <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
840e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const T&, MessageWriter*, void*&);
841e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
842e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const PointerWrapper<T>&, MessageWriter*, void*&);
843e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <FileHandleMode Mode>
844e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const FileHandle<Mode>&, MessageWriter*, void*&);
845e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <ChannelHandleMode Mode>
846e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const ChannelHandle<Mode>&, MessageWriter*, void*&);
847e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
848e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const BufferWrapper<std::vector<T, Allocator>>&, MessageWriter*, void*&);
849e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
850e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const BufferWrapper<T*>&, MessageWriter*, void*&);
851e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::string&, MessageWriter*, void*&);
852e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
853e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const StringWrapper<T>&, MessageWriter*, void*&);
854e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
855e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::vector<T, Allocator>&, MessageWriter*, void*&);
856e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
857e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const ArrayWrapper<T>&, MessageWriter*, void*&);
858e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, std::size_t Size>
859e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::array<T, Size>&, MessageWriter*, void*&);
860e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Compare, typename Allocator>
861e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::map<Key, T, Compare, Allocator>&, MessageWriter*, void*&);
862e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Hash, typename KeyEqual,
863e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          typename Allocator>
864e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(
865e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>&, MessageWriter*, void*&);
866e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename U>
867e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::pair<T, U>&, MessageWriter*, void*&);
868e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
869e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::tuple<T...>&, MessageWriter*, void*&);
870e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
871e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for empty variant type.
872e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const EmptyVariant& empty,
873e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            MessageWriter* /*writer*/, void*& buffer) {
874e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const EncodingType encoding = EncodeType(empty);
875e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeEncoding(encoding, buffer);
876e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
877e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
878e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for Variant types.
879e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... Types>
880e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const Variant<Types...>& variant,
881e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            MessageWriter* writer, void*& buffer) {
882e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(variant, buffer);
883e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeObject(variant.index(), writer, buffer);
884e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return variant.Visit([writer, &buffer](const auto& value) {
885e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return SerializeObject(value, writer, buffer);
886e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  });
887e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
888e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
889e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for serializable structure/class types.
890f6b5b93708333bf7ac746fa75f78d4b2acdf89c2Corey Tabakatemplate <typename T, typename Enabled>
891e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const T& value, MessageWriter* writer,
892e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
893e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializableTraits<T>::SerializeObject(value, writer, buffer);
894e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
895e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
896e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the payload of a PointerWrapper.
897e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
898e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const PointerWrapper<T>& pointer,
899e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            MessageWriter* writer, void*& buffer) {
900e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeObject(pointer.Dereference(), writer, buffer);
901e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
902e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
903e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the payload of file descriptor types.
904e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <FileHandleMode Mode>
905e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const FileHandle<Mode>& fd, MessageWriter* writer,
906e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
907e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(fd, buffer);
908f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  const Status<FileReference> status =
909e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      writer->GetOutputResourceMapper()->PushFileHandle(fd);
910f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  FileReference value = status ? status.get() : -status.error();
911e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeRaw(value, buffer);
912e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
913e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
914e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the payload of channel handle types.
915e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <ChannelHandleMode Mode>
916e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const ChannelHandle<Mode>& handle,
917e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            MessageWriter* writer, void*& buffer) {
918e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(handle, buffer);
919f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  const Status<ChannelReference> status =
920e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      writer->GetOutputResourceMapper()->PushChannelHandle(handle);
921f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  ChannelReference value = status ? status.get() : -status.error();
922e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeRaw(value, buffer);
923e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
924e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
925e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the payload of BufferWrapper types.
926e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
927e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const BufferWrapper<std::vector<T, Allocator>>& b,
928e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            MessageWriter* /*writer*/, void*& buffer) {
929e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto value_type_size =
930e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      sizeof(typename BufferWrapper<std::vector<T, Allocator>>::value_type);
931e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(b, buffer);
932e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  WriteRawData(buffer, b.data(), b.size() * value_type_size);
933e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
934e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
935e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const BufferWrapper<T*>& b,
936e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            MessageWriter* /*writer*/, void*& buffer) {
937e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto value_type_size = sizeof(typename BufferWrapper<T*>::value_type);
938e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(b, buffer);
939e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  WriteRawData(buffer, b.data(), b.size() * value_type_size);
940e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
941e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
942e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the payload of string types.
943e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename StringType>
944e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeString(const StringType& s, void*& buffer) {
945e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto value_type_size = sizeof(typename StringType::value_type);
946e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(s, buffer);
947e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  WriteRawData(buffer, s.data(), s.length() * value_type_size);
948e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
949e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
950e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload of SerializeObject() for std::string and StringWrapper. These types
951e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// are interchangeable and must serialize to the same format.
952e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::string& s, MessageWriter* /*writer*/,
953e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
954e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeString(s, buffer);
955e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
956e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
957e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const StringWrapper<T>& s,
958e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            MessageWriter* /*writer*/, void*& buffer) {
959e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeString(s, buffer);
960e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
961e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
962e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the payload of array types.
963e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename ArrayType>
964e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeArray(const ArrayType& v, MessageWriter* writer,
965e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                           void*& buffer) {
966e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(v, buffer);
967e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (const auto& element : v)
968e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeObject(element, writer, buffer);
969e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
970e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
971e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the payload for map types.
972e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename MapType>
973e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeMap(const MapType& v, MessageWriter* writer,
974e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                         void*& buffer) {
975e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(v, buffer);
976e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (const auto& element : v) {
977e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeObject(element.first, writer, buffer);
978e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    SerializeObject(element.second, writer, buffer);
979e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
980e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
981e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
982e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload of SerializeObject() for std::vector and ArrayWrapper types. These
983e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// types are interchangeable and must serialize to the same format.
984e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
985e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::vector<T, Allocator>& v,
986e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            MessageWriter* writer, void*& buffer) {
987e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeArray(v, writer, buffer);
988e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
989e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
990e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const ArrayWrapper<T>& v, MessageWriter* writer,
991e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
992e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeArray(v, writer, buffer);
993e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
994e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
995e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload of SerializeObject() for std::array types. These types serialize to
996e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// the same format at std::vector and ArrayWrapper and are interchangeable in
997e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// certain situations.
998e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, std::size_t Size>
999e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::array<T, Size>& v, MessageWriter* writer,
1000e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
1001e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeArray(v, writer, buffer);
1002e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1003e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1004e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload of SerializeObject() for std::map types.
1005e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Compare, typename Allocator>
1006e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::map<Key, T, Compare, Allocator>& v,
1007e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            MessageWriter* writer, void*& buffer) {
1008e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeMap(v, writer, buffer);
1009e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1010e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1011e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload of SerializeObject() for std::unordered_map types.
1012e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Hash, typename KeyEqual,
1013e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          typename Allocator>
1014e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(
1015e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& v,
1016e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    MessageWriter* writer, void*& buffer) {
1017e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeMap(v, writer, buffer);
1018e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1019e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1020e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload of SerializeObject() for std:pair types.
1021e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename U>
1022e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::pair<T, U>& pair, MessageWriter* writer,
1023e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer) {
1024e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(pair, buffer);
1025e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeObject(pair.first, writer, buffer);
1026e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeObject(pair.second, writer, buffer);
1027e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1028e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1029e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Stops template recursion when the last tuple element is reached.
1030e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
1031e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeTuple(const std::tuple<T...>&, MessageWriter*, void*&,
1032e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                           Index<0>) {}
1033e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1034e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes each element of a tuple recursively.
1035e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T, std::size_t index>
1036e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeTuple(const std::tuple<T...>& tuple, MessageWriter* writer,
1037e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                           void*& buffer, Index<index>) {
1038e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeTuple(tuple, writer, buffer, Index<index - 1>());
1039e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeObject(std::get<index - 1>(tuple), writer, buffer);
1040e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1041e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1042e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload of SerializeObject() for tuple types.
1043e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
1044e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeObject(const std::tuple<T...>& tuple,
1045e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            MessageWriter* writer, void*& buffer) {
1046e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeType(tuple, buffer);
1047e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeTuple(tuple, writer, buffer, Index<sizeof...(T)>());
1048e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1049e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1050e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Stops template recursion when the last member pointer is reached.
1051e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Members, typename T>
1052e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeMember(const T&, MessageWriter*, void*&, Index<0>) {}
1053e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1054e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes each member pointer recursively.
1055e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Members, typename T, std::size_t index>
1056e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeMember(const T& object, MessageWriter* writer,
1057e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            void*& buffer, Index<index>) {
1058e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeMember<Members>(object, writer, buffer, Index<index - 1>());
1059e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeObject(Members::template At<index - 1>::Resolve(object), writer,
1060e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                  buffer);
1061e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1062e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1063e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Serializes the members of a type using the given SerializableMembersType
1064e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// type.
1065e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Members, typename T>
1066e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void SerializeMembers(const T& object, MessageWriter* writer,
1067e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             void*& buffer) {
1068e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeMember<Members>(object, writer, buffer,
1069e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                           Index<Members::MemberCount>());
1070e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1071e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1072e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Top level serialization function that replaces the buffer's contents.
1073e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1074e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline void Serialize(const T& object, MessageWriter* writer) {
1075e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Serialize");
1076e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const std::size_t size = GetSerializedSize(object);
1077e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1078e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Reserve the space needed for the object(s).
1079e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void* buffer = writer->GetNextWriteBufferSection(size);
1080e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializeObject(object, writer, buffer);
1081e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1082e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1083e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
1084e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Object Deserialization //
1085e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
1086e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1087e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType ReadRawDataFromNextSection(void* dest, MessageReader* reader,
1088e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                            const void*& start,
1089e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                            const void*& end, size_t size) {
1090e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  while (AdvancePointer(start, size) > end) {
1091e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    auto remaining_size = PointerDistance(end, start);
1092e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (remaining_size > 0) {
1093e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      memcpy(dest, start, remaining_size);
1094e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      dest = AdvancePointer(dest, remaining_size);
1095e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      size -= remaining_size;
1096e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
1097e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    reader->ConsumeReadBufferSectionData(AdvancePointer(start, remaining_size));
1098e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::tie(start, end) = reader->GetNextReadBufferSection();
1099e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (start == end)
1100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return ErrorCode::INSUFFICIENT_BUFFER;
1101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  memcpy(dest, start, size);
1103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  start = AdvancePointer(start, size);
1104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ErrorCode::NO_ERROR;
1105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType ReadRawData(void* dest, MessageReader* /*reader*/,
1108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             const void*& start, const void*& end,
1109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             size_t size) {
1110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (PDX_UNLIKELY(AdvancePointer(start, size) > end)) {
1111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // TODO(avakulenko): Enabling reading from next sections of input buffer
1112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // (using ReadRawDataFromNextSection) screws up clang compiler optimizations
1113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // (probably inefficient inlining) making the whole deserialization
1114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // code path about twice as slow. Investigate and enable more generic
1115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // deserialization code, but right now we don't really need/support this
1116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // scenario, so I keep this commented out for the time being...
1117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // return ReadRawDataFromNextSection(dest, reader, start, end, size);
1119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::INSUFFICIENT_BUFFER;
1120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  memcpy(dest, start, size);
1122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  start = AdvancePointer(start, size);
1123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ErrorCode::NO_ERROR;
1124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes a primitive object from raw bytes.
1127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T,
1128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          typename = typename std::enable_if<std::is_pod<T>::value>::type>
1129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeRaw(T* value, MessageReader* reader,
1130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                const void*& start, const void*& end) {
1131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ReadRawData(value, reader, start, end, sizeof(T));
1132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Utility to deserialize POD types when the serialized type is different
1135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// (smaller) than the target real type. This happens when values are serialized
1136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// into more compact encodings.
1137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename SerializedType, typename RealType>
1138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoErrorType DeserializeValue(RealType* real_value, MessageReader* reader,
1139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                           const void*& start, const void*& end) {
1140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  SerializedType serialized_value;
1141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeRaw(&serialized_value, reader, start, end)) {
1143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *real_value = serialized_value;
1146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeEncoding(EncodingType* encoding,
1151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                     MessageReader* reader, const void*& start,
1152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                     const void*& end) {
1153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return DeserializeRaw(encoding, reader, start, end);
1154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload to deserialize bool type.
1157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(bool* value, MessageReader* reader,
1158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsBoolEncoding(encoding)) {
1163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = (encoding == ENCODING_TYPE_TRUE);
1164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_BOOL,
1167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Specializations to deserialize float and double types.
1172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(float* value, MessageReader* reader,
1173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFloat32Encoding(encoding)) {
1178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<float>(value, reader, start, end);
1179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_FLOAT,
1181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(double* value, MessageReader* reader,
1186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFloat32Encoding(encoding)) {
1191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<float>(value, reader, start, end);
1192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFloat64Encoding(encoding)) {
1193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<double>(value, reader, start, end);
1194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_FLOAT,
1196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Specializations to deserialize standard integer types.
1201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(char* value, MessageReader* reader,
1202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUnsignedFixintEncoding(encoding)) {
1207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = static_cast<char>(encoding);
1208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt8Encoding(encoding)) {
1210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<char>(value, reader, start, end);
1211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
1213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::int8_t* value, MessageReader* reader,
1218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFixintEncoding(encoding)) {
1223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = static_cast<std::int8_t>(encoding);
1224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsInt8Encoding(encoding)) {
1226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::int8_t>(value, reader, start, end);
1227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
1229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::uint8_t* value, MessageReader* reader,
1234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUnsignedFixintEncoding(encoding)) {
1239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = encoding;
1240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt8Encoding(encoding)) {
1242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint8_t>(value, reader, start, end);
1243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
1245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::int16_t* value, MessageReader* reader,
1250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFixintEncoding(encoding)) {
1255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = static_cast<std::int8_t>(encoding);
1256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsInt8Encoding(encoding)) {
1258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::int8_t>(value, reader, start, end);
1259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsInt16Encoding(encoding)) {
1260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::int16_t>(value, reader, start, end);
1261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
1263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::uint16_t* value, MessageReader* reader,
1268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUnsignedFixintEncoding(encoding)) {
1273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = encoding;
1274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt8Encoding(encoding)) {
1276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint8_t>(value, reader, start, end);
1277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt16Encoding(encoding)) {
1278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint16_t>(value, reader, start, end);
1279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
1281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::int32_t* value, MessageReader* reader,
1286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFixintEncoding(encoding)) {
1291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = static_cast<std::int8_t>(encoding);
1292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsInt8Encoding(encoding)) {
1294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::int8_t>(value, reader, start, end);
1295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsInt16Encoding(encoding)) {
1296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::int16_t>(value, reader, start, end);
1297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsInt32Encoding(encoding)) {
1298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::int32_t>(value, reader, start, end);
1299e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
1301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1303e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1304e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::uint32_t* value, MessageReader* reader,
1306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUnsignedFixintEncoding(encoding)) {
1311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = encoding;
1312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt8Encoding(encoding)) {
1314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint8_t>(value, reader, start, end);
1315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt16Encoding(encoding)) {
1316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint16_t>(value, reader, start, end);
1317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt32Encoding(encoding)) {
1318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint32_t>(value, reader, start, end);
1319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
1321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::int64_t* value, MessageReader* reader,
1326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1328e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1329e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFixintEncoding(encoding)) {
1331e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = static_cast<std::int8_t>(encoding);
1332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsInt8Encoding(encoding)) {
1334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::int8_t>(value, reader, start, end);
1335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsInt16Encoding(encoding)) {
1336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::int16_t>(value, reader, start, end);
1337e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsInt32Encoding(encoding)) {
1338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::int32_t>(value, reader, start, end);
1339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsInt64Encoding(encoding)) {
1340e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::int64_t>(value, reader, start, end);
1341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1342e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
1343e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1346e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1347e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::uint64_t* value, MessageReader* reader,
1348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1350e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1351e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUnsignedFixintEncoding(encoding)) {
1353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = encoding;
1354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt8Encoding(encoding)) {
1356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint8_t>(value, reader, start, end);
1357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt16Encoding(encoding)) {
1358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint16_t>(value, reader, start, end);
1359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt32Encoding(encoding)) {
1360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint32_t>(value, reader, start, end);
1361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsUInt64Encoding(encoding)) {
1362e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint64_t>(value, reader, start, end);
1363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
1365e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1366e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1368e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1369e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline EnableIfEnum<T, ErrorType> DeserializeObject(T* value,
1371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                                    MessageReader* reader,
1372e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                                    const void*& start,
1373e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                                    const void*& end) {
1374e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::underlying_type_t<T> enum_value;
1375e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ErrorType error = DeserializeObject(&enum_value, reader, start, end);
1376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!error)
1377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *value = static_cast<T>(enum_value);
1378e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return error;
1379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1380e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1381e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Forward declarations for nested definitions.
1382f6b5b93708333bf7ac746fa75f78d4b2acdf89c2Corey Tabakatemplate <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
1383e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(T*, MessageReader*, const void*&,
1384e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&);
1385e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1386e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(PointerWrapper<T>*, MessageReader*,
1387e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(LocalHandle*, MessageReader*, const void*&,
1389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&);
1390e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(LocalChannelHandle*, MessageReader*,
1391e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1392e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
1393e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(BufferWrapper<std::vector<T, Allocator>>*,
1394e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader*, const void*&, const void*&);
1395e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1396e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(BufferWrapper<T*>*, MessageReader*,
1397e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::string*, MessageReader*, const void*&,
1399e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&);
1400e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(StringWrapper<T>*, MessageReader*,
1402e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1403e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename U>
1404e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::pair<T, U>*, MessageReader*,
1405e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1406e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
1407e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::tuple<T...>*, MessageReader*,
1408e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1409e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
1410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::vector<T, Allocator>*, MessageReader*,
1411e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1412e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Compare, typename Allocator>
1413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::map<Key, T, Compare, Allocator>*,
1414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader*, const void*&, const void*&);
1415e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Hash, typename KeyEqual,
1416e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          typename Allocator>
1417e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(
1418e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::unordered_map<Key, T, Hash, KeyEqual, Allocator>*, MessageReader*,
1419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const void*&, const void*&);
1420e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1421e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(ArrayWrapper<T>*, MessageReader*,
1422e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1423e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, std::size_t Size>
1424e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::array<T, Size>*, MessageReader*,
1425e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1426e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename U>
1427e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::pair<T, U>*, MessageReader*,
1428e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1429e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
1430e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::tuple<T...>*, MessageReader*,
1431e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&, const void*&);
1432e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(EmptyVariant*,
1433e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader*, const void*&,
1434e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&);
1435e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... Types>
1436e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(Variant<Types...>*,
1437e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader*, const void*&,
1438e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*&);
1439e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1440e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes a Serializable type.
1441f6b5b93708333bf7ac746fa75f78d4b2acdf89c2Corey Tabakatemplate <typename T, typename Enable>
1442e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(T* value, MessageReader* reader,
1443e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1444e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return SerializableTraits<T>::DeserializeObject(value, reader, start, end);
1445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1446e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1447e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes a PointerWrapper.
1448e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1449e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(PointerWrapper<T>* pointer,
1450e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1451e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1452e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return DeserializeObject(&pointer->Dereference(), reader, start, end);
1453e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1454e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1455e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes the type code and size for extension types.
1456e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeExtType(EncodingType* encoding,
1457e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                    EncodingExtType* type, std::size_t* size,
1458e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                    MessageReader* reader, const void*& start,
1459e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                    const void*& end) {
1460e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
1461e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1462e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFixextEncoding(*encoding)) {
1463e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *size = GetFixextSize(*encoding);
1464e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_EXT8) {
1465e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error =
1466e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            DeserializeValue<std::uint8_t>(size, reader, start, end))
1467e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1468e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_EXT16) {
1469e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error =
1470e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            DeserializeValue<std::uint16_t>(size, reader, start, end))
1471e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1472e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_EXT32) {
1473e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error =
1474e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            DeserializeValue<std::uint32_t>(size, reader, start, end))
1475e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1476e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1477e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
1478e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     *encoding);
1479e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1480e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1481e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // The extension type code follows the encoding and size.
1482e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return DeserializeRaw(type, reader, start, end);
1483e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1484e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1485e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes a file handle and performs handle space translation, if
1486e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// required.
1487e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(LocalHandle* value, MessageReader* reader,
1488e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1489e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1490e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingExtType type;
1491e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1492e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1493e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1494e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeExtType(&encoding, &type, &size, reader, start, end)) {
1495e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1496e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (size != 2) {
1497e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_EXTENSION,
1498e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1499e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (type == ENCODING_EXT_TYPE_FILE_DESCRIPTOR) {
1500e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Read the encoded file descriptor value.
1501e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    FileReference ref;
1502e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error = DeserializeRaw(&ref, reader, start, end)) {
1503e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1504e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
1505e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1506e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return reader->GetInputResourceMapper()->GetFileHandle(ref, value)
1507e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               ? ErrorCode::NO_ERROR
1508e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               : ErrorCode::GET_FILE_DESCRIPTOR_FAILED;
1509e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1510e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
1511e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1513e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1514e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1515e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(LocalChannelHandle* value,
1516e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1517e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1518e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1519e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingExtType type;
1520e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1521e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1523e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeExtType(&encoding, &type, &size, reader, start, end)) {
1524e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1525e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (size != 4) {
1526e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_EXTENSION,
1527e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1528e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (type == ENCODING_EXT_TYPE_CHANNEL_HANDLE) {
1529e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Read the encoded channel handle value.
1530e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    ChannelReference ref;
1531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error = DeserializeRaw(&ref, reader, start, end)) {
1532e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1533e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
1534e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return reader->GetInputResourceMapper()->GetChannelHandle(ref, value)
1535e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               ? ErrorCode::NO_ERROR
1536e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               : ErrorCode::GET_CHANNEL_HANDLE_FAILED;
1537e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1538e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
1539e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1540e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1541e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1542e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1543e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes the type code and size for bin types.
1544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeBinType(EncodingType* encoding, std::size_t* size,
1545e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                    MessageReader* reader, const void*& start,
1546e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                    const void*& end) {
1547e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
1548e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1549e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_BIN8) {
1550e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint8_t>(size, reader, start, end);
1551e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_BIN16) {
1552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint16_t>(size, reader, start, end);
1553e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_BIN32) {
1554e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint32_t>(size, reader, start, end);
1555e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1556e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_BINARY,
1557e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     *encoding);
1558e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1559e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1560e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1561e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload of DeserializeObject() for BufferWrapper types.
1562e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
1563e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(
1564e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    BufferWrapper<std::vector<T, Allocator>>* value, MessageReader* reader,
1565e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const void*& start, const void*& end) {
1566e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto value_type_size =
1567e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      sizeof(typename BufferWrapper<std::vector<T, Allocator>>::value_type);
1568e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1569e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1570e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1571e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1572e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeBinType(&encoding, &size, reader, start, end))
1573e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1574e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1575e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Try to resize the BufferWrapper to the size of the payload.
1576e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  value->resize(size / value_type_size);
1577e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1578e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (size > value->size() * value_type_size || size % value_type_size != 0) {
1579e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
1580e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (size == 0U) {
1581e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1582e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1583e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReadRawData(value->data(), reader, start, end, size);
1584e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1585e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1587e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(BufferWrapper<T*>* value,
1588e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1589e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto value_type_size = sizeof(typename BufferWrapper<T*>::value_type);
1591e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1592e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1593e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1594e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1595e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeBinType(&encoding, &size, reader, start, end))
1596e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1597e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1598e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Try to resize the BufferWrapper to the size of the payload.
1599e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  value->resize(size / value_type_size);
1600e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1601e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (size > value->size() * value_type_size || size % value_type_size != 0) {
1602e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
1603e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (size == 0U) {
1604e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1605e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1606e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReadRawData(value->data(), reader, start, end, size);
1607e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1608e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1609e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1610e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes the type code and size for string types.
1611e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeStringType(EncodingType* encoding,
1612e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                       std::size_t* size, MessageReader* reader,
1613e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                       const void*& start, const void*& end) {
1614e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
1615e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1616e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFixstrEncoding(*encoding)) {
1617e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *size = GetFixstrSize(*encoding);
1618e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1619e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_STR8) {
1620e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint8_t>(size, reader, start, end);
1621e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_STR16) {
1622e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint16_t>(size, reader, start, end);
1623e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_STR32) {
1624e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint32_t>(size, reader, start, end);
1625e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1626e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_STRING,
1627e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     *encoding);
1628e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1629e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1630e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1631e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload of DeserializeObject() for std::string types.
1632e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::string* value, MessageReader* reader,
1633e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end) {
1634e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1635e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1636e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1637e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1638e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeStringType(&encoding, &size, reader, start, end)) {
1639e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1640e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (size == 0U) {
1641e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    value->clear();
1642e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1643e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1644e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    value->resize(size);
1645e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReadRawData(&(*value)[0], reader, start, end, size);
1646e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1647e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1648e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1649e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload of DeserializeObject() for StringWrapper types.
1650e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1651e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(StringWrapper<T>* value,
1652e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1653e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1654e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto value_type_size = sizeof(typename StringWrapper<T>::value_type);
1655e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1656e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1657e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1658e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1659e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeStringType(&encoding, &size, reader, start, end))
1660e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1661e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1662e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Try to resize the StringWrapper to the size of the payload
1663e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // string.
1664e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  value->resize(size / value_type_size);
1665e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1666e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (size > value->length() * value_type_size || size % value_type_size != 0) {
1667e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
1668e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (size == 0U) {
1669e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1670e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1671e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReadRawData(value->data(), reader, start, end, size);
1672e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1673e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1674e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1675e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes the type code and size of array types.
1676e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeArrayType(EncodingType* encoding, std::size_t* size,
1677e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                      MessageReader* reader, const void*& start,
1678e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                      const void*& end) {
1679e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
1680e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1681e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFixarrayEncoding(*encoding)) {
1682e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *size = GetFixarraySize(*encoding);
1683e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1684e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_ARRAY16) {
1685e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint16_t>(size, reader, start, end);
1686e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_ARRAY32) {
1687e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint32_t>(size, reader, start, end);
1688e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1689e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_ARRAY,
1690e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     *encoding);
1691e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1692e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1693e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1694e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes the type code and size of map types.
1695e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeMapType(EncodingType* encoding, std::size_t* size,
1696e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                    MessageReader* reader, const void*& start,
1697e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                    const void*& end) {
1698e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
1699e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1700e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (IsFixmapEncoding(*encoding)) {
1701e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *size = GetFixmapSize(*encoding);
1702e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1703e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_MAP16) {
1704e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint16_t>(size, reader, start, end);
1705e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (*encoding == ENCODING_TYPE_MAP32) {
1706e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeValue<std::uint32_t>(size, reader, start, end);
1707e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1708e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_MAP,
1709e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     *encoding);
1710e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1711e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1712e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1713e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for std::vector types.
1714e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename Allocator>
1715e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::vector<T, Allocator>* value,
1716e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1717e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1718e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1719e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1720e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1721e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1722e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeArrayType(&encoding, &size, reader, start, end))
1723e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1724e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1725e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::vector<T, Allocator> result(size);
1726e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (std::size_t i = 0; i < size; i++) {
1727e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error = DeserializeObject(&result[i], reader, start, end))
1728e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1729e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1730e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1731e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  *value = std::move(result);
1732e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ErrorCode::NO_ERROR;
1733e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1734e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// TODO(eieio): Consider the benefits and trade offs of this alternative.
1735e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#if 0
1736e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  value->resize(size);
1737e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (std::size_t i = 0; i < size; i++) {
1738e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
1739e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1740e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1741e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ErrorCode::NO_ERROR;
1742e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif
1743e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1744e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1745e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes an EmptyVariant value.
1746e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(EmptyVariant* /*empty*/,
1747e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1748e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1749e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1750e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1751e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
1752e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1753e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (encoding != ENCODING_TYPE_NIL) {
1754e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_MAP,
1755e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1756e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1757e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1758e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1759e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1760e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1761e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes a Variant type.
1762e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... Types>
1763e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(Variant<Types...>* variant,
1764e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1765e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1766e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1767e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1768e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1769e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1770e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeMapType(&encoding, &size, reader, start, end)) {
1771e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1772e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1773e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1774e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (size != 1)
1775e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_MAP,
1776e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     encoding);
1777e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1778e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::int32_t type;
1779e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeObject(&type, reader, start, end)) {
1780e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1781e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (type < Variant<Types...>::kEmptyIndex ||
1782e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko             type >= static_cast<std::int32_t>(sizeof...(Types))) {
1783e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::INVALID_VARIANT_ELEMENT;
1784e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1785e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    variant->Become(type);
1786e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return variant->Visit([reader, &start, &end](auto&& value) {
1787e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return DeserializeObject(&value, reader, start, end);
1788e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    });
1789e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1790e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1791e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1792e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes map types.
1793e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename MapType>
1794e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeMap(MapType* value, MessageReader* reader,
1795e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                const void*& start, const void*& end) {
1796e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1797e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1798e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1799e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1800e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeMapType(&encoding, &size, reader, start, end))
1801e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1802e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1803e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  MapType result;
1804e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (std::size_t i = 0; i < size; i++) {
1805e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::pair<typename MapType::key_type, typename MapType::mapped_type>
1806e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        element;
1807e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error =
1808e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            DeserializeObject(&element.first, reader, start, end))
1809e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1810e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error =
1811e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            DeserializeObject(&element.second, reader, start, end))
1812e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1813e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    result.emplace(std::move(element));
1814e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1815e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1816e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  *value = std::move(result);
1817e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ErrorCode::NO_ERROR;
1818e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1819e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1820e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for std::map types.
1821e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Compare, typename Allocator>
1822e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::map<Key, T, Compare, Allocator>* value,
1823e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1824e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1825e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return DeserializeMap(value, reader, start, end);
1826e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1827e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1828e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for std::unordered_map types.
1829e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Key, typename T, typename Hash, typename KeyEqual,
1830e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          typename Allocator>
1831e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(
1832e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::unordered_map<Key, T, Hash, KeyEqual, Allocator>* value,
1833e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    MessageReader* reader, const void*& start, const void*& end) {
1834e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return DeserializeMap(value, reader, start, end);
1835e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1836e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1837e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for ArrayWrapper types.
1838e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1839e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(ArrayWrapper<T>* value,
1840e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1841e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1842e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1843e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1844e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1845e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1846e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeArrayType(&encoding, &size, reader, start, end)) {
1847e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1848e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1849e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1850e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Try to resize the wrapper.
1851e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  value->resize(size);
1852e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1853e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Make sure there is enough space in the ArrayWrapper for the
1854e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // payload.
1855e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (size > value->capacity())
1856e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
1857e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1858e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (std::size_t i = 0; i < size; i++) {
1859e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
1860e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1861e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1862e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1863e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ErrorCode::NO_ERROR;
1864e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1865e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1866e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for std::array types.
1867e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, std::size_t Size>
1868e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::array<T, Size>* value,
1869e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1870e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1871e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1872e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1873e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1874e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1875e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeArrayType(&encoding, &size, reader, start, end)) {
1876e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1877e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1878e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1879e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (size != Size)
1880e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
1881e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1882e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  for (std::size_t i = 0; i < size; i++) {
1883e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
1884e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return error;
1885e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1886e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1887e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ErrorCode::NO_ERROR;
1888e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1889e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1890e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes std::pair types.
1891e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T, typename U>
1892e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::pair<T, U>* value,
1893e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1894e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1895e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1896e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1897e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1898e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1899e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeArrayType(&encoding, &size, reader, start, end)) {
1900e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1901e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (size != 2) {
1902e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::UNEXPECTED_TYPE_SIZE;
1903e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (const auto error =
1904e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                 DeserializeObject(&value->first, reader, start, end)) {
1905e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1906e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (const auto error =
1907e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                 DeserializeObject(&value->second, reader, start, end)) {
1908e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1909e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1910e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::NO_ERROR;
1911e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1912e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1913e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1914e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Stops template recursion when the last tuple element is reached.
1915e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
1916e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeTuple(std::tuple<T...>*, MessageReader*,
1917e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                  const void*&, const void*, Index<0>) {
1918e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ErrorCode::NO_ERROR;
1919e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1920e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1921e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes each element of a tuple recursively.
1922e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T, std::size_t index>
1923e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeTuple(std::tuple<T...>* tuple,
1924e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                  MessageReader* reader, const void*& start,
1925e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                  const void*& end, Index<index>) {
1926e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1927e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeTuple(tuple, reader, start, end, Index<index - 1>()))
1928e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1929e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  else
1930e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeObject(&std::get<index - 1>(*tuple), reader, start, end);
1931e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1932e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1933e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Overload for standard tuple types.
1934e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename... T>
1935e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeObject(std::tuple<T...>* value,
1936e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   MessageReader* reader, const void*& start,
1937e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& end) {
1938e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EncodingType encoding;
1939e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::size_t size;
1940e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1941e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error =
1942e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          DeserializeArrayType(&encoding, &size, reader, start, end)) {
1943e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1944e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (size != sizeof...(T)) {
1945e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::UNEXPECTED_TYPE_SIZE;
1946e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
1947e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeTuple(value, reader, start, end, Index<sizeof...(T)>());
1948e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
1949e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1950e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1951e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Stops template recursion when the last member of a Serializable type is
1952e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// reached.
1953e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Members, typename T>
1954e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeMember(T*, MessageReader*, const void*&,
1955e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*, Index<0>) {
1956e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ErrorCode::NO_ERROR;
1957e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1958e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1959e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes each member of a Serializable type recursively.
1960e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Members, typename T, std::size_t index>
1961e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeMember(T* value, MessageReader* reader,
1962e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   const void*& start, const void*& end,
1963e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                   Index<index>) {
1964e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (const auto error = DeserializeMember<Members>(value, reader, start, end,
1965e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                                    Index<index - 1>()))
1966e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return error;
1967e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  else
1968e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return DeserializeObject(&Members::template At<index - 1>::Resolve(*value),
1969e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             reader, start, end);
1970e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1971e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1972e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Deserializes the members of a Serializable type using the given
1973e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// SerializableMembersType type.
1974e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename Members, typename T>
1975e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType DeserializeMembers(T* value, MessageReader* reader,
1976e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                    const void*& start, const void*& end) {
1977e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return DeserializeMember<Members>(value, reader, start, end,
1978e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                    Index<Members::MemberCount>());
1979e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1980e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1981e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Top level deserialization function.
1982e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename T>
1983e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoinline ErrorType Deserialize(T* value, MessageReader* reader) {
1984e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Deserialize");
1985e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  MessageReader::BufferSection section = reader->GetNextReadBufferSection();
1986e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (section.first == section.second)
1987e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorCode::INSUFFICIENT_BUFFER;
1988e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ErrorType error =
1989e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      DeserializeObject(value, reader, section.first, section.second);
1990e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  reader->ConsumeReadBufferSectionData(section.first);
1991e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return error;
1992e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
1993e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1994e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace rpc
1995e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace pdx
1996e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace android
1997e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1998e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif  // ANDROID_PDX_RPC_SERIALIZATION_H_
1999