blob: ee800f699e0447afaab4cf73aec70bf55c0fcf62 [file] [log] [blame]
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <memory>
#include <string>
#include <thread>
#include <utility>
#include <gtest/gtest.h>
#include <pdx/rpc/argument_encoder.h>
#include <pdx/rpc/array_wrapper.h>
#include <pdx/rpc/default_initialization_allocator.h>
#include <pdx/rpc/payload.h>
#include <pdx/rpc/serializable.h>
#include <pdx/rpc/serialization.h>
#include <pdx/rpc/string_wrapper.h>
#include <pdx/utility.h>
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<const std::uint8_t*>(&kZeroFloat);
const auto kOneFloatBytes = reinterpret_cast<const std::uint8_t*>(&kOneFloat);
const double kZeroDouble = 0.0;
const double kOneDouble = 1.0;
const auto kZeroDoubleBytes =
reinterpret_cast<const std::uint8_t*>(&kZeroDouble);
const auto kOneDoubleBytes = reinterpret_cast<const std::uint8_t*>(&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 <typename FileHandleType>
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<FileHandleType>, fd);
};
// Utilities to generate test maps and payloads.
template <typename MapType>
MapType MakeMap(std::size_t size) {
MapType result;
for (std::size_t i = 0; i < size; i++) {
result.emplace(i, i);
}
return result;
}
template <typename MapType>
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<uint8_t> 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<std::uint32_t, std::uint32_t> value;
// Min FIXMAP.
value = {};
Serialize(value, &result);
expected = {ENCODING_TYPE_FIXMAP_MIN};
EXPECT_EQ(expected, result);
result.Clear();
// Max FIXMAP.
value = MakeMap<decltype(value)>((1 << 4) - 1);
Serialize(value, &result);
expected = {ENCODING_TYPE_FIXMAP_MAX};
InsertKeyValue<decltype(value)>(&expected, (1 << 4) - 1);
EXPECT_EQ(expected, result);
result.Clear();
// Min MAP16.
value = MakeMap<decltype(value)>((1 << 4));
Serialize(value, &result);
expected = {ENCODING_TYPE_MAP16, 0x10, 0x00};
InsertKeyValue<decltype(value)>(&expected, (1 << 4));
EXPECT_EQ(expected, result);
result.Clear();
// Max MAP16.
value = MakeMap<decltype(value)>((1 << 16) - 1);
Serialize(value, &result);
expected = {ENCODING_TYPE_MAP16, 0xff, 0xff};
InsertKeyValue<decltype(value)>(&expected, (1 << 16) - 1);
EXPECT_EQ(expected, result);
result.Clear();
// Min MAP32.
value = MakeMap<decltype(value)>((1 << 16));
Serialize(value, &result);
expected = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00};
InsertKeyValue<decltype(value)>(&expected, (1 << 16));
EXPECT_EQ(expected, result);
result.Clear();
}
TEST(SerializationTest, unordered_map) {
Payload result;
Payload expected;
std::unordered_map<std::uint32_t, std::uint32_t> value;
// Min FIXMAP.
value = {};
Serialize(value, &result);
expected = {ENCODING_TYPE_FIXMAP_MIN};
EXPECT_EQ(expected, result);
result.Clear();
// Max FIXMAP.
value = MakeMap<decltype(value)>((1 << 4) - 1);
Serialize(value, &result);
expected = {ENCODING_TYPE_FIXMAP_MAX};
InsertKeyValue<decltype(value)>(&expected, (1 << 4) - 1);
EXPECT_EQ(expected, result);
result.Clear();
// Min MAP16.
value = MakeMap<decltype(value)>((1 << 4));
Serialize(value, &result);
expected = {ENCODING_TYPE_MAP16, 0x10, 0x00};
InsertKeyValue<decltype(value)>(&expected, (1 << 4));
EXPECT_EQ(expected, result);
result.Clear();
// Max MAP16.
value = MakeMap<decltype(value)>((1 << 16) - 1);
Serialize(value, &result);
expected = {ENCODING_TYPE_MAP16, 0xff, 0xff};
InsertKeyValue<decltype(value)>(&expected, (1 << 16) - 1);
EXPECT_EQ(expected, result);
result.Clear();
// Min MAP32.
value = MakeMap<decltype(value)>((1 << 16));
Serialize(value, &result);
expected = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00};
InsertKeyValue<decltype(value)>(&expected, (1 << 16));
EXPECT_EQ(expected, result);
result.Clear();
}
TEST(SerializationTest, array) {
Payload result;
Payload expected;
// Min FIXARRAY.
std::array<std::uint8_t, 0> a0;
Serialize(a0, &result);
expected = {ENCODING_TYPE_FIXARRAY_MIN};
EXPECT_EQ(expected, result);
result.Clear();
// Max FIXARRAY.
std::array<std::uint8_t, (1 << 4) - 1> 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<std::uint8_t, (1 << 4)> 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<std::uint8_t, (1 << 16) - 1> 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<std::uint8_t, (1 << 16)> 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<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>> value;
ArrayWrapper<std::uint8_t> 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<int, int>(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<int, int>(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<char>{'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<int, std::pair<std::string, int>> 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<LocalHandle> 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<int, bool, float> 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<LocalHandle&, LocalHandle&> 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<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>>
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<std::uint32_t, std::uint32_t> result;
std::map<std::uint32_t, std::uint32_t> 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<decltype(result)>(&buffer, (1 << 4) - 1);
error = Deserialize(&result, &buffer);
expected = MakeMap<decltype(expected)>((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<decltype(result)>(&buffer, (1 << 16) - 1);
error = Deserialize(&result, &buffer);
expected = MakeMap<decltype(expected)>((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<decltype(result)>(&buffer, (1 << 16));
error = Deserialize(&result, &buffer);
expected = MakeMap<decltype(expected)>((1 << 16));
EXPECT_EQ(ErrorCode::NO_ERROR, error);
EXPECT_EQ(expected, result);
}
TEST(DeserializationTest, unordered_map) {
Payload buffer;
std::unordered_map<std::uint32_t, std::uint32_t> result;
std::unordered_map<std::uint32_t, std::uint32_t> 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<decltype(result)>(&buffer, (1 << 4) - 1);
error = Deserialize(&result, &buffer);
expected = MakeMap<decltype(expected)>((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<decltype(result)>(&buffer, (1 << 16) - 1);
error = Deserialize(&result, &buffer);
expected = MakeMap<decltype(expected)>((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<decltype(result)>(&buffer, (1 << 16));
error = Deserialize(&result, &buffer);
expected = MakeMap<decltype(expected)>((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<std::uint8_t, 0> 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<std::uint8_t, (1 << 4) - 1> 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<std::uint8_t, (1 << 16) - 1> 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<std::uint8_t, (1 << 16)> 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<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>>
result;
std::vector<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>>
expected;
ErrorType error;
result.reserve(0x10000);
ArrayWrapper<std::uint8_t> 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<int, int> 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<LocalHandle> tt;
error = Deserialize(&tt, &buffer);
EXPECT_EQ(ErrorCode::NO_ERROR, error);
EXPECT_EQ(TestTemplateType<LocalHandle>(LocalHandle(-1)), tt);
}
TEST(DeserializationTest, Variant) {
Payload buffer;
ErrorType error;
Variant<int, bool, float> 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<int>());
EXPECT_EQ(10, std::get<int>(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<bool>());
EXPECT_EQ(true, std::get<bool>(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<bool>());
EXPECT_EQ(false, std::get<bool>(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<float>());
EXPECT_FLOAT_EQ(1.0, std::get<float>(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<std::uint8_t> 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<int> t;
error = Deserialize(&t, &buffer);
EXPECT_EQ(ErrorCode::UNEXPECTED_TYPE_SIZE, error);
buffer = {ENCODING_TYPE_FIXARRAY_MIN + 3, 0, 1, 2};
std::pair<int, int> p;
error = Deserialize(&p, &buffer);
EXPECT_EQ(ErrorCode::UNEXPECTED_TYPE_SIZE, error);
}