Added EXT support.

Removed obsolete unpack functions.
Updated examples that no longer use obsolete functions.
Added reference checking function to unpacked. ( unpacked::referenced() )
Added std:: namespace.
Added reference or copy choice function and default behavior:
  When you use unpacker, default behavior is:
    STR, BIN, EXT types are always held by reference.
  When you don't use unpacker, default behavior is:
    STR, BIN, EXT types are always held by copy.
    The memory is allocated from zone.
  You can customize the behavior passing your custom judging function to unpack() or unpacker's constructor.
This commit is contained in:
Takatoshi Kondo 2014-08-06 16:18:37 +09:00
parent ce21ab0ebf
commit 1f5d6b9cac
12 changed files with 519 additions and 400 deletions

View File

@ -30,9 +30,9 @@ int main(void)
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, oc); msgpack::pack(sbuf, oc);
msgpack::zone zone; msgpack::unpacked result;
msgpack::object obj; msgpack::unpack(result, sbuf.data(), sbuf.size());
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &zone, &obj); msgpack::object obj = result.get();
obj.convert(&nc); obj.convert(&nc);
@ -46,9 +46,9 @@ int main(void)
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, nc); msgpack::pack(sbuf, nc);
msgpack::zone zone; msgpack::unpacked result;
msgpack::object obj; msgpack::unpack(result, sbuf.data(), sbuf.size());
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &zone, &obj); msgpack::object obj = result.get();
obj.convert(&oc); obj.convert(&oc);

View File

@ -46,12 +46,12 @@ int main(void)
{ {
std::string buffer(stream.str()); std::string buffer(stream.str());
msgpack::zone mempool; msgpack::unpacked result;
msgpack::object o = msgpack::unpack(result, buffer.data(), buffer.size());
msgpack::unpack(buffer.data(), buffer.size(), mempool); msgpack::object o = result.get();
myprotocol::Get req; myprotocol::Get req;
msgpack::convert(req, o); o.convert(req);
std::cout << "received: " << o << std::endl; std::cout << "received: " << o << std::endl;
} }
@ -74,12 +74,13 @@ int main(void)
{ {
std::string buffer(stream.str()); std::string buffer(stream.str());
msgpack::zone mempool; msgpack::unpacked result;
msgpack::object o = msgpack::unpack(result, buffer.data(), buffer.size());
msgpack::unpack(buffer.data(), buffer.size(), mempool); msgpack::object o = result.get();
myprotocol::MultiGet req; myprotocol::MultiGet req;
msgpack::convert(req, o); o.convert(req);
std::cout << "received: " << o << std::endl; std::cout << "received: " << o << std::endl;
} }
} }

View File

@ -18,11 +18,12 @@ int main(void)
// deserialize the buffer into msgpack::object instance. // deserialize the buffer into msgpack::object instance.
std::string str(buffer.str()); std::string str(buffer.str());
// deserialized object is valid during the msgpack::zone instance alive. msgpack::unpacked result;
msgpack::zone mempool;
msgpack::object deserialized; msgpack::unpack(result, str.data(), str.size());
msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized);
// deserialized object is valid during the msgpack::unpacked instance alive.
msgpack::object deserialized = result.get();
// msgpack::object supports ostream. // msgpack::object supports ostream.
std::cout << deserialized << std::endl; std::cout << deserialized << std::endl;

View File

@ -28,23 +28,11 @@ void test_map_pack_unpack() {
buffer.seekg(0); buffer.seekg(0);
std::string str(buffer.str()); std::string str(buffer.str());
// deserialized object is valid during the msgpack::zone instance alive.
msgpack::zone mempool;
msgpack::object deserialized;
std::cout << "Start unpacking..." << std::endl;
{
boost::timer::cpu_timer timer;
msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized);
std::string result = timer.format();
std::cout << result << std::endl;
}
std::cout << "Unpack finished..." << std::endl;
msgpack::unpacked unpacked; msgpack::unpacked unpacked;
std::cout << "Start unpacking...by void unpack(unpacked* result, const char* data, size_t len, size_t* offset = NULL)" << std::endl; std::cout << "Start unpacking...by void unpack(unpacked& result, const char* data, size_t len)" << std::endl;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
msgpack::unpack(&unpacked, str.data(), str.size()); msgpack::unpack(unpacked, str.data(), str.size());
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }
@ -53,7 +41,7 @@ void test_map_pack_unpack() {
std::cout << "Start converting..." << std::endl; std::cout << "Start converting..." << std::endl;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
deserialized.convert(&m2); unpacked.get().convert(&m2);
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }

View File

@ -51,23 +51,11 @@ void test_array_of_array() {
buffer.seekg(0); buffer.seekg(0);
std::string str(buffer.str()); std::string str(buffer.str());
// deserialized object is valid during the msgpack::zone instance alive.
msgpack::zone mempool;
msgpack::object deserialized;
std::cout << "Start unpacking..." << std::endl;
{
boost::timer::cpu_timer timer;
msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized);
std::string result = timer.format();
std::cout << result << std::endl;
}
std::cout << "Unpack finished..." << std::endl;
msgpack::unpacked unpacked; msgpack::unpacked unpacked;
std::cout << "Start unpacking...by void unpack(unpacked* result, const char* data, size_t len, size_t* offset = NULL)" << std::endl; std::cout << "Start unpacking...by void unpack(unpacked& result, const char* data, size_t len)" << std::endl;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
msgpack::unpack(&unpacked, str.data(), str.size()); msgpack::unpack(unpacked, str.data(), str.size());
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }
@ -76,7 +64,7 @@ void test_array_of_array() {
std::cout << "Start converting..." << std::endl; std::cout << "Start converting..." << std::endl;
{ {
boost::timer::cpu_timer timer; boost::timer::cpu_timer timer;
deserialized.convert(&v2); unpacked.get().convert(&v2);
std::string result = timer.format(); std::string result = timer.format();
std::cout << result << std::endl; std::cout << result << std::endl;
} }

View File

@ -41,7 +41,8 @@ typedef enum {
MSGPACK_OBJECT_STR = 0x05, MSGPACK_OBJECT_STR = 0x05,
MSGPACK_OBJECT_ARRAY = 0x06, MSGPACK_OBJECT_ARRAY = 0x06,
MSGPACK_OBJECT_MAP = 0x07, MSGPACK_OBJECT_MAP = 0x07,
MSGPACK_OBJECT_BIN = 0x08 MSGPACK_OBJECT_BIN = 0x08,
MSGPACK_OBJECT_EXT = 0x09
} msgpack_object_type; } msgpack_object_type;

View File

@ -43,7 +43,8 @@ namespace type {
STR = MSGPACK_OBJECT_STR, STR = MSGPACK_OBJECT_STR,
BIN = MSGPACK_OBJECT_BIN, BIN = MSGPACK_OBJECT_BIN,
ARRAY = MSGPACK_OBJECT_ARRAY, ARRAY = MSGPACK_OBJECT_ARRAY,
MAP = MSGPACK_OBJECT_MAP MAP = MSGPACK_OBJECT_MAP,
EXT = MSGPACK_OBJECT_EXT
}; };
} }
@ -71,6 +72,13 @@ struct object_bin {
const char* ptr; const char* ptr;
}; };
struct object_ext {
int8_t type() const { return ptr[0]; }
const char* data() const { return &ptr[1]; }
uint32_t size;
const char* ptr;
};
struct object { struct object {
union union_type { union union_type {
bool boolean; bool boolean;
@ -81,6 +89,7 @@ struct object {
object_map map; object_map map;
object_str str; object_str str;
object_bin bin; object_bin bin;
object_ext ext;
}; };
type::object_type type; type::object_type type;
@ -242,6 +251,10 @@ inline bool operator==(const object& x, const object& y)
return x.via.bin.size == y.via.bin.size && return x.via.bin.size == y.via.bin.size &&
memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0; memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0;
case type::EXT:
return x.via.bin.size == y.via.bin.size &&
memcmp(x.via.bin.ptr, y.via.bin.ptr, x.via.bin.size) == 0;
case type::ARRAY: case type::ARRAY:
if(x.via.array.size != y.via.array.size) { if(x.via.array.size != y.via.array.size) {
return false; return false;
@ -444,6 +457,11 @@ packer<Stream>& operator<< (packer<Stream>& o, const object& v)
o.pack_bin_body(v.via.bin.ptr, v.via.bin.size); o.pack_bin_body(v.via.bin.ptr, v.via.bin.size);
return o; return o;
case type::EXT:
o.pack_ext(v.via.ext.size, v.via.ext.type());
o.pack_ext_body(v.via.ext.data(), v.via.ext.size);
return o;
case type::ARRAY: case type::ARRAY:
o.pack_array(v.via.array.size); o.pack_array(v.via.array.size);
for(object* p(v.via.array.ptr), for(object* p(v.via.array.ptr),

View File

@ -84,6 +84,9 @@ public:
packer<Stream>& pack_bin(size_t l); packer<Stream>& pack_bin(size_t l);
packer<Stream>& pack_bin_body(const char* b, size_t l); packer<Stream>& pack_bin_body(const char* b, size_t l);
packer<Stream>& pack_ext(size_t l, int8_t type);
packer<Stream>& pack_ext_body(const char* b, size_t l);
private: private:
template <typename T> template <typename T>
void pack_imp_uint8(T d); void pack_imp_uint8(T d);
@ -699,6 +702,72 @@ inline packer<Stream>& packer<Stream>::pack_bin_body(const char* b, size_t l)
return *this; return *this;
} }
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_ext(size_t l, int8_t type)
{
switch(l) {
case 1: {
char buf[2];
buf[0] = static_cast<char>(0xd4);
buf[1] = static_cast<char>(type);
append_buffer(buf, 2);
} break;
case 2: {
char buf[2];
buf[0] = static_cast<char>(0xd5);
buf[1] = static_cast<char>(type);
append_buffer(buf, 2);
} break;
case 4: {
char buf[2];
buf[0] = static_cast<char>(0xd6);
buf[1] = static_cast<char>(type);
append_buffer(buf, 2);
} break;
case 8: {
char buf[2];
buf[0] = static_cast<char>(0xd7);
buf[1] = static_cast<char>(type);
append_buffer(buf, 2);
} break;
case 16: {
char buf[2];
buf[0] = static_cast<char>(0xd8);
buf[1] = static_cast<char>(type);
append_buffer(buf, 2);
} break;
default:
if(l < 256) {
char buf[3];
buf[0] = static_cast<char>(0xc7);
buf[1] = static_cast<char>(l);
buf[2] = static_cast<char>(type);
append_buffer(buf, 3);
} else if(l < 65536) {
char buf[4];
buf[0] = static_cast<char>(0xc8);
_msgpack_store16(&buf[1], static_cast<uint16_t>(l));
buf[3] = static_cast<char>(type);
append_buffer(buf, 4);
} else {
char buf[6];
buf[0] = static_cast<char>(0xc9);
_msgpack_store32(&buf[1], static_cast<uint32_t>(l));
buf[5] = static_cast<char>(type);
append_buffer(buf, 6);
}
break;
}
return *this;
}
template <typename Stream>
inline packer<Stream>& packer<Stream>::pack_ext_body(const char* b, size_t l)
{
append_buffer(b, l);
return *this;
}
template <typename Stream> template <typename Stream>
template <typename T> template <typename T>
inline void packer<Stream>::pack_imp_uint8(T d) inline void packer<Stream>::pack_imp_uint8(T d)

View File

@ -17,7 +17,6 @@
// //
#ifndef MSGPACK_UNPACK_HPP #ifndef MSGPACK_UNPACK_HPP
#define MSGPACK_UNPACK_HPP #define MSGPACK_UNPACK_HPP
#include "object.hpp" #include "object.hpp"
#include "zone.hpp" #include "zone.hpp"
#include "unpack_define.h" #include "unpack_define.h"
@ -48,18 +47,26 @@
namespace msgpack { namespace msgpack {
typedef bool (*unpack_reference_func)(type::object_type, uint64_t, void*);
namespace detail { namespace detail {
class unpack_user { class unpack_user {
public: public:
unpack_user(unpack_reference_func f = nullptr, void* user_data = nullptr)
:m_func(f), m_user_data(user_data) {}
msgpack::zone const& zone() const { return *m_zone; } msgpack::zone const& zone() const { return *m_zone; }
msgpack::zone& zone() { return *m_zone; } msgpack::zone& zone() { return *m_zone; }
void set_zone(msgpack::zone& zone) { m_zone = &zone; } void set_zone(msgpack::zone& zone) { m_zone = &zone; }
bool referenced() const { return m_referenced; } bool referenced() const { return m_referenced; }
void set_referenced(bool referenced) { m_referenced = referenced; } void set_referenced(bool referenced) { m_referenced = referenced; }
unpack_reference_func reference_func() const { return m_func; }
void* user_data() const { return m_user_data; }
private: private:
msgpack::zone* m_zone; msgpack::zone* m_zone;
bool m_referenced; bool m_referenced;
unpack_reference_func m_func;
void* m_user_data;
}; };
inline void unpack_uint8(uint8_t d, object& o) inline void unpack_uint8(uint8_t d, object& o)
@ -106,7 +113,7 @@ inline void unpack_false(object& o)
{ o.type = type::BOOLEAN; o.via.boolean = false; } { o.type = type::BOOLEAN; o.via.boolean = false; }
struct unpack_array { struct unpack_array {
void operator()(unpack_user&u, unsigned int n, object& o) const { void operator()(unpack_user& u, uint32_t n, object& o) const {
o.type = type::ARRAY; o.type = type::ARRAY;
o.via.array.size = 0; o.via.array.size = 0;
o.via.array.ptr = static_cast<object*>(u.zone().allocate_align(n*sizeof(object))); o.via.array.ptr = static_cast<object*>(u.zone().allocate_align(n*sizeof(object)));
@ -116,14 +123,14 @@ struct unpack_array {
inline void unpack_array_item(object& c, object const& o) inline void unpack_array_item(object& c, object const& o)
{ {
#if defined(__GNUC__) && !defined(__clang__) #if defined(__GNUC__) && !defined(__clang__)
memcpy(&c.via.array.ptr[c.via.array.size++], &o, sizeof(object)); std::memcpy(&c.via.array.ptr[c.via.array.size++], &o, sizeof(object));
#else /* __GNUC__ && !__clang__ */ #else /* __GNUC__ && !__clang__ */
c.via.array.ptr[c.via.array.size++] = o; c.via.array.ptr[c.via.array.size++] = o;
#endif /* __GNUC__ && !__clang__ */ #endif /* __GNUC__ && !__clang__ */
} }
struct unpack_map { struct unpack_map {
void operator()(unpack_user& u, unsigned int n, object& o) const { void operator()(unpack_user& u, uint32_t n, object& o) const {
o.type = type::MAP; o.type = type::MAP;
o.via.map.size = 0; o.via.map.size = 0;
o.via.map.ptr = static_cast<object_kv*>(u.zone().allocate_align(n*sizeof(object_kv))); o.via.map.ptr = static_cast<object_kv*>(u.zone().allocate_align(n*sizeof(object_kv)));
@ -133,8 +140,8 @@ struct unpack_map {
inline void unpack_map_item(object& c, object const& k, object const& v) inline void unpack_map_item(object& c, object const& k, object const& v)
{ {
#if defined(__GNUC__) && !defined(__clang__) #if defined(__GNUC__) && !defined(__clang__)
memcpy(&c.via.map.ptr[c.via.map.size].key, &k, sizeof(object)); std::memcpy(&c.via.map.ptr[c.via.map.size].key, &k, sizeof(object));
memcpy(&c.via.map.ptr[c.via.map.size].val, &v, sizeof(object)); std::memcpy(&c.via.map.ptr[c.via.map.size].val, &v, sizeof(object));
#else /* __GNUC__ && !__clang__ */ #else /* __GNUC__ && !__clang__ */
c.via.map.ptr[c.via.map.size].key = k; c.via.map.ptr[c.via.map.size].key = k;
c.via.map.ptr[c.via.map.size].val = v; c.via.map.ptr[c.via.map.size].val = v;
@ -142,20 +149,49 @@ inline void unpack_map_item(object& c, object const& k, object const& v)
++c.via.map.size; ++c.via.map.size;
} }
inline void unpack_str(unpack_user& u, const char* b, const char* p, unsigned int l, object& o) inline void unpack_str(unpack_user& u, const char* b, const char* p, uint64_t l, object& o)
{ {
o.type = type::STR; o.type = type::STR;
o.via.str.ptr = p; if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
o.via.str.ptr = p;
u.set_referenced(true);
}
else {
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
std::memcpy(tmp, p, l);
o.via.str.ptr = tmp;
}
o.via.str.size = l; o.via.str.size = l;
u.set_referenced(true);
} }
inline void unpack_bin(unpack_user& u, const char* b, const char* p, unsigned int l, object& o) inline void unpack_bin(unpack_user& u, const char* b, const char* p, uint64_t l, object& o)
{ {
o.type = type::BIN; o.type = type::BIN;
o.via.bin.ptr = p; if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
o.via.bin.ptr = p;
u.set_referenced(true);
}
else {
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
std::memcpy(tmp, p, l);
o.via.bin.ptr = tmp;
}
o.via.bin.size = l; o.via.bin.size = l;
u.set_referenced(true); }
inline void unpack_ext(unpack_user& u, const char* p, uint64_t l, object& o)
{
o.type = type::EXT;
if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
o.via.ext.ptr = p;
u.set_referenced(true);
}
else {
char* tmp = static_cast<char*>(u.zone().allocate_align(l));
std::memcpy(tmp, p, l);
o.via.ext.ptr = tmp;
}
o.via.ext.size = l - 1;
} }
@ -167,14 +203,14 @@ public:
std::size_t count() const { return m_count; } std::size_t count() const { return m_count; }
void set_count(std::size_t count) { m_count = count; } void set_count(std::size_t count) { m_count = count; }
std::size_t decl_count() { return --m_count; } std::size_t decl_count() { return --m_count; }
unsigned int container_type() const { return m_container_type; } uint32_t container_type() const { return m_container_type; }
void set_container_type(unsigned int container_type) { m_container_type = container_type; } void set_container_type(uint32_t container_type) { m_container_type = container_type; }
object const& map_key() const { return m_map_key; } object const& map_key() const { return m_map_key; }
void set_map_key(object const& map_key) { m_map_key = map_key; } void set_map_key(object const& map_key) { m_map_key = map_key; }
private: private:
object m_obj; object m_obj;
std::size_t m_count; std::size_t m_count;
unsigned int m_container_type; uint32_t m_container_type;
object m_map_key; object m_map_key;
}; };
@ -210,12 +246,12 @@ struct value {
}; };
template <> template <>
struct value<fix_tag> { struct value<fix_tag> {
typedef unsigned int type; typedef uint32_t type;
}; };
template <typename T> template <typename T>
inline void load(unsigned int& dst, const char* n, typename msgpack::enable_if<sizeof(T) == sizeof(fix_tag)>::type* = nullptr) { inline void load(uint32_t& dst, const char* n, typename msgpack::enable_if<sizeof(T) == sizeof(fix_tag)>::type* = nullptr) {
dst = static_cast<unsigned int>(*reinterpret_cast<const uint8_t*>(n)) & 0x0f; dst = static_cast<uint32_t>(*reinterpret_cast<const uint8_t*>(n)) & 0x0f;
} }
template <typename T> template <typename T>
@ -240,7 +276,7 @@ inline void load(T& dst, const char* n, typename msgpack::enable_if<sizeof(T) ==
class context { class context {
public: public:
context():m_trail(0), m_cs(CS_HEADER), m_top(0) context(unpack_reference_func f, void* user_data):m_trail(0), m_user(f, user_data), m_cs(CS_HEADER), m_top(0)
{ {
m_stack[0].set_obj(object()); m_stack[0].set_obj(object());
} }
@ -305,28 +341,36 @@ public:
int ret = push_proc(obj, off); int ret = push_proc(obj, off);
if (ret != 0) return ret; if (ret != 0) return ret;
} break; } break;
//case 0xc1: // string //case 0xc1: // string
case 0xc2: { // false case 0xc2: { // false
unpack_false(obj); unpack_false(obj);
int ret = push_proc(obj, off); int ret = push_proc(obj, off);
if (ret != 0) return ret; if (ret != 0) return ret;
} break; } break;
case 0xc3: { // true case 0xc3: { // true
unpack_true(obj); unpack_true(obj);
int ret = push_proc(obj, off); int ret = push_proc(obj, off);
if (ret != 0) return ret; if (ret != 0) return ret;
} break; } break;
case 0xc4: // bin 8 case 0xc4: // bin 8
case 0xc5: // bin 16 case 0xc5: // bin 16
case 0xc6: // bin 32 case 0xc6: // bin 32
m_trail = 1 << (static_cast<unsigned int>(*m_current) & 0x03); m_trail = 1 << (static_cast<uint32_t>(*m_current) & 0x03);
m_cs = next_cs(m_current);
fixed_trail_again = true;
break;
case 0xc7: // ext 8
case 0xc8: // ext 16
case 0xc9: // ext 32
m_trail = 1 << ((static_cast<uint32_t>(*m_current) + 1) & 0x03);
m_cs = next_cs(m_current); m_cs = next_cs(m_current);
fixed_trail_again = true; fixed_trail_again = true;
break; break;
//case 0xc7:
//case 0xc8:
//case 0xc9:
case 0xca: // float case 0xca: // float
case 0xcb: // double case 0xcb: // double
case 0xcc: // unsigned int 8 case 0xcc: // unsigned int 8
@ -337,36 +381,49 @@ public:
case 0xd1: // signed int 16 case 0xd1: // signed int 16
case 0xd2: // signed int 32 case 0xd2: // signed int 32
case 0xd3: // signed int 64 case 0xd3: // signed int 64
m_trail = 1 << (static_cast<unsigned int>(*m_current) & 0x03); m_trail = 1 << (static_cast<uint32_t>(*m_current) & 0x03);
m_cs = next_cs(m_current); m_cs = next_cs(m_current);
fixed_trail_again = true; fixed_trail_again = true;
break; break;
//case 0xd4:
//case 0xd5: case 0xd4: // fixext 1
//case 0xd6: // big integer 16 case 0xd5: // fixext 2
//case 0xd7: // big integer 32 case 0xd6: // fixext 4
//case 0xd8: // big float 16 case 0xd7: // fixext 8
m_trail = (1 << (static_cast<uint32_t>(*m_current) & 0x03)) + 1;
m_cs = next_cs(m_current);
fixed_trail_again = true;
break;
case 0xd8: // fixext 16
m_trail = 17;
m_cs = next_cs(m_current);
fixed_trail_again = true;
break;
case 0xd9: // str 8 case 0xd9: // str 8
case 0xda: // str 16 case 0xda: // str 16
case 0xdb: // str 32 case 0xdb: // str 32
m_trail = 1 << ((static_cast<unsigned int>(*m_current) & 0x03) - 1); m_trail = 1 << ((static_cast<uint32_t>(*m_current) & 0x03) - 1);
m_cs = next_cs(m_current); m_cs = next_cs(m_current);
fixed_trail_again = true; fixed_trail_again = true;
break; break;
case 0xdc: // array 16 case 0xdc: // array 16
case 0xdd: // array 32 case 0xdd: // array 32
case 0xde: // map 16 case 0xde: // map 16
case 0xdf: // map 32 case 0xdf: // map 32
m_trail = 2 << (static_cast<unsigned int>(*m_current) & 0x01); m_trail = 2 << (static_cast<uint32_t>(*m_current) & 0x01);
m_cs = next_cs(m_current); m_cs = next_cs(m_current);
fixed_trail_again = true; fixed_trail_again = true;
break; break;
default: default:
off = m_current - m_start; off = m_current - m_start;
return -1; return -1;
} }
} else if(0xa0 <= selector && selector <= 0xbf) { // FixStr } else if(0xa0 <= selector && selector <= 0xbf) { // FixStr
m_trail = static_cast<unsigned int>(*m_current) & 0x1f; m_trail = static_cast<uint32_t>(*m_current) & 0x1f;
if(m_trail == 0) { if(m_trail == 0) {
unpack_str(m_user, data, n, m_trail, obj); unpack_str(m_user, data, n, m_trail, obj);
int ret = push_proc(obj, off); int ret = push_proc(obj, off);
@ -479,6 +536,31 @@ public:
int ret = push_proc(obj, off); int ret = push_proc(obj, off);
if (ret != 0) return ret; if (ret != 0) return ret;
} break; } break;
case CS_FIXEXT_1: {
unpack_ext(m_user, n, 1+1, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_FIXEXT_2: {
unpack_ext(m_user, n, 2+1, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_FIXEXT_4: {
unpack_ext(m_user, n, 4+1, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_FIXEXT_8: {
unpack_ext(m_user, n, 8+1, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_FIXEXT_16: {
unpack_ext(m_user, n, 16+1, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_STR_8: { case CS_STR_8: {
uint8_t tmp; uint8_t tmp;
load<uint8_t>(tmp, n); load<uint8_t>(tmp, n);
@ -507,6 +589,20 @@ public:
fixed_trail_again = true; fixed_trail_again = true;
} }
} break; } break;
case CS_EXT_8: {
uint8_t tmp;
load<uint8_t>(tmp, n);
m_trail = tmp + 1;
if(m_trail == 0) {
unpack_ext(m_user, n, m_trail, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
}
else {
m_cs = ACS_EXT_VALUE;
fixed_trail_again = true;
}
} break;
case CS_STR_16: { case CS_STR_16: {
uint16_t tmp; uint16_t tmp;
load<uint16_t>(tmp, n); load<uint16_t>(tmp, n);
@ -535,8 +631,24 @@ public:
fixed_trail_again = true; fixed_trail_again = true;
} }
} break; } break;
case CS_STR_32: case CS_EXT_16: {
load<uint32_t>(m_trail, n); uint16_t tmp;
load<uint16_t>(tmp, n);
m_trail = tmp + 1;
if(m_trail == 0) {
unpack_ext(m_user, n, m_trail, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
}
else {
m_cs = ACS_EXT_VALUE;
fixed_trail_again = true;
}
} break;
case CS_STR_32: {
uint32_t tmp;
load<uint32_t>(tmp, n);
m_trail = tmp;
if(m_trail == 0) { if(m_trail == 0) {
unpack_str(m_user, data, n, m_trail, obj); unpack_str(m_user, data, n, m_trail, obj);
int ret = push_proc(obj, off); int ret = push_proc(obj, off);
@ -546,9 +658,11 @@ public:
m_cs = ACS_STR_VALUE; m_cs = ACS_STR_VALUE;
fixed_trail_again = true; fixed_trail_again = true;
} }
break; } break;
case CS_BIN_32: case CS_BIN_32: {
load<uint32_t>(m_trail, n); uint32_t tmp;
load<uint32_t>(tmp, n);
m_trail = tmp;
if(m_trail == 0) { if(m_trail == 0) {
unpack_bin(m_user, data, n, m_trail, obj); unpack_bin(m_user, data, n, m_trail, obj);
int ret = push_proc(obj, off); int ret = push_proc(obj, off);
@ -558,7 +672,21 @@ public:
m_cs = ACS_BIN_VALUE; m_cs = ACS_BIN_VALUE;
fixed_trail_again = true; fixed_trail_again = true;
} }
break; } break;
case CS_EXT_32: {
uint32_t tmp;
load<uint32_t>(tmp, n);
m_trail = tmp + 1;
if(m_trail == 0) {
unpack_ext(m_user, n, m_trail, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
}
else {
m_cs = ACS_EXT_VALUE;
fixed_trail_again = true;
}
} break;
case ACS_STR_VALUE: { case ACS_STR_VALUE: {
unpack_str(m_user, data, n, m_trail, obj); unpack_str(m_user, data, n, m_trail, obj);
int ret = push_proc(obj, off); int ret = push_proc(obj, off);
@ -569,6 +697,11 @@ public:
int ret = push_proc(obj, off); int ret = push_proc(obj, off);
if (ret != 0) return ret; if (ret != 0) return ret;
} break; } break;
case ACS_EXT_VALUE: {
unpack_ext(m_user, n, m_trail, obj);
int ret = push_proc(obj, off);
if (ret != 0) return ret;
} break;
case CS_ARRAY_16: { case CS_ARRAY_16: {
int ret = push_aggregate<uint16_t>( int ret = push_aggregate<uint16_t>(
unpack_array(), CT_ARRAY_ITEM, obj, n, off); unpack_array(), CT_ARRAY_ITEM, obj, n, off);
@ -604,15 +737,15 @@ public:
private: private:
template <typename T> template <typename T>
static unsigned int next_cs(T p) static uint32_t next_cs(T p)
{ {
return static_cast<unsigned int>(*p) & 0x1f; return static_cast<uint32_t>(*p) & 0x1f;
} }
template <typename T, typename Func> template <typename T, typename Func>
int push_aggregate( int push_aggregate(
Func const& f, Func const& f,
unsigned int container_type, uint32_t container_type,
object& obj, object& obj,
const char* load_pos, const char* load_pos,
std::size_t& off) { std::size_t& off) {
@ -706,11 +839,11 @@ private:
char const* m_start; char const* m_start;
char const* m_current; char const* m_current;
unsigned int m_trail; uint64_t m_trail;
unpack_user m_user; unpack_user m_user;
unsigned int m_cs; uint32_t m_cs;
unsigned int m_top; uint32_t m_top;
unsigned int m_stack_idx; uint32_t m_stack_idx;
unpack_stack m_stack[MSGPACK_EMBED_STACK_SIZE]; unpack_stack m_stack[MSGPACK_EMBED_STACK_SIZE];
}; };
@ -730,7 +863,7 @@ struct unpack_error : public std::runtime_error {
class unpacked { class unpacked {
public: public:
unpacked() { } unpacked():m_referenced(false) { }
unpacked(object const& obj, msgpack::unique_ptr<msgpack::zone> z) : unpacked(object const& obj, msgpack::unique_ptr<msgpack::zone> z) :
m_obj(obj), m_zone(msgpack::move(z)) { } m_obj(obj), m_zone(msgpack::move(z)) { }
@ -747,15 +880,24 @@ public:
const msgpack::unique_ptr<msgpack::zone>& zone() const const msgpack::unique_ptr<msgpack::zone>& zone() const
{ return m_zone; } { return m_zone; }
void set_referenced(bool r)
{ m_referenced = r; }
bool referenced() const
{ return m_referenced; }
private: private:
object m_obj; object m_obj;
msgpack::unique_ptr<msgpack::zone> m_zone; msgpack::unique_ptr<msgpack::zone> m_zone;
bool m_referenced;
}; };
class unpacker { class unpacker {
public: public:
unpacker(std::size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE); unpacker(unpack_reference_func f = &unpacker::default_reference_func,
void* user_data = nullptr,
std::size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
#if !defined(MSGPACK_USE_CPP03) #if !defined(MSGPACK_USE_CPP03)
unpacker(unpacker&& other); unpacker(unpacker&& other);
@ -854,6 +996,7 @@ private:
void expand_buffer(std::size_t size); void expand_buffer(std::size_t size);
int execute_imp(); int execute_imp();
bool flush_zone(); bool flush_zone();
static bool default_reference_func(type::object_type type, uint64_t len, void*);
private: private:
char* m_buffer; char* m_buffer;
@ -871,14 +1014,19 @@ private:
}; };
inline void unpack(unpacked& result, inline void unpack(unpacked& result,
const char* data, std::size_t len, std::size_t& off); const char* data, std::size_t len, std::size_t& off,
unpack_reference_func f = nullptr, void* user_data = nullptr);
inline void unpack(unpacked& result, inline void unpack(unpacked& result,
const char* data, std::size_t len); const char* data, std::size_t len,
// obsolete unpack_reference_func f = nullptr, void* user_data = nullptr);
inline void unpack(unpacked* result,
const char* data, std::size_t len, std::size_t* off = nullptr);
// obsolete // obsolete
inline void unpack(unpacked* result,
const char* data, std::size_t len, std::size_t* off = nullptr,
unpack_reference_func f = nullptr, void* user_data = nullptr);
// for internal use
typedef enum { typedef enum {
UNPACK_SUCCESS = 2, UNPACK_SUCCESS = 2,
UNPACK_EXTRA_BYTES = 1, UNPACK_EXTRA_BYTES = 1,
@ -886,22 +1034,10 @@ typedef enum {
UNPACK_PARSE_ERROR = -1 UNPACK_PARSE_ERROR = -1
} unpack_return; } unpack_return;
// obsolete inline unpacker::unpacker(unpack_reference_func f,
static unpack_return unpack(const char* data, std::size_t len, std::size_t& off, void* user_data,
zone& z, object& result); std::size_t initial_buffer_size)
static unpack_return unpack(const char* data, std::size_t len, :m_ctx(f, user_data)
zone& z, object& result);
static unpack_return unpack(const char* data, std::size_t len, std::size_t* off,
zone* z, object* result);
// obsolete
static object unpack(const char* data, std::size_t len, zone& z, std::size_t& off);
static object unpack(const char* data, std::size_t len, zone& z);
static object unpack(const char* data, std::size_t len, zone* z, std::size_t* off = nullptr);
inline unpacker::unpacker(std::size_t initial_buffer_size)
{ {
if(initial_buffer_size < COUNTER_SIZE) { if(initial_buffer_size < COUNTER_SIZE) {
initial_buffer_size = COUNTER_SIZE; initial_buffer_size = COUNTER_SIZE;
@ -1012,7 +1148,7 @@ inline void unpacker::expand_buffer(std::size_t size)
detail::init_count(tmp); detail::init_count(tmp);
::memcpy(tmp+COUNTER_SIZE, m_buffer + m_off, not_parsed); std::memcpy(tmp+COUNTER_SIZE, m_buffer + m_off, not_parsed);
if(m_ctx.user().referenced()) { if(m_ctx.user().referenced()) {
try { try {
@ -1066,6 +1202,7 @@ inline bool unpacker::next(unpacked& result)
} else { } else {
result.zone().reset( release_zone() ); result.zone().reset( release_zone() );
result.set(data()); result.set(data());
result.set_referenced(m_ctx.user().referenced());
reset(); reset();
return true; return true;
} }
@ -1184,7 +1321,8 @@ namespace detail {
inline unpack_return inline unpack_return
unpack_imp(const char* data, std::size_t len, std::size_t& off, unpack_imp(const char* data, std::size_t len, std::size_t& off,
zone& result_zone, object& result) zone& result_zone, object& result, bool& referenced,
unpack_reference_func f = nullptr, void* user_data = nullptr)
{ {
std::size_t noff = off; std::size_t noff = off;
@ -1193,17 +1331,19 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
return UNPACK_CONTINUE; return UNPACK_CONTINUE;
} }
detail::context ctx; detail::context ctx(f, user_data);
ctx.init(); ctx.init();
ctx.user().set_zone(result_zone); ctx.user().set_zone(result_zone);
ctx.user().set_referenced(false); ctx.user().set_referenced(false);
referenced = false;
int e = ctx.execute(data, len, noff); int e = ctx.execute(data, len, noff);
if(e < 0) { if(e < 0) {
return UNPACK_PARSE_ERROR; return UNPACK_PARSE_ERROR;
} }
referenced = ctx.user().referenced();
off = noff; off = noff;
if(e == 0) { if(e == 0) {
@ -1223,29 +1363,28 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
// reference version // reference version
inline void unpack(unpacked& result, inline void unpack(unpacked& result,
const char* data, std::size_t len, std::size_t& off) const char* data, std::size_t len, std::size_t& off,
unpack_reference_func f, void* user_data)
{ {
object obj; object obj;
msgpack::unique_ptr<zone> z(new zone()); msgpack::unique_ptr<zone> z(new zone());
bool referenced = false;
unpack_return ret = detail::unpack_imp( unpack_return ret = detail::unpack_imp(
data, len, off, *z, obj); data, len, off, *z, obj, referenced);
result.set_referenced(referenced);
switch(ret) { switch(ret) {
case UNPACK_SUCCESS: case UNPACK_SUCCESS:
result.set(obj); result.set(obj);
result.zone() = msgpack::move(z); result.zone() = msgpack::move(z);
return; return;
case UNPACK_EXTRA_BYTES: case UNPACK_EXTRA_BYTES:
result.set(obj); result.set(obj);
result.zone() = msgpack::move(z); result.zone() = msgpack::move(z);
return; return;
case UNPACK_CONTINUE: case UNPACK_CONTINUE:
throw unpack_error("insufficient bytes"); throw unpack_error("insufficient bytes");
case UNPACK_PARSE_ERROR: case UNPACK_PARSE_ERROR:
default: default:
throw unpack_error("parse error"); throw unpack_error("parse error");
@ -1253,88 +1392,29 @@ inline void unpack(unpacked& result,
} }
inline void unpack(unpacked& result, inline void unpack(unpacked& result,
const char* data, std::size_t len) const char* data, std::size_t len,
unpack_reference_func f, void* user_data)
{ {
std::size_t off = 0; std::size_t off = 0;
return unpack(result, data, len, off); unpack(result, data, len, off, f, user_data);
} }
// obsolete // obsolete
// pointer version // pointer version
inline void unpack(unpacked* result, inline void unpack(unpacked* result,
const char* data, std::size_t len, std::size_t* off) { const char* data, std::size_t len, std::size_t* off,
unpack_reference_func f, void* user_data)
{
if (off) unpack(*result, data, len, *off); if (off) unpack(*result, data, len, *off);
else unpack(*result, data, len); else unpack(*result, data, len, f, user_data);
} }
bool unpacker::default_reference_func(type::object_type type, uint64_t len, void*)
// obsolete
// reference version
inline unpack_return unpack(const char* data, std::size_t len, std::size_t& off,
zone& z, object& result)
{ {
return detail::unpack_imp(data, len, off, z, result); return true;
}
// obsolete
inline unpack_return unpack(const char* data, std::size_t len,
zone& z, object& result)
{
std::size_t off = 0;
return detail::unpack_imp(data, len, off, z, result);
}
// obsolete
// pointer version
inline unpack_return unpack(const char* data, std::size_t len, std::size_t* off,
zone* z, object* result)
{
if (off) return unpack(data, len, *off, *z, *result);
else return unpack(data, len, *z, *result);
}
// obsolete
// reference version
inline object unpack(const char* data, std::size_t len, zone& z, std::size_t& off)
{
object result;
switch( unpack(data, len, off, z, result) ) {
case UNPACK_SUCCESS:
return result;
case UNPACK_EXTRA_BYTES:
if(off) {
return result;
} else {
throw unpack_error("extra bytes");
}
case UNPACK_CONTINUE:
throw unpack_error("insufficient bytes");
case UNPACK_PARSE_ERROR:
default:
throw unpack_error("parse error");
}
}
// obsolete
inline object unpack(const char* data, std::size_t len, zone& z)
{
std::size_t off = 0;
return unpack(data, len, z, off);
}
// obsolete
// pointer version
inline object unpack(const char* data, std::size_t len, zone* z, std::size_t* off)
{
if (off) return unpack(data, len, *z, *off);
else return unpack(data, len, *z);
} }
} // namespace msgpack } // namespace msgpack
#endif /* msgpack/unpack.hpp */ #endif /* msgpack/unpack.hpp */

View File

@ -45,9 +45,9 @@ typedef enum {
CS_BIN_16 = 0x05, CS_BIN_16 = 0x05,
CS_BIN_32 = 0x06, CS_BIN_32 = 0x06,
//CS_EXT_8 = 0x07, CS_EXT_8 = 0x07,
//CS_EXT_16 = 0x08, CS_EXT_16 = 0x08,
//CS_EXT_32 = 0x09, CS_EXT_32 = 0x09,
CS_FLOAT = 0x0a, CS_FLOAT = 0x0a,
CS_DOUBLE = 0x0b, CS_DOUBLE = 0x0b,
@ -60,11 +60,11 @@ typedef enum {
CS_INT_32 = 0x12, CS_INT_32 = 0x12,
CS_INT_64 = 0x13, CS_INT_64 = 0x13,
//CS_FIXEXT_1 = 0x14, CS_FIXEXT_1 = 0x14,
//CS_FIXEXT_2 = 0x15, CS_FIXEXT_2 = 0x15,
//CS_FIXEXT_4 = 0x16, CS_FIXEXT_4 = 0x16,
//CS_FIXEXT_8 = 0x17, CS_FIXEXT_8 = 0x17,
//CS_FIXEXT_16 = 0x18, CS_FIXEXT_16 = 0x18,
CS_STR_8 = 0x19, // str8 CS_STR_8 = 0x19, // str8
CS_STR_16 = 0x1a, // str16 CS_STR_16 = 0x1a, // str16
@ -77,7 +77,8 @@ typedef enum {
//ACS_BIG_INT_VALUE, //ACS_BIG_INT_VALUE,
//ACS_BIG_FLOAT_VALUE, //ACS_BIG_FLOAT_VALUE,
ACS_STR_VALUE, ACS_STR_VALUE,
ACS_BIN_VALUE ACS_BIN_VALUE,
ACS_EXT_VALUE
} msgpack_unpack_state; } msgpack_unpack_state;

View File

@ -274,6 +274,170 @@ TEST(MSGPACK, simple_buffer_false)
EXPECT_EQ(val1, val2); EXPECT_EQ(val1, val2);
} }
TEST(MSGPACK, simple_buffer_fixext1)
{
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
char const buf [] = { 2 };
packer.pack_ext(sizeof(buf), 1);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::unpacked ret;
msgpack::unpack(ret, sbuf.data(), sbuf.size());
EXPECT_EQ(1, ret.get().via.ext.size);
EXPECT_EQ(1, ret.get().via.ext.type());
EXPECT_EQ(2, ret.get().via.ext.data()[0]);
}
TEST(MSGPACK, simple_buffer_fixext2)
{
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
char const buf [] = { 2, 3 };
packer.pack_ext(sizeof(buf), 0);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::unpacked ret;
msgpack::unpack(ret, sbuf.data(), sbuf.size());
EXPECT_EQ(2, ret.get().via.ext.size);
EXPECT_EQ(0, ret.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), ret.get().via.ext.data()));
}
TEST(MSGPACK, simple_buffer_fixext4)
{
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
char const buf [] = { 2, 3, 4, 5 };
packer.pack_ext(sizeof(buf), 1);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::unpacked ret;
msgpack::unpack(ret, sbuf.data(), sbuf.size());
EXPECT_EQ(4, ret.get().via.ext.size);
EXPECT_EQ(1, ret.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), ret.get().via.ext.data()));
}
TEST(MSGPACK, simple_buffer_fixext8)
{
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
char const buf [] = { 2, 3, 4, 5, 6, 7, 8, 9 };
packer.pack_ext(sizeof(buf), 1);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::unpacked ret;
msgpack::unpack(ret, sbuf.data(), sbuf.size());
EXPECT_EQ(8, ret.get().via.ext.size);
EXPECT_EQ(1, ret.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), ret.get().via.ext.data()));
}
TEST(MSGPACK, simple_buffer_fixext16)
{
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
char const buf [] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
packer.pack_ext(sizeof(buf), 1);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::unpacked ret;
msgpack::unpack(ret, sbuf.data(), sbuf.size());
EXPECT_EQ(16, ret.get().via.ext.size);
EXPECT_EQ(1, ret.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), ret.get().via.ext.data()));
}
TEST(MSGPACK, simple_buffer_fixext_1byte_0)
{
std::size_t const size = 0;
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
packer.pack_ext(size, 77);
msgpack::unpacked ret;
msgpack::unpack(ret, sbuf.data(), sbuf.size());
EXPECT_EQ(size, ret.get().via.ext.size);
EXPECT_EQ(77, ret.get().via.ext.type());
}
TEST(MSGPACK, simple_buffer_fixext_1byte_255)
{
std::size_t const size = 255;
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
char buf[size];
for (int i = 0; i != size; ++i) buf[i] = static_cast<char>(i);
packer.pack_ext(sizeof(buf), 77);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::unpacked ret;
msgpack::unpack(ret, sbuf.data(), sbuf.size());
EXPECT_EQ(size, ret.get().via.ext.size);
EXPECT_EQ(77, ret.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), ret.get().via.ext.data()));
}
TEST(MSGPACK, simple_buffer_fixext_2byte_256)
{
std::size_t const size = 256;
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
char buf[size];
for (int i = 0; i != size; ++i) buf[i] = static_cast<char>(i);
packer.pack_ext(sizeof(buf), 77);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::unpacked ret;
msgpack::unpack(ret, sbuf.data(), sbuf.size());
EXPECT_EQ(size, ret.get().via.ext.size);
EXPECT_EQ(77, ret.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), ret.get().via.ext.data()));
}
TEST(MSGPACK, simple_buffer_fixext_2byte_65535)
{
std::size_t const size = 65535;
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
char buf[size];
for (int i = 0; i != size; ++i) buf[i] = static_cast<char>(i);
packer.pack_ext(sizeof(buf), 77);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::unpacked ret;
msgpack::unpack(ret, sbuf.data(), sbuf.size());
EXPECT_EQ(size, ret.get().via.ext.size);
EXPECT_EQ(77, ret.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), ret.get().via.ext.data()));
}
TEST(MSGPACK, simple_buffer_fixext_4byte_65536)
{
std::size_t const size = 65536;
msgpack::sbuffer sbuf;
msgpack::packer<msgpack::sbuffer> packer(sbuf);
char buf[size];
for (int i = 0; i != size; ++i) buf[i] = static_cast<char>(i);
packer.pack_ext(sizeof(buf), 77);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::unpacked ret;
msgpack::unpack(ret, sbuf.data(), sbuf.size());
EXPECT_EQ(size, ret.get().via.ext.size);
EXPECT_EQ(77, ret.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), ret.get().via.ext.data()));
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// STL // STL
@ -707,16 +871,9 @@ TEST(MSGPACK_USER_DEFINED, simple_buffer_class_old_to_new)
TestClass val1; TestClass val1;
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1); msgpack::pack(sbuf, val1);
msgpack::zone z; msgpack::unpacked ret;
msgpack::object obj; msgpack::unpack(ret, sbuf.data(), sbuf.size());
msgpack::unpack_return ret = TestClass2 val2 = ret.get().as<TestClass2>();
msgpack::unpack(sbuf.data(), sbuf.size(), z, obj);
EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret);
TestClass2 val2;
val2.i = -1;
val2.s = "";
val2.v = vector<int>();
obj.convert(&val2);
EXPECT_EQ(val1.i, val2.i); EXPECT_EQ(val1.i, val2.i);
EXPECT_EQ(val1.s, val2.s); EXPECT_EQ(val1.s, val2.s);
EXPECT_FALSE(val2.s.empty()); EXPECT_FALSE(val2.s.empty());

View File

@ -49,88 +49,6 @@ TEST(pack, myclass)
msgpack::pack(sbuf, m); msgpack::pack(sbuf, m);
} }
TEST(unpack, myclass_no_offset)
{
msgpack::sbuffer sbuf;
myclass m1(1, "phraser");
msgpack::pack(sbuf, m1);
msgpack::zone z;
msgpack::object obj;
// obsolete
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), z, obj);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
myclass m2 = obj.as<myclass>();
EXPECT_EQ(m1.num, m2.num);
EXPECT_EQ(m1.str, m2.str);
}
TEST(unpack, myclass_offset)
{
msgpack::sbuffer sbuf;
myclass m1(1, "phraser");
msgpack::pack(sbuf, m1);
msgpack::zone z;
msgpack::object obj;
std::size_t off = 0;
// obsolete
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), off, z, obj);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
myclass m2 = obj.as<myclass>();
EXPECT_EQ(m1.num, m2.num);
EXPECT_EQ(m1.str, m2.str);
EXPECT_EQ(off, sbuf.size());
}
TEST(unpack, myclass_offset_pointer)
{
msgpack::sbuffer sbuf;
myclass m1(1, "phraser");
msgpack::pack(sbuf, m1);
msgpack::zone z;
msgpack::object obj;
std::size_t off = 0;
// obsolete
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), &off, &z, &obj);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
myclass m2 = obj.as<myclass>();
EXPECT_EQ(m1.num, m2.num);
EXPECT_EQ(m1.str, m2.str);
EXPECT_EQ(off, sbuf.size());
}
TEST(unpack, myclass_offset_null_pointer)
{
msgpack::sbuffer sbuf;
myclass m1(1, "phraser");
msgpack::pack(sbuf, m1);
msgpack::zone z;
msgpack::object obj;
// obsolete
msgpack::unpack_return ret =
msgpack::unpack(sbuf.data(), sbuf.size(), nullptr, &z, &obj);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
myclass m2 = obj.as<myclass>();
EXPECT_EQ(m1.num, m2.num);
EXPECT_EQ(m1.str, m2.str);
}
TEST(unpack, int_no_offset) TEST(unpack, int_no_offset)
{ {
msgpack::sbuffer sbuf; msgpack::sbuffer sbuf;
@ -212,106 +130,3 @@ TEST(unpack, sequence)
EXPECT_EQ(off, sbuf.size()); EXPECT_EQ(off, sbuf.size());
} }
TEST(unpack_return, int_no_offset)
{
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret;
// obsolete
ret = msgpack::unpack(sbuf.data(), sbuf.size(), z, obj);
EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
EXPECT_EQ(1, obj.as<int>());
}
TEST(unpack_return, int_offset)
{
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1);
std::size_t off = 0;
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret;
// obsolete
ret = msgpack::unpack(sbuf.data(), sbuf.size(), off, z, obj);
EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
EXPECT_EQ(1, obj.as<int>());
EXPECT_EQ(off, sbuf.size());
}
TEST(unpack_return, int_pointer)
{
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1);
std::size_t off = 0;
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret;
// obsolete
ret = msgpack::unpack(sbuf.data(), sbuf.size(), &off, &z, &obj);
EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
EXPECT_EQ(1, obj.as<int>());
EXPECT_EQ(off, sbuf.size());
}
TEST(unpack_return, int_null_pointer)
{
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1);
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret;
// obsolete
ret = msgpack::unpack(sbuf.data(), sbuf.size(), nullptr, &z, &obj);
EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
EXPECT_EQ(1, obj.as<int>());
}
TEST(unpack, sequence_compat)
{
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, 1);
msgpack::pack(sbuf, 2);
msgpack::pack(sbuf, 3);
std::size_t off = 0;
msgpack::zone z;
msgpack::object obj;
msgpack::unpack_return ret;
// obsolete
ret = msgpack::unpack(sbuf.data(), sbuf.size(), off, z, obj);
EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES);
EXPECT_EQ(1, obj.as<int>());
// obsolete
ret = msgpack::unpack(sbuf.data(), sbuf.size(), off, z, obj);
EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES);
EXPECT_EQ(2, obj.as<int>());
// obsolete
ret = msgpack::unpack(sbuf.data(), sbuf.size(), off, z, obj);
EXPECT_TRUE(ret >= 0);
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
EXPECT_EQ(3, obj.as<int>());
}