#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace android::pdx; using namespace android::pdx::rpc; // Tests the serialization/deserialization of all supported types, verifying all // reasonable boundary conditions for types with multiple encodings. // // NOTE: Sometimes this file uses the construct "var = decltype(var)({...})" // instead of the equivalent "var = {...}" to construct vectors. This is to // prevent clang-format from producing annoyingly vertical code from long // initializers. // TODO(eieio): Automatically generate some of these tests? namespace { // Test data for serialization/deserialization of floats. const float kZeroFloat = 0.0f; const float kOneFloat = 1.0f; const auto kZeroFloatBytes = reinterpret_cast(&kZeroFloat); const auto kOneFloatBytes = reinterpret_cast(&kOneFloat); const double kZeroDouble = 0.0; const double kOneDouble = 1.0; const auto kZeroDoubleBytes = reinterpret_cast(&kZeroDouble); const auto kOneDoubleBytes = reinterpret_cast(&kOneDouble); struct TestType { enum class Foo { kFoo, kBar, kBaz }; int a; float b; std::string c; Foo d; TestType() {} TestType(int a, float b, const std::string& c, Foo d) : a(a), b(b), c(c), d(d) {} // Make gtest expressions simpler by defining equality operator. This is not // needed for serialization. bool operator==(const TestType& other) const { return a == other.a && b == other.b && c == other.c && d == other.d; } private: PDX_SERIALIZABLE_MEMBERS(TestType, a, b, c, d); }; template struct TestTemplateType { FileHandleType fd; TestTemplateType() {} explicit TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {} bool operator==(const TestTemplateType& other) const { return fd.Get() == other.fd.Get(); } private: PDX_SERIALIZABLE_MEMBERS(TestTemplateType, fd); }; // Utilities to generate test maps and payloads. template MapType MakeMap(std::size_t size) { MapType result; for (std::size_t i = 0; i < size; i++) { result.emplace(i, i); } return result; } template void InsertKeyValue(MessageWriter* writer, std::size_t size) { MapType map; for (std::size_t i = 0; i < size; i++) { map.emplace(i, i); } for (const auto& element : map) { Serialize(element.first, writer); Serialize(element.second, writer); } } } // anonymous namespace TEST(SerializableTypes, Constructor) { TestType tt(1, 2.0, "three", TestType::Foo::kBar); EXPECT_EQ(1, tt.a); EXPECT_EQ(2.0, tt.b); EXPECT_EQ("three", tt.c); EXPECT_EQ(TestType::Foo::kBar, tt.d); } TEST(SerializationTest, bool) { Payload result; Payload expected; bool value; // True. value = true; Serialize(value, &result); expected = {ENCODING_TYPE_TRUE}; EXPECT_EQ(expected, result); result.Clear(); // False. value = false; Serialize(value, &result); expected = {ENCODING_TYPE_FALSE}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, uint8_t) { Payload result; Payload expected; uint8_t value; // Min FIXINT. value = 0; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXINT. value = (1 << 7) - 1; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min UINT8. value = (1 << 7); Serialize(value, &result); expected = {ENCODING_TYPE_UINT8, (1 << 7)}; EXPECT_EQ(expected, result); result.Clear(); // Max UINT8. value = 0xff; Serialize(value, &result); expected = {ENCODING_TYPE_UINT8, 0xff}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, uint16_t) { Payload result; Payload expected; uint16_t value; // Min FIXINT. value = 0; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXINT. value = (1 << 7) - 1; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min UINT8. value = (1 << 7); Serialize(value, &result); expected = {ENCODING_TYPE_UINT8, (1 << 7)}; EXPECT_EQ(expected, result); result.Clear(); // Max UINT8. value = 0xff; Serialize(value, &result); expected = {ENCODING_TYPE_UINT8, 0xff}; EXPECT_EQ(expected, result); result.Clear(); // Min UINT16. value = (1 << 8); Serialize(value, &result); expected = {ENCODING_TYPE_UINT16, 0, 1}; EXPECT_EQ(expected, result); result.Clear(); // Max UINT16. value = 0xffff; Serialize(value, &result); expected = {ENCODING_TYPE_UINT16, 0xff, 0xff}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, uint32_t) { Payload result; Payload expected; uint32_t value; // Min FIXINT. value = 0; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXINT. value = (1 << 7) - 1; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min UINT8. value = (1 << 7); Serialize(value, &result); expected = {ENCODING_TYPE_UINT8, (1 << 7)}; EXPECT_EQ(expected, result); result.Clear(); // Max UINT8. value = 0xff; Serialize(value, &result); expected = {ENCODING_TYPE_UINT8, 0xff}; EXPECT_EQ(expected, result); result.Clear(); // Min UINT16. value = (1 << 8); Serialize(value, &result); expected = {ENCODING_TYPE_UINT16, 0, 1}; EXPECT_EQ(expected, result); result.Clear(); // Max UINT16. value = 0xffff; Serialize(value, &result); expected = {ENCODING_TYPE_UINT16, 0xff, 0xff}; EXPECT_EQ(expected, result); result.Clear(); // Min UINT32. value = (1 << 16); Serialize(value, &result); expected = {ENCODING_TYPE_UINT32, 0, 0, 1, 0}; EXPECT_EQ(expected, result); result.Clear(); // Max UINT32. value = 0xffffffff; Serialize(value, &result); expected = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, uint64_t) { Payload result; Payload expected; uint64_t value; // Min FIXINT. value = 0; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXINT. value = (1 << 7) - 1; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min UINT8. value = (1 << 7); Serialize(value, &result); expected = {ENCODING_TYPE_UINT8, (1 << 7)}; EXPECT_EQ(expected, result); result.Clear(); // Max UINT8. value = 0xff; Serialize(value, &result); expected = {ENCODING_TYPE_UINT8, 0xff}; EXPECT_EQ(expected, result); result.Clear(); // Min UINT16. value = (1 << 8); Serialize(value, &result); expected = {ENCODING_TYPE_UINT16, 0, 1}; EXPECT_EQ(expected, result); result.Clear(); // Max UINT16. value = 0xffff; Serialize(value, &result); expected = {ENCODING_TYPE_UINT16, 0xff, 0xff}; EXPECT_EQ(expected, result); result.Clear(); // Min UINT32. value = (1 << 16); Serialize(value, &result); expected = {ENCODING_TYPE_UINT32, 0, 0, 1, 0}; EXPECT_EQ(expected, result); result.Clear(); // Max UINT32. value = 0xffffffff; Serialize(value, &result); expected = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff}; EXPECT_EQ(expected, result); result.Clear(); // Min UINT64. value = (1ULL << 32); Serialize(value, &result); expected = {ENCODING_TYPE_UINT64, 0, 0, 0, 0, 1, 0, 0, 0}; EXPECT_EQ(expected, result); result.Clear(); // Max UINT64. value = 0xffffffffffffffffULL; Serialize(value, &result); expected = { ENCODING_TYPE_UINT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, int8_t) { Payload result; Payload expected; int8_t value; // Min NEGATIVE FIXINT. value = -32; Serialize(value, &result); expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max NEGATIVE FIXINT. value = -1; Serialize(value, &result); expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min FIXINT. value = 0; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXINT. value = 127; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min INT8. value = -128; Serialize(value, &result); expected = {ENCODING_TYPE_INT8, 0x80}; EXPECT_EQ(expected, result); result.Clear(); // Max INT8. value = -33; Serialize(value, &result); expected = {ENCODING_TYPE_INT8, 0xdf}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, int16_t) { Payload result; Payload expected; int16_t value; // Min NEGATIVE FIXINT. value = -32; Serialize(value, &result); expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max NEGATIVE FIXINT. value = -1; Serialize(value, &result); expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min FIXINT. value = 0; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXINT. value = 127; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min INT8. value = -128; Serialize(value, &result); expected = {ENCODING_TYPE_INT8, 0x80}; EXPECT_EQ(expected, result); result.Clear(); // Max INT8. value = -33; Serialize(value, &result); expected = {ENCODING_TYPE_INT8, 0xdf}; EXPECT_EQ(expected, result); result.Clear(); // Min INT16. value = -32768; Serialize(value, &result); expected = {ENCODING_TYPE_INT16, 0x00, 0x80}; EXPECT_EQ(expected, result); result.Clear(); // Max INT16. value = 32767; Serialize(value, &result); expected = {ENCODING_TYPE_INT16, 0xff, 0x7f}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, int32_t) { Payload result; Payload expected; int32_t value; // Min NEGATIVE FIXINT. value = -32; Serialize(value, &result); expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max NEGATIVE FIXINT. value = -1; Serialize(value, &result); expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min FIXINT. value = 0; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXINT. value = 127; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min INT8. value = -128; Serialize(value, &result); expected = {ENCODING_TYPE_INT8, 0x80}; EXPECT_EQ(expected, result); result.Clear(); // Max INT8. value = -33; Serialize(value, &result); expected = {ENCODING_TYPE_INT8, 0xdf}; EXPECT_EQ(expected, result); result.Clear(); // Min INT16. value = -32768; Serialize(value, &result); expected = {ENCODING_TYPE_INT16, 0x00, 0x80}; EXPECT_EQ(expected, result); result.Clear(); // Max INT16. value = 32767; Serialize(value, &result); expected = {ENCODING_TYPE_INT16, 0xff, 0x7f}; EXPECT_EQ(expected, result); result.Clear(); // Min INT32. value = -2147483648; Serialize(value, &result); expected = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80}; EXPECT_EQ(expected, result); result.Clear(); // Max INT32. value = 2147483647; Serialize(value, &result); expected = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, int64_t) { Payload result; Payload expected; int64_t value; // Min NEGATIVE FIXINT. value = -32; Serialize(value, &result); expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max NEGATIVE FIXINT. value = -1; Serialize(value, &result); expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min FIXINT. value = 0; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXINT. value = 127; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; EXPECT_EQ(expected, result); result.Clear(); // Min INT8. value = -128; Serialize(value, &result); expected = {ENCODING_TYPE_INT8, 0x80}; EXPECT_EQ(expected, result); result.Clear(); // Max INT8. value = -33; Serialize(value, &result); expected = {ENCODING_TYPE_INT8, 0xdf}; EXPECT_EQ(expected, result); result.Clear(); // Min INT16. value = -32768; Serialize(value, &result); expected = {ENCODING_TYPE_INT16, 0x00, 0x80}; EXPECT_EQ(expected, result); result.Clear(); // Max INT16. value = 32767; Serialize(value, &result); expected = {ENCODING_TYPE_INT16, 0xff, 0x7f}; EXPECT_EQ(expected, result); result.Clear(); // Min INT32. value = -2147483648; Serialize(value, &result); expected = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80}; EXPECT_EQ(expected, result); result.Clear(); // Max INT32. value = 2147483647; Serialize(value, &result); expected = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f}; EXPECT_EQ(expected, result); result.Clear(); // Min INT64. value = -9223372036854775808ULL; Serialize(value, &result); expected = { ENCODING_TYPE_INT64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}; EXPECT_EQ(expected, result); result.Clear(); // Max INT64. value = 9223372036854775807ULL; Serialize(value, &result); expected = { ENCODING_TYPE_INT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, float) { Payload result; Payload expected; float value; value = 0.0f; Serialize(value, &result); expected = {ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2], kZeroFloatBytes[3]}; EXPECT_EQ(expected, result); result.Clear(); value = 1.0f; Serialize(value, &result); expected = {ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1], kOneFloatBytes[2], kOneFloatBytes[3]}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, double) { Payload result; Payload expected; double value; value = 0.0f; Serialize(value, &result); expected = {ENCODING_TYPE_FLOAT64, kZeroDoubleBytes[0], kZeroDoubleBytes[1], kZeroDoubleBytes[2], kZeroDoubleBytes[3], kZeroDoubleBytes[4], kZeroDoubleBytes[5], kZeroDoubleBytes[6], kZeroDoubleBytes[7]}; EXPECT_EQ(expected, result); result.Clear(); value = 1.0f; Serialize(value, &result); expected = {ENCODING_TYPE_FLOAT64, kOneDoubleBytes[0], kOneDoubleBytes[1], kOneDoubleBytes[2], kOneDoubleBytes[3], kOneDoubleBytes[4], kOneDoubleBytes[5], kOneDoubleBytes[6], kOneDoubleBytes[7]}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, Enum) { Payload result; Payload expected; enum Foo { kFoo, kBar, kBaz }; Foo value = kBar; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, EnumClass) { Payload result; Payload expected; enum class Foo { kFoo, kBar, kBaz }; Foo value = Foo::kBaz; Serialize(value, &result); expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2}; EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, LocalHandle) { Payload result; Payload expected; LocalHandle fd1; LocalHandle fd2; fd1 = LocalHandle(100); Serialize(fd1, &result); expected = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0}; EXPECT_EQ(expected, result); EXPECT_EQ(1u, result.FdCount()); EXPECT_EQ(100, result.FdArray()[0]); result.Clear(); fd2 = LocalHandle(200); Serialize(std::forward_as_tuple(fd1, fd2), &result); expected = decltype(expected)( {ENCODING_TYPE_FIXARRAY_MIN + 2, ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0, ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 1, 0}); EXPECT_EQ(expected, result); EXPECT_EQ(2u, result.FdCount()); EXPECT_EQ(100, result.FdArray()[0]); EXPECT_EQ(200, result.FdArray()[1]); result.Clear(); fd1.Release(); // Don't try to close fd 100. fd2.Release(); // Don't try to close fd 200. fd1 = LocalHandle(-2); Serialize(fd1, &result); expected = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xfe, 0xff}; EXPECT_EQ(expected, result); EXPECT_EQ(0u, result.FdCount()); result.Clear(); } TEST(SerializationTest, string) { Payload result; Payload expected; std::string value; // Min FIXSTR. value = ""; Serialize(value, &result); expected = {ENCODING_TYPE_FIXSTR_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXSTR. value = std::string((1 << 5) - 1, 'x'); Serialize(value, &result); expected = {ENCODING_TYPE_FIXSTR_MAX}; expected.Append((1 << 5) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min STR8. value = std::string((1 << 5), 'x'); Serialize(value, &result); expected = {ENCODING_TYPE_STR8, (1 << 5)}; expected.Append((1 << 5), 'x'); EXPECT_EQ(expected, result); result.Clear(); // Max STR8. value = std::string((1 << 8) - 1, 'x'); Serialize(value, &result); expected = {ENCODING_TYPE_STR8, (1 << 8) - 1}; expected.Append((1 << 8) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min STR16. value = std::string((1 << 8), 'x'); Serialize(value, &result); expected = {ENCODING_TYPE_STR16, 0x00, 0x01}; expected.Append((1 << 8), 'x'); EXPECT_EQ(expected, result); result.Clear(); // Max STR16. value = std::string((1 << 16) - 1, 'x'); Serialize(value, &result); expected = {ENCODING_TYPE_STR16, 0xff, 0xff}; expected.Append((1 << 16) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min STR32. value = std::string((1 << 16), 'x'); Serialize(value, &result); expected = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x01, 0x00}; expected.Append((1 << 16), 'x'); EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, StringWrapper) { Payload result; Payload expected; std::string value; // Min FIXSTR. value = ""; Serialize(WrapString(value), &result); expected = {ENCODING_TYPE_FIXSTR_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXSTR. value = std::string((1 << 5) - 1, 'x'); Serialize(WrapString(value), &result); expected = {ENCODING_TYPE_FIXSTR_MAX}; expected.Append((1 << 5) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min STR8. value = std::string((1 << 5), 'x'); Serialize(WrapString(value), &result); expected = {ENCODING_TYPE_STR8, (1 << 5)}; expected.Append((1 << 5), 'x'); EXPECT_EQ(expected, result); result.Clear(); // Max STR8. value = std::string((1 << 8) - 1, 'x'); Serialize(WrapString(value), &result); expected = {ENCODING_TYPE_STR8, (1 << 8) - 1}; expected.Append((1 << 8) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min STR16. value = std::string((1 << 8), 'x'); Serialize(WrapString(value), &result); expected = {ENCODING_TYPE_STR16, 0x00, 0x01}; expected.Append((1 << 8), 'x'); EXPECT_EQ(expected, result); result.Clear(); // Max STR16. value = std::string((1 << 16) - 1, 'x'); Serialize(WrapString(value), &result); expected = {ENCODING_TYPE_STR16, 0xff, 0xff}; expected.Append((1 << 16) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min STR32. value = std::string((1 << 16), 'x'); Serialize(WrapString(value), &result); expected = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x01, 0x00}; expected.Append((1 << 16), 'x'); EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, vector) { Payload result; Payload expected; std::vector value; // Min FIXARRAY. value = {}; Serialize(value, &result); expected = {ENCODING_TYPE_FIXARRAY_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXARRAY. value = decltype(value)((1 << 4) - 1, 'x'); Serialize(value, &result); expected = {ENCODING_TYPE_FIXARRAY_MAX}; expected.Append((1 << 4) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min ARRAY16. value = decltype(value)((1 << 4), 'x'); Serialize(value, &result); expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00}; expected.Append((1 << 4), 'x'); EXPECT_EQ(expected, result); result.Clear(); // Max ARRAY16. value = decltype(value)((1 << 16) - 1, 'x'); Serialize(value, &result); expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff}; expected.Append((1 << 16) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min ARRAY32. value = decltype(value)((1 << 16), 'x'); Serialize(value, &result); expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00}; expected.Append((1 << 16), 'x'); EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, map) { Payload result; Payload expected; std::map value; // Min FIXMAP. value = {}; Serialize(value, &result); expected = {ENCODING_TYPE_FIXMAP_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXMAP. value = MakeMap((1 << 4) - 1); Serialize(value, &result); expected = {ENCODING_TYPE_FIXMAP_MAX}; InsertKeyValue(&expected, (1 << 4) - 1); EXPECT_EQ(expected, result); result.Clear(); // Min MAP16. value = MakeMap((1 << 4)); Serialize(value, &result); expected = {ENCODING_TYPE_MAP16, 0x10, 0x00}; InsertKeyValue(&expected, (1 << 4)); EXPECT_EQ(expected, result); result.Clear(); // Max MAP16. value = MakeMap((1 << 16) - 1); Serialize(value, &result); expected = {ENCODING_TYPE_MAP16, 0xff, 0xff}; InsertKeyValue(&expected, (1 << 16) - 1); EXPECT_EQ(expected, result); result.Clear(); // Min MAP32. value = MakeMap((1 << 16)); Serialize(value, &result); expected = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00}; InsertKeyValue(&expected, (1 << 16)); EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, unordered_map) { Payload result; Payload expected; std::unordered_map value; // Min FIXMAP. value = {}; Serialize(value, &result); expected = {ENCODING_TYPE_FIXMAP_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXMAP. value = MakeMap((1 << 4) - 1); Serialize(value, &result); expected = {ENCODING_TYPE_FIXMAP_MAX}; InsertKeyValue(&expected, (1 << 4) - 1); EXPECT_EQ(expected, result); result.Clear(); // Min MAP16. value = MakeMap((1 << 4)); Serialize(value, &result); expected = {ENCODING_TYPE_MAP16, 0x10, 0x00}; InsertKeyValue(&expected, (1 << 4)); EXPECT_EQ(expected, result); result.Clear(); // Max MAP16. value = MakeMap((1 << 16) - 1); Serialize(value, &result); expected = {ENCODING_TYPE_MAP16, 0xff, 0xff}; InsertKeyValue(&expected, (1 << 16) - 1); EXPECT_EQ(expected, result); result.Clear(); // Min MAP32. value = MakeMap((1 << 16)); Serialize(value, &result); expected = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00}; InsertKeyValue(&expected, (1 << 16)); EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, array) { Payload result; Payload expected; // Min FIXARRAY. std::array a0; Serialize(a0, &result); expected = {ENCODING_TYPE_FIXARRAY_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXARRAY. std::array a1; for (auto& element : a1) element = 'x'; Serialize(a1, &result); expected = {ENCODING_TYPE_FIXARRAY_MAX}; expected.Append((1 << 4) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min ARRAY16. std::array a2; for (auto& element : a2) element = 'x'; Serialize(a2, &result); expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00}; expected.Append((1 << 4), 'x'); EXPECT_EQ(expected, result); result.Clear(); // Max ARRAY16. std::array a3; for (auto& element : a3) element = 'x'; Serialize(a3, &result); expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff}; expected.Append((1 << 16) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min ARRAY32. std::array a4; for (auto& element : a4) element = 'x'; Serialize(a4, &result); expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00}; expected.Append((1 << 16), 'x'); EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, ArrayWrapper) { Payload result; Payload expected; std::vector> value; ArrayWrapper wrapper; // Min FIXARRAY. value = {}; Serialize(wrapper, &result); expected = {ENCODING_TYPE_FIXARRAY_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXARRAY. value = decltype(value)((1 << 4) - 1, 'x'); wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size()); Serialize(wrapper, &result); expected = {ENCODING_TYPE_FIXARRAY_MAX}; expected.Append((1 << 4) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min ARRAY16. value = decltype(value)((1 << 4), 'x'); wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size()); Serialize(wrapper, &result); expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00}; expected.Append((1 << 4), 'x'); EXPECT_EQ(expected, result); result.Clear(); // Max ARRAY16. value = decltype(value)((1 << 16) - 1, 'x'); wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size()); Serialize(wrapper, &result); expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff}; expected.Append((1 << 16) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min ARRAY32. value = decltype(value)((1 << 16), 'x'); wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size()); Serialize(wrapper, &result); expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00}; expected.Append((1 << 16), 'x'); EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, pair) { Payload result; Payload expected; auto p1 = std::make_pair(1, 2); Serialize(p1, &result); expected = {ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2}; EXPECT_EQ(expected, result); result.Clear(); auto p2 = std::make_pair('x', std::string("12345")); Serialize(p2, &result); expected = decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 2, 'x', ENCODING_TYPE_FIXSTR_MIN + 5, '1', '2', '3', '4', '5'}); EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, tuple) { Payload result; Payload expected; // Min FIXARRAY. auto t1 = std::make_tuple(); Serialize(t1, &result); expected = {ENCODING_TYPE_FIXARRAY_MIN}; EXPECT_EQ(expected, result); result.Clear(); // Max FIXARRAY. auto t2 = GetNTuple<15>('x'); Serialize(t2, &result); expected = {ENCODING_TYPE_FIXARRAY_MAX}; expected.Append((1 << 4) - 1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min ARRAY16. auto t3 = GetNTuple<(1 << 4)>('x'); Serialize(t3, &result); expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00}; expected.Append((1 << 4), 'x'); EXPECT_EQ(expected, result); result.Clear(); // Template instantiation depth is an issue for these tests. They are commented // out to document the expected behavior, even though tuples of this order are // not expected in practice. #if 0 // Max ARRAY16. auto t4 = GetNTuple<(1 << 16)-1>('x'); Serialize(t4, &result); expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff}; expected.Append((1 << 16)-1, 'x'); EXPECT_EQ(expected, result); result.Clear(); // Min ARRAY32. auto t5 = GetNTuple<(1 << 16)>('x'); Serialize(t5, &result); expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00}; expected.Append((1 << 16), 'x'); EXPECT_EQ(expected, result); result.Clear(); #endif } // TODO(eieio): More exhaustive testing of type nesting. TEST(SerializationTest, NestedTuple) { Payload result; Payload expected; auto t1 = std::make_tuple('x', std::make_tuple(1, 2)); Serialize(t1, &result); expected = decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 2, 'x', ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2}); EXPECT_EQ(expected, result); result.Clear(); auto t2 = std::make_tuple('x', std::make_tuple(1, 2), std::string("0123456789")); Serialize(t2, &result); expected = decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 3, 'x', ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2, ENCODING_TYPE_FIXSTR | 10, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}); EXPECT_EQ(expected, result); result.Clear(); auto t3 = std::make_tuple(0.0f, std::uint64_t(10ULL), std::vector{'a', 'b', 'c'}); Serialize(t3, &result); expected = decltype(expected)( {ENCODING_TYPE_FIXARRAY_MIN + 3, ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2], kZeroFloatBytes[3], ENCODING_TYPE_POSITIVE_FIXINT_MIN + 10, ENCODING_TYPE_FIXARRAY_MIN + 3, 'a', 'b', 'c'}); EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, NestedMap) { Payload result; Payload expected; std::map> m1 = {{0, {"a", 2}}, {1, {"b", 10}}}; Serialize(m1, &result); expected = decltype(expected)( {ENCODING_TYPE_FIXMAP_MIN + 2, 0, ENCODING_TYPE_FIXARRAY_MIN + 2, ENCODING_TYPE_FIXSTR_MIN + 1, 'a', 2, 1, ENCODING_TYPE_FIXARRAY_MIN + 2, ENCODING_TYPE_FIXSTR_MIN + 1, 'b', 10}); EXPECT_EQ(expected, result); result.Clear(); } TEST(SerializationTest, Serializable) { Payload result; Payload expected; TestType t1{10, 0.0, "12345", TestType::Foo::kBaz}; Serialize(t1, &result); expected = decltype(expected)( {ENCODING_TYPE_FIXARRAY_MIN + 4, 10, ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2], kZeroFloatBytes[3], ENCODING_TYPE_FIXSTR_MIN + 5, '1', '2', '3', '4', '5', ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2}); EXPECT_EQ(expected, result); result.Clear(); TestTemplateType tt{LocalHandle(-1)}; Serialize(tt, &result); expected = decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 1, ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xff, 0xff}); EXPECT_EQ(expected, result); } TEST(SerializationTest, Variant) { Payload result; Payload expected; Variant v; // Empty variant. Serialize(v, &result); expected = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_NEGATIVE_FIXINT_MAX, ENCODING_TYPE_NIL}; EXPECT_EQ(expected, result); result.Clear(); v = 10; Serialize(v, &result); expected = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 0, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 10}; EXPECT_EQ(expected, result); result.Clear(); v = true; Serialize(v, &result); expected = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1, ENCODING_TYPE_TRUE}; EXPECT_EQ(expected, result); result.Clear(); v = false; Serialize(v, &result); expected = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1, ENCODING_TYPE_FALSE}; EXPECT_EQ(expected, result); result.Clear(); v = 1.0f; Serialize(v, &result); expected = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2, ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1], kOneFloatBytes[2], kOneFloatBytes[3]}; EXPECT_EQ(expected, result); result.Clear(); // TODO(eieio): Add more serialization tests for Variant. } TEST(DeserializationTest, bool) { Payload buffer; bool result = false; ErrorType error; // True. buffer = {ENCODING_TYPE_TRUE}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(1, result); // Gtest generates warning from bool literals. // False. buffer = {ENCODING_TYPE_FALSE}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0, result); // Gtest generates warning from bool literals. } TEST(DeserializationTest, uint8_t) { Payload buffer; std::uint8_t result = 0; ErrorType error; // Min FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127U, result); // Min UINT8. buffer = {ENCODING_TYPE_UINT8, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max UINT8. buffer = {ENCODING_TYPE_UINT8, 0xff}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0xffU, result); // UINT16 out of range. buffer = {ENCODING_TYPE_UINT16}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_UINT16, error.encoding_type()); // UINT32 out of range. buffer = {ENCODING_TYPE_UINT32}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_UINT32, error.encoding_type()); // UINT64 out of range. buffer = {ENCODING_TYPE_UINT64}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_UINT64, error.encoding_type()); } TEST(DeserializationTest, uint16_t) { Payload buffer; std::uint16_t result = 0; ErrorType error; // Min FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127U, result); // Min UINT8. buffer = {ENCODING_TYPE_UINT8, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max UINT8. buffer = {ENCODING_TYPE_UINT8, 0xff}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0xffU, result); // Min UINT16. buffer = {ENCODING_TYPE_UINT16, 0x00, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max UINT16. buffer = {ENCODING_TYPE_UINT16, 0xff, 0xff}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0xffffU, result); // UINT32 out of range. buffer = {ENCODING_TYPE_UINT32}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_UINT32, error.encoding_type()); // UINT64 out of range. buffer = {ENCODING_TYPE_UINT64}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_UINT64, error.encoding_type()); } TEST(DeserializationTest, uint32_t) { Payload buffer; std::uint32_t result = 0; ErrorType error; // Min FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127U, result); // Min UINT8. buffer = {ENCODING_TYPE_UINT8, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max UINT8. buffer = {ENCODING_TYPE_UINT8, 0xff}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0xffU, result); // Min UINT16. buffer = {ENCODING_TYPE_UINT16, 0x00, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max UINT16. buffer = {ENCODING_TYPE_UINT16, 0xff, 0xff}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0xffffU, result); // Min UINT32. buffer = {ENCODING_TYPE_UINT32, 0x00, 0x00, 0x00, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max UINT32. buffer = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0xffffffffU, result); // UINT64 out of range. buffer = {ENCODING_TYPE_UINT64}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_UINT64, error.encoding_type()); } TEST(DeserializationTest, uint64_t) { Payload buffer; std::uint64_t result = 0; ErrorType error; // Min FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127U, result); // Min UINT8. buffer = {ENCODING_TYPE_UINT8, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max UINT8. buffer = {ENCODING_TYPE_UINT8, 0xff}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0xffU, result); // Min UINT16. buffer = {ENCODING_TYPE_UINT16, 0x00, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max UINT16. buffer = {ENCODING_TYPE_UINT16, 0xff, 0xff}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0xffffU, result); // Min UINT32. buffer = {ENCODING_TYPE_UINT32, 0x00, 0x00, 0x00, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max UINT32. buffer = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0xffffffffU, result); // Min UINT64. buffer = { ENCODING_TYPE_UINT64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0U, result); // Max UINT64. buffer = { ENCODING_TYPE_UINT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0xffffffffffffffffUL, result); } TEST(DeserializationTest, int8_t) { Payload buffer; std::int8_t result = 0; ErrorType error; // Min NEGATIVE FIXINT. buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-32, result); // Max NEGATIVE FIXINT. buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-1, result); // Min FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0, result); // Max FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127, result); // Min INT8. buffer = {ENCODING_TYPE_INT8, 0x80}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-128, result); // Max INT8. buffer = {ENCODING_TYPE_INT8, 0x7f}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127, result); // INT16 out of range. buffer = {ENCODING_TYPE_INT16}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_INT16, error.encoding_type()); // INT32 out of range. buffer = {ENCODING_TYPE_INT32}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_INT32, error.encoding_type()); // INT64 out of range. buffer = {ENCODING_TYPE_INT64}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_INT64, error.encoding_type()); } TEST(DeserializationTest, int16_t) { Payload buffer; std::int16_t result = 0; ErrorType error; // Min NEGATIVE FIXINT. buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-32, result); // Max NEGATIVE FIXINT. buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-1, result); // Min FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0, result); // Max FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127, result); // Min INT8. buffer = {ENCODING_TYPE_INT8, 0x80}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-128, result); // Max INT8. buffer = {ENCODING_TYPE_INT8, 0x7f}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127, result); // Min INT16. buffer = {ENCODING_TYPE_INT16, 0x00, 0x80}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-32768, result); // Max INT16. buffer = {ENCODING_TYPE_INT16, 0xff, 0x7f}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(32767, result); // INT32 out of range. buffer = {ENCODING_TYPE_INT32}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_INT32, error.encoding_type()); // INT64 out of range. buffer = {ENCODING_TYPE_INT64}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_INT64, error.encoding_type()); } TEST(DeserializationTest, int32_t) { Payload buffer; std::int32_t result = 0; ErrorType error; // Min NEGATIVE FIXINT. buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-32, result); // Max NEGATIVE FIXINT. buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-1, result); // Min FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0, result); // Max FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127, result); // Min INT8. buffer = {ENCODING_TYPE_INT8, 0x80}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-128, result); // Max INT8. buffer = {ENCODING_TYPE_INT8, 0x7f}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127, result); // Min INT16. buffer = {ENCODING_TYPE_INT16, 0x00, 0x80}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-32768, result); // Max INT16. buffer = {ENCODING_TYPE_INT16, 0xff, 0x7f}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(32767, result); // Min INT32. buffer = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-2147483648, result); // Max INT32. buffer = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(2147483647, result); // INT64 out of range. buffer = {ENCODING_TYPE_INT64}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_INT64, error.encoding_type()); } TEST(DeserializationTest, int64_t) { Payload buffer; std::int64_t result = 0; ErrorType error; // Min NEGATIVE FIXINT. buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-32, result); // Max NEGATIVE FIXINT. buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-1, result); // Min FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0, result); // Max FIXINT. buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127, result); // Min INT8. buffer = {ENCODING_TYPE_INT8, 0x80}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-128, result); // Max INT8. buffer = {ENCODING_TYPE_INT8, 0x7f}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(127, result); // Min INT16. buffer = {ENCODING_TYPE_INT16, 0x00, 0x80}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-32768, result); // Max INT16. buffer = {ENCODING_TYPE_INT16, 0xff, 0x7f}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(32767, result); // Min INT32. buffer = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-2147483648, result); // Max INT32. buffer = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(2147483647, result); // Min INT64. buffer = { ENCODING_TYPE_INT64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); // Believe it or not, this is actually the correct way to specify the most // negative signed long long. EXPECT_EQ(-9223372036854775807LL - 1, result); // Max INT64. buffer = { ENCODING_TYPE_INT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(9223372036854775807LL, result); } TEST(DeserializationTest, float) { Payload buffer; float result; ErrorType error; // FLOAT32. buffer = {ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2], kZeroFloatBytes[3]}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(kZeroFloat, result); // FLOAT32. buffer = {ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1], kOneFloatBytes[2], kOneFloatBytes[3]}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(kOneFloat, result); } TEST(DeserializationTest, double) { Payload buffer; double result; ErrorType error; // FLOAT32. buffer = {ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2], kZeroFloatBytes[3]}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(kZeroDouble, result); // FLOAT64. buffer = {ENCODING_TYPE_FLOAT64, kZeroDoubleBytes[0], kZeroDoubleBytes[1], kZeroDoubleBytes[2], kZeroDoubleBytes[3], kZeroDoubleBytes[4], kZeroDoubleBytes[5], kZeroDoubleBytes[6], kZeroDoubleBytes[7]}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(kZeroDouble, result); // FLOAT32. buffer = {ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1], kOneFloatBytes[2], kOneFloatBytes[3]}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(kOneDouble, result); // FLOAT64. buffer = {ENCODING_TYPE_FLOAT64, kOneDoubleBytes[0], kOneDoubleBytes[1], kOneDoubleBytes[2], kOneDoubleBytes[3], kOneDoubleBytes[4], kOneDoubleBytes[5], kOneDoubleBytes[6], kOneDoubleBytes[7]}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(kOneDouble, result); } TEST(DeserializationTest, Enum) { Payload buffer; enum Foo { kFoo, kBar, kBaz } result; ErrorType error; buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(kBar, result); } TEST(DeserializationTest, EnumClass) { Payload buffer; enum Foo { kFoo, kBar, kBaz } result; ErrorType error; buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(Foo::kBaz, result); } TEST(DeserializationTest, LocalHandle) { Payload buffer; LocalHandle result1; LocalHandle result2; ErrorType error; buffer = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0}; error = Deserialize(&result1, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0, result1.Get()); result1.Release(); // Don't close fd 0. std::tuple t1(result1, result2); buffer = decltype(buffer)( {ENCODING_TYPE_FIXARRAY_MIN + 2, ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0, ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 1, 0}); error = Deserialize(&t1, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(0, result1.Get()); EXPECT_EQ(1, result2.Get()); result1.Release(); // Don't close fd 0. result2.Release(); // Don't close fd 1. buffer = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xfe, 0xff}; error = Deserialize(&result1, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(-2, result1.Get()); } TEST(DeserializationTest, string) { Payload buffer; std::string result = ""; ErrorType error; // Min FIXSTR. buffer = {ENCODING_TYPE_FIXSTR_MIN}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ("", result); // Max FIXSTR. buffer = {ENCODING_TYPE_FIXSTR_MAX}; buffer.Append((1 << 5) - 1, 'x'); error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(std::string((1 << 5) - 1, 'x'), result); // Min STR8. buffer = {ENCODING_TYPE_STR8, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ("", result); // Max STR8. buffer = {ENCODING_TYPE_STR8, 0xff}; buffer.Append(0xff, 'x'); error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(std::string(0xff, 'x'), result); // Min STR16. buffer = {ENCODING_TYPE_STR16, 0x00, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ("", result); // Max STR16. buffer = {ENCODING_TYPE_STR16, 0xff, 0xff}; buffer.Append(0xffff, 'x'); error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(std::string(0xffff, 'x'), result); // Min STR32. buffer = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x00, 0x00}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ("", result); // Test STR32 with max STR16 + 1 bytes. It's not practical to test max // STR32. buffer = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x01, 0x00}; buffer.Append(0x10000, 'x'); error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(std::string(0x10000, 'x'), result); } TEST(DeserializationTest, vector) { Payload buffer; std::vector> result; Payload expected; ErrorType error; // Min FIXARRAY. buffer = {ENCODING_TYPE_FIXARRAY_MIN}; error = Deserialize(&result, &buffer); expected = {}; EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Max FIXARRAY. buffer = {ENCODING_TYPE_FIXARRAY_MAX}; buffer.Append((1 << 4) - 1, 1); error = Deserialize(&result, &buffer); expected = decltype(expected)((1 << 4) - 1, 1); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Min ARRAY16. buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00}; error = Deserialize(&result, &buffer); expected = {}; EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Max ARRAY16. buffer = {ENCODING_TYPE_ARRAY16, 0xff, 0xff}; buffer.Append(0xffff, 1); error = Deserialize(&result, &buffer); expected = decltype(expected)(0xffff, 1); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Min ARRAY32. buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00}; error = Deserialize(&result, &buffer); expected = {}; EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // ARRAY32 with max ARRAY16 + 1. It's not practical to test max ARRAY32. buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00}; buffer.Append(0x10000, 1); error = Deserialize(&result, &buffer); expected = decltype(expected)(0x10000, 1); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); } TEST(DeserializationTest, map) { Payload buffer; std::map result; std::map expected; ErrorType error; // Min FIXMAP. buffer = {ENCODING_TYPE_FIXMAP_MIN}; error = Deserialize(&result, &buffer); expected = {}; EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Size mismatch. buffer = {ENCODING_TYPE_FIXMAP_MIN + 1}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::INSUFFICIENT_BUFFER, error); // Max FIXMAP. buffer = {ENCODING_TYPE_FIXMAP_MAX}; InsertKeyValue(&buffer, (1 << 4) - 1); error = Deserialize(&result, &buffer); expected = MakeMap((1 << 4) - 1); EXPECT_EQ(ErrorCode::NO_ERROR, error) << std::string(error); EXPECT_EQ(expected, result); // Min MAP16. buffer = {ENCODING_TYPE_MAP16, 0x00, 0x00}; error = Deserialize(&result, &buffer); expected = {}; EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Max MAP16. buffer = {ENCODING_TYPE_MAP16, 0xff, 0xff}; InsertKeyValue(&buffer, (1 << 16) - 1); error = Deserialize(&result, &buffer); expected = MakeMap((1 << 16) - 1); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Min MAP32. buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x00, 0x00}; error = Deserialize(&result, &buffer); expected = {}; EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // MAP32 with max MAP16 + 1. It's not practical to test max MAP32. buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00}; InsertKeyValue(&buffer, (1 << 16)); error = Deserialize(&result, &buffer); expected = MakeMap((1 << 16)); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); } TEST(DeserializationTest, unordered_map) { Payload buffer; std::unordered_map result; std::unordered_map expected; ErrorType error; // Min FIXMAP. buffer = {ENCODING_TYPE_FIXMAP_MIN}; error = Deserialize(&result, &buffer); expected = {}; EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Size mismatch. buffer = {ENCODING_TYPE_FIXMAP_MIN + 1}; error = Deserialize(&result, &buffer); EXPECT_EQ(ErrorCode::INSUFFICIENT_BUFFER, error); // Max FIXMAP. buffer = {ENCODING_TYPE_FIXMAP_MAX}; InsertKeyValue(&buffer, (1 << 4) - 1); error = Deserialize(&result, &buffer); expected = MakeMap((1 << 4) - 1); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Min MAP16. buffer = {ENCODING_TYPE_MAP16, 0x00, 0x00}; error = Deserialize(&result, &buffer); expected = {}; EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Max MAP16. buffer = {ENCODING_TYPE_MAP16, 0xff, 0xff}; InsertKeyValue(&buffer, (1 << 16) - 1); error = Deserialize(&result, &buffer); expected = MakeMap((1 << 16) - 1); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Min MAP32. buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x00, 0x00}; error = Deserialize(&result, &buffer); expected = {}; EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // MAP32 with max MAP16 + 1. It's not practical to test max MAP32. buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00}; InsertKeyValue(&buffer, (1 << 16)); error = Deserialize(&result, &buffer); expected = MakeMap((1 << 16)); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); } TEST(DeserializationTest, array) { Payload buffer; ErrorType error; // Min FIXARRAY. buffer = {ENCODING_TYPE_FIXARRAY_MIN}; std::array a0; error = Deserialize(&a0, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); // Size mismatch. buffer = {ENCODING_TYPE_FIXARRAY_MIN + 1}; error = Deserialize(&a0, &buffer); EXPECT_EQ(ErrorCode::INSUFFICIENT_DESTINATION_SIZE, error); // Max FIXARRAY. buffer = {ENCODING_TYPE_FIXARRAY_MAX}; buffer.Append((1 << 4) - 1, 'x'); std::array a1, expected1; for (auto& element : expected1) element = 'x'; error = Deserialize(&a1, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected1, a1); // Min ARRAY16. buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00}; error = Deserialize(&a0, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); // Max ARRAY16. buffer = {ENCODING_TYPE_ARRAY16, 0xff, 0xff}; buffer.Append((1 << 16) - 1, 'x'); std::array a3, expected3; for (auto& element : expected3) element = 'x'; error = Deserialize(&a3, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected3, a3); // Min ARRAY32. buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00}; error = Deserialize(&a0, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); // ARRAY32 with max ARRAY16 + 1. It's not practical to test max ARRAY32. buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00}; buffer.Append((1 << 16), 'x'); std::array a4, expected4; for (auto& element : expected4) element = 'x'; error = Deserialize(&a4, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected4, a4); } TEST(DeserializationTest, ArrayWrapper) { Payload buffer; std::vector> result; std::vector> expected; ErrorType error; result.reserve(0x10000); ArrayWrapper wrapper(result.data(), result.capacity()); // Min FIXARRAY. buffer = {ENCODING_TYPE_FIXARRAY_MIN}; error = Deserialize(&wrapper, &buffer); expected = {}; result.resize(wrapper.size()); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Max FIXARRAY. buffer = {ENCODING_TYPE_FIXARRAY_MAX}; buffer.Append((1 << 4) - 1, 1); error = Deserialize(&wrapper, &buffer); expected = decltype(expected)((1 << 4) - 1, 1); result.resize(wrapper.size()); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Min ARRAY16. buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00}; error = Deserialize(&wrapper, &buffer); expected = {}; result.resize(wrapper.size()); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Max ARRAY16. buffer = {ENCODING_TYPE_ARRAY16, 0xff, 0xff}; buffer.Append(0xffff, 1); error = Deserialize(&wrapper, &buffer); expected = decltype(expected)(0xffff, 1); result.resize(wrapper.size()); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // Min ARRAY32. buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00}; error = Deserialize(&wrapper, &buffer); expected = {}; result.resize(wrapper.size()); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); // ARRAY32 with max ARRAY16 + 1. It's not practical to test max ARRAY32. buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00}; buffer.Append(0x10000, 1); error = Deserialize(&wrapper, &buffer); expected = decltype(expected)(0x10000, 1); result.resize(wrapper.size()); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(expected, result); } TEST(DeserializationTest, pair) { Payload buffer; ErrorType error; std::pair p1; buffer = {ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2}; error = Deserialize(&p1, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(std::make_pair(1, 2), p1); } TEST(DeserializationTest, tuple) { Payload buffer; ErrorType error; // Min FIXARRAY. std::tuple<> t1; buffer = {ENCODING_TYPE_FIXARRAY_MIN}; error = Deserialize(&t1, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(std::make_tuple(), t1); // Superfluous. // Max FIXARRAY. auto t2 = GetNTuple<15, int>(0); buffer = {ENCODING_TYPE_FIXARRAY_MAX}; buffer.Append((1 << 4) - 1, 1); error = Deserialize(&t2, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ((GetNTuple<15, int>(1)), t2); // Min ARRAY16. // Using t1 above. buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00}; error = Deserialize(&t1, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(std::make_tuple(), t1); // ARRAY16 at Max FIXARRAY + 1 auto t3 = GetNTuple<(1 << 4), int>(0); buffer = {ENCODING_TYPE_ARRAY16, 0x10, 0x00}; buffer.Append((1 << 4), 1); error = Deserialize(&t3, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ((GetNTuple<(1 << 4), int>(1)), t3); // Min ARRAY32. // Using t1 from above. buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00}; error = Deserialize(&t1, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(std::make_tuple(), t1); // ARRAY32 at Max FIXARRAY + 1 auto t4 = GetNTuple<(1 << 4), int>(0); buffer = {ENCODING_TYPE_ARRAY32, 0x10, 0x00, 0x00, 0x00}; buffer.Append((1 << 4), 1); error = Deserialize(&t4, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ((GetNTuple<(1 << 4), int>(1)), t4); // Template instantiation depth is an issue for tuples with large numbers of // elements. As these are not expected in practice, the limits of ARRAY16 // and ARRAY32 are not tested. } TEST(DeserializationTest, Serializable) { Payload buffer; ErrorType error; buffer = decltype(buffer)( {ENCODING_TYPE_FIXARRAY_MIN + 4, 10, ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2], kZeroFloatBytes[3], ENCODING_TYPE_FIXSTR_MIN + 5, '1', '2', '3', '4', '5', ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1}); TestType t1; error = Deserialize(&t1, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(TestType(10, 0.f, "12345", TestType::Foo::kBar), t1); buffer = decltype(buffer)({ENCODING_TYPE_FIXARRAY_MIN + 1, ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xff, 0xff}); TestTemplateType tt; error = Deserialize(&tt, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_EQ(TestTemplateType(LocalHandle(-1)), tt); } TEST(DeserializationTest, Variant) { Payload buffer; ErrorType error; Variant v; buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_NEGATIVE_FIXINT_MAX, ENCODING_TYPE_NIL}; error = Deserialize(&v, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); EXPECT_TRUE(v.empty()); buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 0, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 10}; error = Deserialize(&v, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); ASSERT_TRUE(v.is()); EXPECT_EQ(10, std::get(v)); buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1, ENCODING_TYPE_TRUE}; error = Deserialize(&v, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); ASSERT_TRUE(v.is()); EXPECT_EQ(true, std::get(v)); buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1, ENCODING_TYPE_FALSE}; error = Deserialize(&v, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); ASSERT_TRUE(v.is()); EXPECT_EQ(false, std::get(v)); buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2, ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1], kOneFloatBytes[2], kOneFloatBytes[3]}; error = Deserialize(&v, &buffer); EXPECT_EQ(ErrorCode::NO_ERROR, error); ASSERT_TRUE(v.is()); EXPECT_FLOAT_EQ(1.0, std::get(v)); // TODO(eieio): Add more deserialization tests for Variant. } TEST(DeserializationTest, ErrorType) { Payload buffer; ErrorType error; std::uint8_t u8; buffer = {ENCODING_TYPE_STR8}; error = Deserialize(&u8, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type()); std::uint16_t u16; buffer = {ENCODING_TYPE_STR8}; error = Deserialize(&u16, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type()); std::uint32_t u32; buffer = {ENCODING_TYPE_STR8}; error = Deserialize(&u32, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type()); std::uint64_t u64; buffer = {ENCODING_TYPE_STR8}; error = Deserialize(&u64, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type()); std::int8_t i8; buffer = {ENCODING_TYPE_STR8}; error = Deserialize(&i8, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type()); std::int16_t i16; buffer = {ENCODING_TYPE_STR8}; error = Deserialize(&i16, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type()); std::int32_t i32; buffer = {ENCODING_TYPE_STR8}; error = Deserialize(&i32, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type()); std::int64_t i64; buffer = {ENCODING_TYPE_STR8}; error = Deserialize(&i64, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type()); std::string s; buffer = {ENCODING_TYPE_POSITIVE_FIXINT}; error = Deserialize(&s, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_STRING, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_POSITIVE_FIXINT, error.encoding_type()); std::vector v; buffer = {ENCODING_TYPE_POSITIVE_FIXINT}; error = Deserialize(&v, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_ARRAY, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_POSITIVE_FIXINT, error.encoding_type()); buffer = {ENCODING_TYPE_FIXARRAY_MIN + 1, ENCODING_TYPE_STR8}; error = Deserialize(&v, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error); EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class()); EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type()); buffer = {ENCODING_TYPE_FIXARRAY_MIN + 2, 0, 1}; std::tuple t; error = Deserialize(&t, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_TYPE_SIZE, error); buffer = {ENCODING_TYPE_FIXARRAY_MIN + 3, 0, 1, 2}; std::pair p; error = Deserialize(&p, &buffer); EXPECT_EQ(ErrorCode::UNEXPECTED_TYPE_SIZE, error); }