mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-10-18 03:29:49 +02:00
Merge pull request #288 from redboltz/work/add_deep_copy
Added a clone function for msgpack::object.
This commit is contained in:
@@ -353,6 +353,12 @@ inline void zone::undo_allocate(size_t size)
|
||||
m_chunk_list.m_free += size;
|
||||
}
|
||||
|
||||
inline std::size_t aligned_size(
|
||||
std::size_t size,
|
||||
std::size_t align = MSGPACK_ZONE_ALIGN) {
|
||||
return (size + align - 1) / align * align;
|
||||
}
|
||||
|
||||
/// @cond
|
||||
|
||||
template <typename T>
|
||||
|
@@ -363,6 +363,12 @@ T* zone::allocate(Args... args)
|
||||
}
|
||||
}
|
||||
|
||||
inline std::size_t aligned_size(
|
||||
std::size_t size,
|
||||
std::size_t align = MSGPACK_ZONE_ALIGN) {
|
||||
return (size + align - 1) / align * align;
|
||||
}
|
||||
|
||||
/// @cond
|
||||
} // MSGPACK_API_VERSION_NAMESPACE(v1)
|
||||
/// @endcond
|
||||
|
@@ -36,6 +36,117 @@ namespace msgpack {
|
||||
MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||
/// @endcond
|
||||
|
||||
class object_handle {
|
||||
public:
|
||||
object_handle() {}
|
||||
|
||||
object_handle(msgpack::object const& obj, msgpack::unique_ptr<msgpack::zone> z) :
|
||||
m_obj(obj), m_zone(msgpack::move(z)) { }
|
||||
|
||||
// obsolete
|
||||
void set(msgpack::object const& obj)
|
||||
{ m_obj = obj; }
|
||||
|
||||
const msgpack::object& get() const
|
||||
{ return m_obj; }
|
||||
|
||||
msgpack::unique_ptr<msgpack::zone>& zone()
|
||||
{ return m_zone; }
|
||||
|
||||
const msgpack::unique_ptr<msgpack::zone>& zone() const
|
||||
{ return m_zone; }
|
||||
|
||||
#if defined(MSGPACK_USE_CPP03)
|
||||
struct object_handle_ref {
|
||||
object_handle_ref(object_handle* oh):m_oh(oh) {}
|
||||
object_handle* m_oh;
|
||||
};
|
||||
|
||||
object_handle(object_handle& other):
|
||||
m_obj(other.m_obj),
|
||||
m_zone(msgpack::move(other.m_zone)) {
|
||||
}
|
||||
|
||||
object_handle(object_handle_ref ref):
|
||||
m_obj(ref.m_oh->m_obj),
|
||||
m_zone(msgpack::move(ref.m_oh->m_zone)) {
|
||||
}
|
||||
|
||||
object_handle& operator=(object_handle& other) {
|
||||
m_obj = other.m_obj;
|
||||
m_zone = msgpack::move(other.m_zone);
|
||||
return *this;
|
||||
}
|
||||
|
||||
object_handle& operator=(object_handle_ref ref) {
|
||||
m_obj = ref.m_oh->m_obj;
|
||||
m_zone = msgpack::move(ref.m_oh->m_zone);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator object_handle_ref() {
|
||||
return object_handle_ref(this);
|
||||
}
|
||||
#endif // defined(MSGPACK_USE_CPP03)
|
||||
|
||||
private:
|
||||
msgpack::object m_obj;
|
||||
msgpack::unique_ptr<msgpack::zone> m_zone;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <std::size_t N>
|
||||
inline std::size_t add_ext_type_size(std::size_t size) {
|
||||
return size + 1;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::size_t add_ext_type_size<4>(std::size_t size) {
|
||||
return size == 0xffffffff ? size : size + 1;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
inline std::size_t aligned_zone_size(msgpack::object const& obj) {
|
||||
std::size_t s = 0;
|
||||
switch (obj.type) {
|
||||
case msgpack::type::ARRAY:
|
||||
s += sizeof(msgpack::object) * obj.via.array.size;
|
||||
for (uint32_t i = 0; i < obj.via.array.size; ++i) {
|
||||
s += msgpack::aligned_zone_size(obj.via.array.ptr[i]);
|
||||
}
|
||||
break;
|
||||
case msgpack::type::MAP:
|
||||
s += sizeof(msgpack::object_kv) * obj.via.map.size;
|
||||
for (uint32_t i = 0; i < obj.via.map.size; ++i) {
|
||||
s += msgpack::aligned_zone_size(obj.via.map.ptr[i].key);
|
||||
s += msgpack::aligned_zone_size(obj.via.map.ptr[i].val);
|
||||
}
|
||||
break;
|
||||
case msgpack::type::EXT:
|
||||
s += msgpack::aligned_size(
|
||||
detail::add_ext_type_size<sizeof(std::size_t)>(obj.via.ext.size));
|
||||
break;
|
||||
case msgpack::type::STR:
|
||||
s += msgpack::aligned_size(obj.via.str.size);
|
||||
break;
|
||||
case msgpack::type::BIN:
|
||||
s += msgpack::aligned_size(obj.via.bin.size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
inline object_handle clone(msgpack::object const& obj) {
|
||||
std::size_t size = msgpack::aligned_zone_size(obj);
|
||||
msgpack::unique_ptr<msgpack::zone> z(size == 0 ? nullptr : new msgpack::zone(size));
|
||||
msgpack::object newobj = z.get() ? msgpack::object(obj, *z) : obj;
|
||||
return object_handle(newobj, msgpack::move(z));
|
||||
}
|
||||
|
||||
struct object::implicit_type {
|
||||
implicit_type(object const& o) : obj(o) { }
|
||||
~implicit_type() { }
|
||||
|
@@ -991,30 +991,7 @@ inline int context::execute(const char* data, std::size_t len, std::size_t& off)
|
||||
} // detail
|
||||
|
||||
|
||||
class unpacked {
|
||||
public:
|
||||
unpacked() {}
|
||||
|
||||
unpacked(msgpack::object const& obj, msgpack::unique_ptr<msgpack::zone> z) :
|
||||
m_obj(obj), m_zone(msgpack::move(z)) { }
|
||||
|
||||
void set(msgpack::object const& obj)
|
||||
{ m_obj = obj; }
|
||||
|
||||
const msgpack::object& get() const
|
||||
{ return m_obj; }
|
||||
|
||||
msgpack::unique_ptr<msgpack::zone>& zone()
|
||||
{ return m_zone; }
|
||||
|
||||
const msgpack::unique_ptr<msgpack::zone>& zone() const
|
||||
{ return m_zone; }
|
||||
|
||||
private:
|
||||
msgpack::object m_obj;
|
||||
msgpack::unique_ptr<msgpack::zone> m_zone;
|
||||
};
|
||||
|
||||
typedef object_handle unpacked;
|
||||
|
||||
class unpacker {
|
||||
public:
|
||||
@@ -1143,8 +1120,6 @@ private:
|
||||
#endif // defined(MSGPACK_USE_CPP03)
|
||||
};
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
unpacked unpack(
|
||||
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
||||
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||
@@ -1162,8 +1137,6 @@ unpacked unpack(
|
||||
unpack_reference_func f = nullptr, void* user_data = nullptr,
|
||||
unpack_limit const& limit = unpack_limit());
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
|
||||
void unpack(unpacked& result,
|
||||
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
||||
@@ -1554,8 +1527,6 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
|
||||
|
||||
// reference version
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
inline unpacked unpack(
|
||||
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
||||
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||
@@ -1605,8 +1576,6 @@ inline unpacked unpack(
|
||||
return unpack(data, len, off, referenced, f, user_data, limit);
|
||||
}
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
inline void unpack(unpacked& result,
|
||||
const char* data, std::size_t len, std::size_t& off, bool& referenced,
|
||||
unpack_reference_func f, void* user_data, unpack_limit const& limit)
|
||||
|
Reference in New Issue
Block a user