mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-10-14 15:05:37 +02:00
This fix is ogirinally from https://github.com/msgpack/msgpack-c/pull/133 I removed raw support and added str, bin, and ext support.
This commit is contained in:
@@ -195,6 +195,81 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const T& v)
|
||||
return detail::packer_serializer<Stream, T>::pack(o, v);
|
||||
}
|
||||
|
||||
inline void operator<< (object::with_zone& o, const object& v)
|
||||
{
|
||||
o.type = v.type;
|
||||
|
||||
switch(v.type) {
|
||||
case type::NIL:
|
||||
case type::BOOLEAN:
|
||||
case type::POSITIVE_INTEGER:
|
||||
case type::NEGATIVE_INTEGER:
|
||||
case type::DOUBLE:
|
||||
::memcpy(&o.via, &v.via, sizeof(v.via));
|
||||
return;
|
||||
|
||||
case type::STR: {
|
||||
char* ptr = static_cast<char*>(o.zone.allocate_align(v.via.str.size));
|
||||
o.via.str.ptr = ptr;
|
||||
o.via.str.size = v.via.str.size;
|
||||
::memcpy(ptr, v.via.str.ptr, v.via.str.size);
|
||||
return;
|
||||
}
|
||||
|
||||
case type::BIN: {
|
||||
char* ptr = static_cast<char*>(o.zone.allocate_align(v.via.bin.size));
|
||||
o.via.bin.ptr = ptr;
|
||||
o.via.bin.size = v.via.bin.size;
|
||||
::memcpy(ptr, v.via.bin.ptr, v.via.bin.size);
|
||||
return;
|
||||
}
|
||||
|
||||
case type::EXT: {
|
||||
char* ptr = static_cast<char*>(o.zone.allocate_align(v.via.ext.size + 1));
|
||||
o.via.ext.ptr = ptr;
|
||||
o.via.ext.size = v.via.ext.size;
|
||||
::memcpy(ptr, v.via.ext.ptr, v.via.ext.size + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
case type::ARRAY:
|
||||
o.via.array.ptr = static_cast<object*>(o.zone.allocate_align(sizeof(object) * v.via.array.size));
|
||||
o.via.array.size = v.via.array.size;
|
||||
for (object
|
||||
* po(o.via.array.ptr),
|
||||
* pv(v.via.array.ptr),
|
||||
* const pvend(v.via.array.ptr + v.via.array.size);
|
||||
pv < pvend;
|
||||
++po, ++pv) {
|
||||
new (po) object(*pv, o.zone);
|
||||
}
|
||||
return;
|
||||
|
||||
case type::MAP:
|
||||
o.via.map.ptr = (object_kv*)o.zone.allocate_align(sizeof(object_kv) * v.via.map.size);
|
||||
o.via.map.size = v.via.map.size;
|
||||
for(object_kv
|
||||
* po(o.via.map.ptr),
|
||||
* pv(v.via.map.ptr),
|
||||
* const pvend(v.via.map.ptr + v.via.map.size);
|
||||
pv < pvend;
|
||||
++po, ++pv) {
|
||||
object_kv* kv = new (po) object_kv;
|
||||
new (&kv->key) object(pv->key, o.zone);
|
||||
new (&kv->val) object(pv->val, o.zone);
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
throw type_error();
|
||||
}
|
||||
}
|
||||
|
||||
inline void operator<< (object::with_zone& o, const object::with_zone& v)
|
||||
{
|
||||
return o << static_cast<object const&>(v);
|
||||
}
|
||||
|
||||
// deconvert operator
|
||||
template <typename T>
|
||||
inline void operator<< (object::with_zone& o, const T& v)
|
||||
@@ -551,6 +626,12 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const object& v)
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
packer<Stream>& operator<< (packer<Stream>& o, const object::with_zone& v)
|
||||
{
|
||||
return o << static_cast<object>(v);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<< (std::ostream& s, const object& o)
|
||||
{
|
||||
switch(o.type) {
|
||||
|
@@ -150,6 +150,9 @@ object const& operator>> (object const& o, T& v);
|
||||
template <typename T>
|
||||
void operator<< (object::with_zone& o, const T& v);
|
||||
|
||||
void operator<< (object::with_zone& o, const object& v);
|
||||
|
||||
void operator<< (object::with_zone& o, const object::with_zone& v);
|
||||
|
||||
template <typename Stream>
|
||||
class packer;
|
||||
@@ -157,6 +160,9 @@ class packer;
|
||||
template <typename Stream>
|
||||
packer<Stream>& operator<< (packer<Stream>& o, const object& v);
|
||||
|
||||
template <typename Stream>
|
||||
packer<Stream>& operator<< (packer<Stream>& o, const object::with_zone& v);
|
||||
|
||||
template <typename Stream, typename T>
|
||||
packer<Stream>& operator<< (packer<Stream>& o, const T& v);
|
||||
|
||||
|
131
test/object.cpp
131
test/object.cpp
@@ -11,12 +11,14 @@ struct myclass {
|
||||
|
||||
int num;
|
||||
std::string str;
|
||||
std::vector<double> vec;
|
||||
std::map<std::string, std::vector<char> > map;
|
||||
|
||||
MSGPACK_DEFINE(num, str);
|
||||
MSGPACK_DEFINE(num, str, vec, map);
|
||||
|
||||
bool operator==(const myclass& o) const
|
||||
{
|
||||
return num == o.num && str == o.str;
|
||||
return num == o.num && str == o.str && vec == o.vec && map == o.map;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -28,7 +30,7 @@ std::ostream& operator<<(std::ostream& o, const myclass& m)
|
||||
|
||||
TEST(object, convert)
|
||||
{
|
||||
myclass m1;
|
||||
myclass m1(1, "custom");
|
||||
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, m1);
|
||||
@@ -45,7 +47,7 @@ TEST(object, convert)
|
||||
|
||||
TEST(object, as)
|
||||
{
|
||||
myclass m1;
|
||||
myclass m1(1, "custom");
|
||||
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, m1);
|
||||
@@ -56,6 +58,127 @@ TEST(object, as)
|
||||
EXPECT_EQ(m1, ret.get().as<myclass>());
|
||||
}
|
||||
|
||||
TEST(object, cross_zone_copy)
|
||||
{
|
||||
myclass m1(1, "custom");
|
||||
m1.vec.push_back(1.0);
|
||||
m1.vec.push_back(0.1);
|
||||
std::vector<char> vc;
|
||||
vc.push_back('t');
|
||||
vc.push_back('w');
|
||||
vc.push_back('o');
|
||||
m1.map["one"] = vc;
|
||||
|
||||
msgpack::zone z1;
|
||||
msgpack::object::with_zone obj1(z1);
|
||||
|
||||
{
|
||||
msgpack::zone z2;
|
||||
msgpack::object::with_zone obj2(z2);
|
||||
obj2 << m1;
|
||||
|
||||
obj1 << obj2;
|
||||
|
||||
EXPECT_EQ(obj1.via.array.ptr[2].via.array.ptr[0].via.dec, 1.0);
|
||||
EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr[0], 'o');
|
||||
EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr[0], 't');
|
||||
EXPECT_NE(
|
||||
obj1.via.array.ptr[2].via.array.ptr,
|
||||
obj2.via.array.ptr[2].via.array.ptr);
|
||||
EXPECT_NE(
|
||||
obj1.via.array.ptr[3].via.map.ptr,
|
||||
obj2.via.array.ptr[3].via.map.ptr);
|
||||
EXPECT_NE(
|
||||
obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr,
|
||||
obj2.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr);
|
||||
EXPECT_NE(
|
||||
obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr,
|
||||
obj2.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr);
|
||||
}
|
||||
|
||||
EXPECT_EQ(m1, obj1.as<myclass>());
|
||||
}
|
||||
|
||||
TEST(object, cross_zone_copy_construct)
|
||||
{
|
||||
myclass m1(1, "custom");
|
||||
m1.vec.push_back(1.0);
|
||||
m1.vec.push_back(0.1);
|
||||
std::vector<char> vc;
|
||||
vc.push_back('t');
|
||||
vc.push_back('w');
|
||||
vc.push_back('o');
|
||||
m1.map["one"] = vc;
|
||||
|
||||
msgpack::zone z1;
|
||||
msgpack::zone z2;
|
||||
msgpack::object::with_zone obj2(z2);
|
||||
obj2 << m1;
|
||||
|
||||
msgpack::object obj1(obj2, z1);
|
||||
|
||||
EXPECT_EQ(obj1.via.array.ptr[2].via.array.ptr[0].via.dec, 1.0);
|
||||
EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr[0], 'o');
|
||||
EXPECT_EQ(obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr[0], 't');
|
||||
EXPECT_NE(
|
||||
obj1.via.array.ptr[2].via.array.ptr,
|
||||
obj2.via.array.ptr[2].via.array.ptr);
|
||||
EXPECT_NE(
|
||||
obj1.via.array.ptr[3].via.map.ptr,
|
||||
obj2.via.array.ptr[3].via.map.ptr);
|
||||
EXPECT_NE(
|
||||
obj1.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr,
|
||||
obj2.via.array.ptr[3].via.map.ptr[0].key.via.str.ptr);
|
||||
EXPECT_NE(
|
||||
obj1.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr,
|
||||
obj2.via.array.ptr[3].via.map.ptr[0].val.via.bin.ptr);
|
||||
EXPECT_EQ(m1, obj1.as<myclass>());
|
||||
}
|
||||
|
||||
TEST(object, cross_zone_copy_ext)
|
||||
{
|
||||
msgpack::zone z1;
|
||||
msgpack::zone z2;
|
||||
msgpack::object::with_zone obj1(z1);
|
||||
|
||||
obj1.type = msgpack::type::EXT;
|
||||
char* ptr = static_cast<char*>(obj1.zone.allocate_align(2));
|
||||
ptr[0] = 1;
|
||||
ptr[1] = 2;
|
||||
obj1.via.ext.ptr = ptr;
|
||||
obj1.via.ext.size = 1;
|
||||
|
||||
msgpack::object::with_zone obj2(z2);
|
||||
obj2 << obj1;
|
||||
EXPECT_EQ(obj2.via.ext.size, 1);
|
||||
EXPECT_EQ(obj2.via.ext.ptr[0], 1);
|
||||
EXPECT_EQ(obj2.via.ext.ptr[1], 2);
|
||||
EXPECT_NE(
|
||||
obj1.via.ext.ptr,
|
||||
obj2.via.ext.ptr);
|
||||
}
|
||||
|
||||
TEST(object, cross_zone_copy_construct_ext)
|
||||
{
|
||||
msgpack::zone z1;
|
||||
msgpack::zone z2;
|
||||
msgpack::object::with_zone obj1(z1);
|
||||
|
||||
obj1.type = msgpack::type::EXT;
|
||||
char* ptr = static_cast<char*>(obj1.zone.allocate_align(2));
|
||||
ptr[0] = 1;
|
||||
ptr[1] = 2;
|
||||
obj1.via.ext.ptr = ptr;
|
||||
obj1.via.ext.size = 1;
|
||||
|
||||
msgpack::object obj2(obj1, z2);
|
||||
EXPECT_EQ(obj2.via.ext.size, 1);
|
||||
EXPECT_EQ(obj2.via.ext.ptr[0], 1);
|
||||
EXPECT_EQ(obj2.via.ext.ptr[1], 2);
|
||||
EXPECT_NE(
|
||||
obj1.via.ext.ptr,
|
||||
obj2.via.ext.ptr);
|
||||
}
|
||||
|
||||
TEST(object, print)
|
||||
{
|
||||
|
Reference in New Issue
Block a user