mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-04-21 16:28:19 +02:00

Replaced boost/ with msgpack/ and BOOST with MSGPACK in Boost.Preprocessor files. Renamed existing macron in versioning.hpp to avoid confict with MSGPACK_PP_*. Removed MSGPACK_USE_BOOST requirement from MSGPACK_DEFINE_MAP.
462 lines
9.6 KiB
C++
462 lines
9.6 KiB
C++
#include <msgpack.hpp>
|
|
#include <string>
|
|
#include <cmath>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
const unsigned int kLoop = 1000;
|
|
const unsigned int kElements = 100;
|
|
const double kEPS = 1e-10;
|
|
|
|
// User-Defined Structures
|
|
|
|
class TestEnumMemberClass
|
|
{
|
|
public:
|
|
TestEnumMemberClass()
|
|
: t1(STATE_A), t2(STATE_B), t3(STATE_C) {}
|
|
|
|
enum TestEnumType {
|
|
STATE_INVALID = 0,
|
|
STATE_A = 1,
|
|
STATE_B = 2,
|
|
STATE_C = 3
|
|
};
|
|
TestEnumType t1;
|
|
TestEnumType t2;
|
|
TestEnumType t3;
|
|
|
|
MSGPACK_DEFINE(t1, t2, t3);
|
|
};
|
|
|
|
MSGPACK_ADD_ENUM(TestEnumMemberClass::TestEnumType);
|
|
|
|
class TestClass
|
|
{
|
|
public:
|
|
TestClass() : i(0), s("kzk") {}
|
|
int i;
|
|
string s;
|
|
MSGPACK_DEFINE(i, s);
|
|
};
|
|
|
|
TEST(MSGPACK_USER_DEFINED, simple_buffer_class)
|
|
{
|
|
for (unsigned int k = 0; k < kLoop; k++) {
|
|
TestClass val1;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, val1);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
TestClass val2 = ret.get().as<TestClass>();
|
|
EXPECT_EQ(val1.i, val2.i);
|
|
EXPECT_EQ(val1.s, val2.s);
|
|
}
|
|
}
|
|
|
|
class TestClass2
|
|
{
|
|
public:
|
|
TestClass2() : i(0), s("kzk") {
|
|
for (unsigned int i = 0; i < kElements; i++)
|
|
v.push_back(rand());
|
|
}
|
|
int i;
|
|
string s;
|
|
vector<int> v;
|
|
MSGPACK_DEFINE(i, s, v);
|
|
};
|
|
|
|
TEST(MSGPACK_USER_DEFINED, simple_buffer_class_old_to_new)
|
|
{
|
|
for (unsigned int k = 0; k < kLoop; k++) {
|
|
TestClass val1;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, val1);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
TestClass2 val2 = ret.get().as<TestClass2>();
|
|
EXPECT_EQ(val1.i, val2.i);
|
|
EXPECT_EQ(val1.s, val2.s);
|
|
EXPECT_FALSE(val2.s.empty());
|
|
}
|
|
}
|
|
|
|
TEST(MSGPACK_USER_DEFINED, simple_buffer_class_new_to_old)
|
|
{
|
|
for (unsigned int k = 0; k < kLoop; k++) {
|
|
TestClass2 val1;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, val1);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
TestClass val2 = ret.get().as<TestClass>();
|
|
EXPECT_EQ(val1.i, val2.i);
|
|
EXPECT_EQ(val1.s, val2.s);
|
|
EXPECT_FALSE(val2.s.empty());
|
|
}
|
|
}
|
|
|
|
TEST(MSGPACK_USER_DEFINED, simple_buffer_enum_member)
|
|
{
|
|
TestEnumMemberClass val1;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, val1);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
TestEnumMemberClass val2 = ret.get().as<TestEnumMemberClass>();
|
|
EXPECT_EQ(val1.t1, val2.t1);
|
|
EXPECT_EQ(val1.t2, val2.t2);
|
|
EXPECT_EQ(val1.t3, val2.t3);
|
|
}
|
|
|
|
class TestUnionMemberClass
|
|
{
|
|
public:
|
|
TestUnionMemberClass() {}
|
|
TestUnionMemberClass(double f) {
|
|
is_double = true;
|
|
value.f = f;
|
|
}
|
|
TestUnionMemberClass(int i) {
|
|
is_double = false;
|
|
value.i = i;
|
|
}
|
|
|
|
union {
|
|
double f;
|
|
int i;
|
|
} value;
|
|
bool is_double;
|
|
|
|
template <typename Packer>
|
|
void msgpack_pack(Packer& pk) const
|
|
{
|
|
if (is_double)
|
|
pk.pack(msgpack::type::tuple<bool, double>(true, value.f));
|
|
else
|
|
pk.pack(msgpack::type::tuple<bool, int>(false, value.i));
|
|
}
|
|
|
|
void msgpack_unpack(msgpack::object o)
|
|
{
|
|
msgpack::type::tuple<bool, msgpack::object> tuple;
|
|
o.convert(&tuple);
|
|
|
|
is_double = tuple.get<0>();
|
|
if (is_double)
|
|
tuple.get<1>().convert(&value.f);
|
|
else
|
|
tuple.get<1>().convert(&value.i);
|
|
}
|
|
};
|
|
|
|
TEST(MSGPACK_USER_DEFINED, simple_buffer_union_member)
|
|
{
|
|
{
|
|
// double
|
|
TestUnionMemberClass val1(1.0);
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, val1);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
TestUnionMemberClass val2 = ret.get().as<TestUnionMemberClass>();
|
|
EXPECT_EQ(val1.is_double, val2.is_double);
|
|
EXPECT_TRUE(fabs(val1.value.f - val2.value.f) < kEPS);
|
|
}
|
|
{
|
|
// int
|
|
TestUnionMemberClass val1(1);
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, val1);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
TestUnionMemberClass val2 = ret.get().as<TestUnionMemberClass>();
|
|
EXPECT_EQ(val1.is_double, val2.is_double);
|
|
EXPECT_EQ(val1.value.i, 1);
|
|
EXPECT_EQ(val1.value.i, val2.value.i);
|
|
}
|
|
}
|
|
|
|
// inheritance
|
|
|
|
// define
|
|
|
|
struct d_top {
|
|
int t;
|
|
MSGPACK_DEFINE(t);
|
|
};
|
|
|
|
struct d_mid1 : d_top {
|
|
int m1;
|
|
MSGPACK_DEFINE(MSGPACK_BASE(d_top), m1);
|
|
};
|
|
|
|
struct d_mid2 : d_top {
|
|
int m2;
|
|
MSGPACK_DEFINE(m2, MSGPACK_BASE(d_top));
|
|
};
|
|
|
|
struct d_bottom : d_mid1, d_mid2 {
|
|
int b;
|
|
MSGPACK_DEFINE(MSGPACK_BASE(d_mid1), MSGPACK_BASE(d_mid2), b);
|
|
};
|
|
|
|
TEST(MSGPACK_INHERIT, define_non_virtual)
|
|
{
|
|
d_bottom b;
|
|
b.b = 1;
|
|
b.m1 = 2;
|
|
b.m2 = 3;
|
|
b.d_mid1::t = 4;
|
|
b.d_mid2::t = 5;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, b);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
d_bottom br = ret.get().as<d_bottom>();
|
|
EXPECT_EQ(b.b, br.b);
|
|
EXPECT_EQ(b.m1, br.m1);
|
|
EXPECT_EQ(b.m2, br.m2);
|
|
EXPECT_EQ(b.d_mid1::t, br.d_mid1::t);
|
|
EXPECT_EQ(b.d_mid2::t, br.d_mid2::t);
|
|
}
|
|
|
|
struct v_d_top {
|
|
int t;
|
|
MSGPACK_DEFINE(t);
|
|
};
|
|
|
|
struct v_d_mid1 : virtual v_d_top {
|
|
int m1;
|
|
MSGPACK_DEFINE(m1);
|
|
};
|
|
|
|
struct v_d_mid2 : virtual v_d_top {
|
|
int m2;
|
|
MSGPACK_DEFINE(m2);
|
|
};
|
|
|
|
struct v_d_bottom : v_d_mid1, v_d_mid2 {
|
|
int b;
|
|
MSGPACK_DEFINE(MSGPACK_BASE(v_d_mid1), MSGPACK_BASE(v_d_mid2), MSGPACK_BASE(v_d_top), b);
|
|
};
|
|
|
|
TEST(MSGPACK_INHERIT, define_virtual)
|
|
{
|
|
v_d_bottom b;
|
|
b.b = 1;
|
|
b.m1 = 2;
|
|
b.m2 = 3;
|
|
b.t = 4;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, b);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
v_d_bottom br = ret.get().as<v_d_bottom>();
|
|
EXPECT_EQ(b.b, br.b);
|
|
EXPECT_EQ(b.m1, br.m1);
|
|
EXPECT_EQ(b.m2, br.m2);
|
|
EXPECT_EQ(b.t, br.t);
|
|
}
|
|
|
|
// define_array
|
|
|
|
struct da_top {
|
|
int t;
|
|
MSGPACK_DEFINE_ARRAY(t);
|
|
};
|
|
|
|
struct da_mid1 : da_top {
|
|
int m1;
|
|
MSGPACK_DEFINE_ARRAY(MSGPACK_BASE_ARRAY(da_top), m1);
|
|
};
|
|
|
|
struct da_mid2 : da_top {
|
|
int m2;
|
|
MSGPACK_DEFINE_ARRAY(m2, MSGPACK_BASE_ARRAY(da_top));
|
|
};
|
|
|
|
struct da_bottom : da_mid1, da_mid2 {
|
|
int b;
|
|
MSGPACK_DEFINE_ARRAY(MSGPACK_BASE_ARRAY(da_mid1), MSGPACK_BASE_ARRAY(da_mid2), b);
|
|
};
|
|
|
|
TEST(MSGPACK_INHERIT, define_array_non_virtual)
|
|
{
|
|
da_bottom b;
|
|
b.b = 1;
|
|
b.m1 = 2;
|
|
b.m2 = 3;
|
|
b.da_mid1::t = 4;
|
|
b.da_mid2::t = 5;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, b);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
da_bottom br = ret.get().as<da_bottom>();
|
|
EXPECT_EQ(b.b, br.b);
|
|
EXPECT_EQ(b.m1, br.m1);
|
|
EXPECT_EQ(b.m2, br.m2);
|
|
EXPECT_EQ(b.da_mid1::t, br.da_mid1::t);
|
|
EXPECT_EQ(b.da_mid2::t, br.da_mid2::t);
|
|
}
|
|
|
|
struct v_da_top {
|
|
int t;
|
|
MSGPACK_DEFINE_ARRAY(t);
|
|
};
|
|
|
|
struct v_da_mid1 : virtual v_da_top {
|
|
int m1;
|
|
MSGPACK_DEFINE_ARRAY(m1);
|
|
};
|
|
|
|
struct v_da_mid2 : virtual v_da_top {
|
|
int m2;
|
|
MSGPACK_DEFINE_ARRAY(m2);
|
|
};
|
|
|
|
struct v_da_bottom : v_da_mid1, v_da_mid2 {
|
|
int b;
|
|
MSGPACK_DEFINE_ARRAY(MSGPACK_BASE_ARRAY(v_da_mid1), MSGPACK_BASE_ARRAY(v_da_mid2), MSGPACK_BASE_ARRAY(v_da_top), b);
|
|
};
|
|
|
|
TEST(MSGPACK_INHERIT, define_array_virtual)
|
|
{
|
|
v_da_bottom b;
|
|
b.b = 1;
|
|
b.m1 = 2;
|
|
b.m2 = 3;
|
|
b.t = 4;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, b);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
v_da_bottom br = ret.get().as<v_da_bottom>();
|
|
EXPECT_EQ(b.b, br.b);
|
|
EXPECT_EQ(b.m1, br.m1);
|
|
EXPECT_EQ(b.m2, br.m2);
|
|
EXPECT_EQ(b.t, br.t);
|
|
}
|
|
|
|
// define_map
|
|
|
|
struct dm_top {
|
|
int t;
|
|
MSGPACK_DEFINE_MAP(t);
|
|
};
|
|
|
|
struct dm_mid1 : dm_top {
|
|
int m1;
|
|
MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(dm_top), m1);
|
|
};
|
|
|
|
struct dm_mid2 : dm_top {
|
|
int m2;
|
|
MSGPACK_DEFINE_MAP(m2, MSGPACK_BASE_MAP(dm_top));
|
|
};
|
|
|
|
struct dm_bottom : dm_mid1, dm_mid2 {
|
|
int b;
|
|
MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(dm_mid1), MSGPACK_BASE_MAP(dm_mid2), b);
|
|
};
|
|
|
|
TEST(MSGPACK_INHERIT, define_map_non_virtual)
|
|
{
|
|
dm_bottom b;
|
|
b.b = 1;
|
|
b.m1 = 2;
|
|
b.m2 = 3;
|
|
b.dm_mid1::t = 4;
|
|
b.dm_mid2::t = 5;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, b);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
dm_bottom br = ret.get().as<dm_bottom>();
|
|
EXPECT_EQ(b.b, br.b);
|
|
EXPECT_EQ(b.m1, br.m1);
|
|
EXPECT_EQ(b.m2, br.m2);
|
|
EXPECT_EQ(b.dm_mid1::t, br.dm_mid1::t);
|
|
EXPECT_EQ(b.dm_mid2::t, br.dm_mid2::t);
|
|
}
|
|
|
|
struct v_dm_top {
|
|
int t;
|
|
MSGPACK_DEFINE_MAP(t);
|
|
};
|
|
|
|
struct v_dm_mid1 : virtual v_dm_top {
|
|
int m1;
|
|
MSGPACK_DEFINE_MAP(m1);
|
|
};
|
|
|
|
struct v_dm_mid2 : virtual v_dm_top {
|
|
int m2;
|
|
MSGPACK_DEFINE_MAP(m2);
|
|
};
|
|
|
|
struct v_dm_bottom : v_dm_mid1, v_dm_mid2 {
|
|
int b;
|
|
MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(v_dm_mid1), MSGPACK_BASE_MAP(v_dm_mid2), MSGPACK_BASE_MAP(v_dm_top), b);
|
|
};
|
|
|
|
TEST(MSGPACK_INHERIT, define_map_virtual)
|
|
{
|
|
v_dm_bottom b;
|
|
b.b = 1;
|
|
b.m1 = 2;
|
|
b.m2 = 3;
|
|
b.t = 4;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, b);
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
v_dm_bottom br = ret.get().as<v_dm_bottom>();
|
|
EXPECT_EQ(b.b, br.b);
|
|
EXPECT_EQ(b.m1, br.m1);
|
|
EXPECT_EQ(b.m2, br.m2);
|
|
EXPECT_EQ(b.t, br.t);
|
|
}
|
|
|
|
// map migration
|
|
|
|
struct s_v1 {
|
|
int i;
|
|
std::string s;
|
|
s_v1():i(42), s("foo") {}
|
|
MSGPACK_DEFINE_MAP(i, s);
|
|
};
|
|
|
|
struct s_v2 {
|
|
char c; // new member variable
|
|
std::string s;
|
|
int i;
|
|
s_v2():c('A'), s("bar"), i(77) {}
|
|
MSGPACK_DEFINE_MAP(c, s, i); // variable added, order changed
|
|
};
|
|
|
|
TEST(MSGPACK_MIGRATION, order_number_changed)
|
|
{
|
|
s_v1 v1;
|
|
msgpack::sbuffer sbuf;
|
|
msgpack::pack(sbuf, v1);
|
|
|
|
msgpack::unpacked ret;
|
|
msgpack::unpack(ret, sbuf.data(), sbuf.size());
|
|
s_v2 v2 = ret.get().as<s_v2>();
|
|
|
|
EXPECT_EQ(v2.c, 'A');
|
|
EXPECT_EQ(v2.s, "foo"); // from v1
|
|
EXPECT_EQ(v2.i, 42); // from v1
|
|
}
|