From ab12b2b2b98df96f2103de02c767d79c1f636449 Mon Sep 17 00:00:00 2001 From: Jakob Petsovits Date: Fri, 19 Sep 2014 22:08:59 -0400 Subject: [PATCH 1/3] Specialize operator<<(packer, T) also for object::with_zone. It already existed for T = object, but if trying to pass an object::with_zone it would match the generic operator<<() instead. That operator calls o.msgpack_pack(), which doesn't exist and causes a compile error. (Re-)Using the overload for object is a better way to handle this. --- src/msgpack/object.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/msgpack/object.hpp b/src/msgpack/object.hpp index 76fe4cae..665e1e19 100644 --- a/src/msgpack/object.hpp +++ b/src/msgpack/object.hpp @@ -412,6 +412,12 @@ packer& operator<< (packer& o, const object& v) } } +template +packer& operator<< (packer& o, const object::with_zone& v) +{ + return o << static_cast(v); +} + } // namespace msgpack From d30548af3f5094020d0b53ec3db08f08ac454c60 Mon Sep 17 00:00:00 2001 From: Jakob Petsovits Date: Fri, 19 Sep 2014 21:10:22 -0400 Subject: [PATCH 2/3] Add support for copying an object to an object::with_zone. With test. --- src/msgpack/object.hpp | 53 ++++++++++++++++++++++++++++++++++++++++++ test/object.cc | 48 +++++++++++++++++++++++++++++++++----- 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/src/msgpack/object.hpp b/src/msgpack/object.hpp index 665e1e19..a8a4eddd 100644 --- a/src/msgpack/object.hpp +++ b/src/msgpack/object.hpp @@ -234,6 +234,59 @@ void operator<< (object::with_zone& o, const T& v) v.msgpack_object(static_cast(&o), o.zone); } +template <> +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::RAW: + o.via.raw.ptr = (const char*)o.zone->malloc(v.via.raw.size); + o.via.raw.size = v.via.raw.size; + ::memcpy((void*)o.via.raw.ptr, v.via.raw.ptr, v.via.raw.size); + return; + + case type::ARRAY: + o.via.array.ptr = (object*)o.zone->malloc(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->malloc(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(); + } +} + +template <> +inline void operator<< (object::with_zone& o, const object::with_zone& v) +{ + return o << static_cast(v); +} + inline bool operator==(const object x, const object y) { diff --git a/test/object.cc b/test/object.cc index 5390c4ae..5d187224 100644 --- a/test/object.cc +++ b/test/object.cc @@ -1,22 +1,27 @@ #include +#include +#include +#include #include struct myclass { myclass() : num(0), str("default") { } - myclass(int num, const std::string& str) : - num(0), str("default") { } + myclass(int n, const std::string& s) : + num(n), str(s) { } ~myclass() { } int num; std::string str; + std::vector vec; + std::map 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 +33,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); @@ -49,7 +54,7 @@ TEST(object, convert) TEST(object, as) { - myclass m1; + myclass m1(1, "custom"); msgpack::sbuffer sbuf; msgpack::pack(sbuf, m1); @@ -65,6 +70,37 @@ TEST(object, as) } +TEST(object, cross_zone_copy) +{ + myclass m1(1, "custom"); + m1.vec.push_back(1.0); + m1.vec.push_back(0.1); + m1.map["one"] = "two"; + + 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].val.via.raw.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[0].val.via.raw.ptr, + obj2.via.array.ptr[3].via.map.ptr[0].val.via.raw.ptr); + } + + EXPECT_EQ(m1, obj1.as()); +} + + TEST(object, print) { msgpack::object obj; From 2fcbe6116d45b80a23486929f956a4765fae85ef Mon Sep 17 00:00:00 2001 From: Nobuyuki Kubota Date: Mon, 6 Oct 2014 14:06:21 -0700 Subject: [PATCH 3/3] Replace C-style casts with C++-style ones --- src/msgpack/object.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/msgpack/object.hpp b/src/msgpack/object.hpp index a8a4eddd..8c160eaf 100644 --- a/src/msgpack/object.hpp +++ b/src/msgpack/object.hpp @@ -249,13 +249,13 @@ inline void operator<< (object::with_zone& o, const object& v) return; case type::RAW: - o.via.raw.ptr = (const char*)o.zone->malloc(v.via.raw.size); + o.via.raw.ptr = static_cast(o.zone->malloc(v.via.raw.size)); o.via.raw.size = v.via.raw.size; - ::memcpy((void*)o.via.raw.ptr, v.via.raw.ptr, v.via.raw.size); + ::memcpy(const_cast(o.via.raw.ptr), v.via.raw.ptr, v.via.raw.size); return; case type::ARRAY: - o.via.array.ptr = (object*)o.zone->malloc(sizeof(object) * v.via.array.size); + o.via.array.ptr = static_cast(o.zone->malloc(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); @@ -265,7 +265,7 @@ inline void operator<< (object::with_zone& o, const object& v) return; case type::MAP: - o.via.map.ptr = (object_kv*)o.zone->malloc(sizeof(object_kv) * v.via.map.size); + o.via.map.ptr = static_cast(o.zone->malloc(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);