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