mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-05-28 15:14:11 +02:00
Added additional unpack() APIs to support C++11 style programming.
This commit is contained in:
parent
0335df55e1
commit
4fcb4777f3
@ -964,6 +964,24 @@ private:
|
||||
unpacker& operator=(const unpacker&);
|
||||
};
|
||||
|
||||
#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 = nullptr, void* user_data = nullptr);
|
||||
inline unpacked unpack(
|
||||
const char* data, std::size_t len, std::size_t& off,
|
||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
||||
inline unpacked unpack(
|
||||
const char* data, std::size_t len, bool& referenced,
|
||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
||||
inline unpacked unpack(
|
||||
const char* data, std::size_t len,
|
||||
unpack_reference_func f = nullptr, void* user_data = nullptr);
|
||||
|
||||
#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 = nullptr, void* user_data = nullptr);
|
||||
@ -1312,6 +1330,61 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
|
||||
} // detail
|
||||
|
||||
// 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)
|
||||
{
|
||||
object obj;
|
||||
msgpack::unique_ptr<zone> z(new zone);
|
||||
referenced = false;
|
||||
unpack_return ret = detail::unpack_imp(
|
||||
data, len, off, *z, obj, referenced, f, user_data);
|
||||
|
||||
switch(ret) {
|
||||
case UNPACK_SUCCESS:
|
||||
return unpacked(obj, msgpack::move(z));
|
||||
case UNPACK_EXTRA_BYTES:
|
||||
return unpacked(obj, msgpack::move(z));
|
||||
case UNPACK_CONTINUE:
|
||||
throw unpack_error("insufficient bytes");
|
||||
case UNPACK_PARSE_ERROR:
|
||||
default:
|
||||
throw unpack_error("parse error");
|
||||
}
|
||||
return unpacked();
|
||||
}
|
||||
|
||||
inline unpacked unpack(
|
||||
const char* data, std::size_t len, std::size_t& off,
|
||||
unpack_reference_func f, void* user_data)
|
||||
{
|
||||
bool referenced;
|
||||
return unpack(data, len, off, referenced, f, user_data);
|
||||
}
|
||||
|
||||
inline unpacked unpack(
|
||||
const char* data, std::size_t len, bool& referenced,
|
||||
unpack_reference_func f, void* user_data)
|
||||
{
|
||||
std::size_t off = 0;
|
||||
return unpack(data, len, off, referenced, f, user_data);
|
||||
}
|
||||
|
||||
inline unpacked unpack(
|
||||
const char* data, std::size_t len,
|
||||
unpack_reference_func f, void* user_data)
|
||||
{
|
||||
bool referenced;
|
||||
std::size_t off = 0;
|
||||
return unpack(data, len, off, referenced, f, user_data);
|
||||
}
|
||||
|
||||
#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)
|
||||
|
@ -33,6 +33,7 @@ LIST (APPEND check_PROGRAMS
|
||||
IF (MSGPACK_CXX11)
|
||||
LIST (APPEND check_PROGRAMS
|
||||
msgpack_cpp11.cpp
|
||||
reference_cpp11.cpp
|
||||
)
|
||||
ENDIF ()
|
||||
|
||||
|
@ -23,6 +23,7 @@ check_PROGRAMS = \
|
||||
msgpack_stream \
|
||||
msgpack_vref \
|
||||
msgpack_cpp11 \
|
||||
reference_cpp11 \
|
||||
reference
|
||||
|
||||
TESTS = $(check_PROGRAMS)
|
||||
@ -70,4 +71,6 @@ msgpack_cpp11_SOURCES = msgpack_cpp11.cpp
|
||||
|
||||
reference_SOURCES = reference.cpp
|
||||
|
||||
reference_cpp11_SOURCES = reference_cpp11.cpp
|
||||
|
||||
EXTRA_DIST = cases.mpac cases_compact.mpac
|
||||
|
@ -49,7 +49,58 @@ TEST(pack, myclass)
|
||||
msgpack::pack(sbuf, m);
|
||||
}
|
||||
|
||||
TEST(unpack, int_no_offset)
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
TEST(unpack, int_ret_no_offset_no_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
|
||||
msgpack::unpacked msg = msgpack::unpack(sbuf.data(), sbuf.size());
|
||||
EXPECT_EQ(1, msg.get().as<int>());
|
||||
}
|
||||
|
||||
TEST(unpack, int_ret_offset_no_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
|
||||
std::size_t off = 0;
|
||||
|
||||
msgpack::unpacked msg = msgpack::unpack(sbuf.data(), sbuf.size(), off);
|
||||
EXPECT_EQ(1, msg.get().as<int>());
|
||||
EXPECT_EQ(off, sbuf.size());
|
||||
}
|
||||
|
||||
TEST(unpack, int_ret_no_offset_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
bool referenced;
|
||||
|
||||
msgpack::unpacked msg = msgpack::unpack(sbuf.data(), sbuf.size(), referenced);
|
||||
EXPECT_EQ(1, msg.get().as<int>());
|
||||
EXPECT_EQ(false, referenced);
|
||||
}
|
||||
|
||||
TEST(unpack, int_ret_offset_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
std::size_t off = 0;
|
||||
bool referenced;
|
||||
|
||||
msgpack::unpacked msg = msgpack::unpack(sbuf.data(), sbuf.size(), off, referenced);
|
||||
EXPECT_EQ(1, msg.get().as<int>());
|
||||
EXPECT_EQ(false, referenced);
|
||||
EXPECT_EQ(off, sbuf.size());
|
||||
}
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
|
||||
TEST(unpack, int_no_offset_no_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
@ -59,7 +110,7 @@ TEST(unpack, int_no_offset)
|
||||
EXPECT_EQ(1, msg.get().as<int>());
|
||||
}
|
||||
|
||||
TEST(unpack, int_offset)
|
||||
TEST(unpack, int_offset_no_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
@ -72,7 +123,34 @@ TEST(unpack, int_offset)
|
||||
EXPECT_EQ(off, sbuf.size());
|
||||
}
|
||||
|
||||
TEST(unpack, int_pointer)
|
||||
TEST(unpack, int_no_offset_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
msgpack::unpacked msg;
|
||||
bool referenced;
|
||||
|
||||
msgpack::unpack(msg, sbuf.data(), sbuf.size(), referenced);
|
||||
EXPECT_EQ(1, msg.get().as<int>());
|
||||
EXPECT_EQ(false, referenced);
|
||||
}
|
||||
|
||||
TEST(unpack, int_offset_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
msgpack::unpacked msg;
|
||||
std::size_t off = 0;
|
||||
bool referenced;
|
||||
|
||||
msgpack::unpack(msg, sbuf.data(), sbuf.size(), off, referenced);
|
||||
EXPECT_EQ(1, msg.get().as<int>());
|
||||
EXPECT_EQ(false, referenced);
|
||||
EXPECT_EQ(off, sbuf.size());
|
||||
}
|
||||
|
||||
|
||||
TEST(unpack, int_pointer_off_no_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
@ -86,17 +164,49 @@ TEST(unpack, int_pointer)
|
||||
EXPECT_EQ(off, sbuf.size());
|
||||
}
|
||||
|
||||
TEST(unpack, int_null_pointer)
|
||||
TEST(unpack, int_pointer_off_no_ref_explicit)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
msgpack::unpacked msg;
|
||||
|
||||
std::size_t off = 0;
|
||||
|
||||
// obsolete
|
||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), nullptr);
|
||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &off, nullptr);
|
||||
EXPECT_EQ(1, msg.get().as<int>());
|
||||
EXPECT_EQ(off, sbuf.size());
|
||||
}
|
||||
|
||||
TEST(unpack, int_pointer_no_off_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
msgpack::unpacked msg;
|
||||
bool referenced;
|
||||
|
||||
// obsolete
|
||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), nullptr, &referenced);
|
||||
EXPECT_EQ(1, msg.get().as<int>());
|
||||
EXPECT_EQ(false, referenced);
|
||||
}
|
||||
|
||||
TEST(unpack, int_pointer_off_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
msgpack::unpacked msg;
|
||||
bool referenced;
|
||||
std::size_t off = 0;
|
||||
|
||||
// obsolete
|
||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &off, &referenced);
|
||||
EXPECT_EQ(1, msg.get().as<int>());
|
||||
EXPECT_EQ(off, sbuf.size());
|
||||
EXPECT_EQ(false, referenced);
|
||||
}
|
||||
|
||||
|
||||
TEST(unpack, int_default_null_pointer)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
|
232
test/reference_cpp11.cpp
Normal file
232
test/reference_cpp11.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
#include <msgpack.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#if !defined(MSGPACK_USE_CPP03)
|
||||
|
||||
TEST(reference, unpack_int)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
bool referenced;
|
||||
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced);
|
||||
EXPECT_FALSE(referenced);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_string)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, std::string("abcdefg"));
|
||||
bool referenced;
|
||||
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced);
|
||||
EXPECT_FALSE(referenced);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_bin)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::packer<msgpack::sbuffer> packer(sbuf);
|
||||
char c[] = { 1, 2, 3, 4, 5, 6 };
|
||||
packer.pack_bin(sizeof(c));
|
||||
packer.pack_bin_body(c, sizeof(c));
|
||||
|
||||
bool referenced;
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced);
|
||||
EXPECT_FALSE(referenced);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_ext)
|
||||
{
|
||||
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));
|
||||
bool referenced;
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced);
|
||||
EXPECT_FALSE(referenced);
|
||||
}
|
||||
|
||||
bool never_called(msgpack::type::object_type, std::size_t, void*)
|
||||
{
|
||||
EXPECT_TRUE(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool always_reference(msgpack::type::object_type, std::size_t, void*)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST(reference, unpack_int_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
bool referenced;
|
||||
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, never_called);
|
||||
EXPECT_FALSE(referenced);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_string_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, std::string("abcdefg"));
|
||||
bool referenced;
|
||||
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, always_reference);
|
||||
EXPECT_TRUE(referenced);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_bin_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::packer<msgpack::sbuffer> packer(sbuf);
|
||||
char c[] = { 1, 2, 3, 4, 5, 6 };
|
||||
packer.pack_bin(sizeof(c));
|
||||
packer.pack_bin_body(c, sizeof(c));
|
||||
|
||||
bool referenced;
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, always_reference);
|
||||
EXPECT_TRUE(referenced);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_ext_ref)
|
||||
{
|
||||
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));
|
||||
bool referenced;
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, always_reference);
|
||||
EXPECT_TRUE(referenced);
|
||||
}
|
||||
|
||||
static void* s_p;
|
||||
|
||||
bool sized_reference(msgpack::type::object_type t, std::size_t s, void* p)
|
||||
{
|
||||
s_p = p;
|
||||
switch (t) {
|
||||
case msgpack::type::STR:
|
||||
if (s >= 5) return true;
|
||||
break;
|
||||
case msgpack::type::BIN:
|
||||
if (s >= 6) return true;
|
||||
break;
|
||||
case msgpack::type::EXT:
|
||||
if (s >= 7) return true;
|
||||
break;
|
||||
default:
|
||||
EXPECT_TRUE(false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TEST(reference, unpack_int_sized_ref)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, 1);
|
||||
|
||||
bool referenced;
|
||||
s_p = nullptr;
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, never_called, &sbuf);
|
||||
EXPECT_FALSE(referenced);
|
||||
EXPECT_EQ(nullptr, s_p);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_string_sized_ref_4)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, std::string("1234"));
|
||||
|
||||
bool referenced;
|
||||
s_p = nullptr;
|
||||
// the last argument sbuf is any pointer as a user data.
|
||||
// That is stored to s_p in sized_reference
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, sized_reference, &sbuf);
|
||||
EXPECT_FALSE(referenced);
|
||||
// compare the passed argument with stored s_p.
|
||||
EXPECT_EQ(&sbuf, s_p);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_string_sized_ref_5)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::pack(sbuf, std::string("12345"));
|
||||
|
||||
bool referenced;
|
||||
s_p = nullptr;
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, sized_reference, &sbuf);
|
||||
EXPECT_TRUE(referenced);
|
||||
EXPECT_EQ(&sbuf, s_p);
|
||||
}
|
||||
|
||||
|
||||
TEST(reference, unpack_bin_sized_ref_5)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::packer<msgpack::sbuffer> packer(sbuf);
|
||||
char c[] = { 1, 2, 3, 4, 5 };
|
||||
packer.pack_bin(sizeof(c));
|
||||
packer.pack_bin_body(c, sizeof(c));
|
||||
|
||||
bool referenced;
|
||||
s_p = nullptr;
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, sized_reference, &sbuf);
|
||||
EXPECT_FALSE(referenced);
|
||||
EXPECT_EQ(&sbuf, s_p);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_bin_sized_ref_6)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::packer<msgpack::sbuffer> packer(sbuf);
|
||||
char c[] = { 1, 2, 3, 4, 5, 6 };
|
||||
packer.pack_bin(sizeof(c));
|
||||
packer.pack_bin_body(c, sizeof(c));
|
||||
|
||||
bool referenced;
|
||||
s_p = nullptr;
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, sized_reference, &sbuf);
|
||||
EXPECT_TRUE(referenced);
|
||||
EXPECT_EQ(&sbuf, s_p);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_ext_sized_ref_6)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::packer<msgpack::sbuffer> packer(sbuf);
|
||||
char const buf [] = { 1, 2, 3, 4, 5 };
|
||||
|
||||
packer.pack_ext(sizeof(buf), 1); // 5 + 1(type) = 6
|
||||
packer.pack_ext_body(buf, sizeof(buf));
|
||||
|
||||
bool referenced;
|
||||
s_p = nullptr;
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, sized_reference, &sbuf);
|
||||
EXPECT_FALSE(referenced);
|
||||
EXPECT_EQ(&sbuf, s_p);
|
||||
}
|
||||
|
||||
TEST(reference, unpack_ext_sized_ref_7)
|
||||
{
|
||||
msgpack::sbuffer sbuf;
|
||||
msgpack::packer<msgpack::sbuffer> packer(sbuf);
|
||||
char const buf [] = { 1, 2, 3, 4, 5, 6 };
|
||||
|
||||
packer.pack_ext(sizeof(buf), 1); // 6 + 1(type) = 7
|
||||
packer.pack_ext_body(buf, sizeof(buf));
|
||||
|
||||
bool referenced;
|
||||
s_p = nullptr;
|
||||
msgpack::unpacked ret = msgpack::unpack(sbuf.data(), sbuf.size(), referenced, sized_reference, &sbuf);
|
||||
EXPECT_TRUE(referenced);
|
||||
EXPECT_EQ(&sbuf, s_p);
|
||||
}
|
||||
|
||||
#endif // !defined(MSGPACK_USE_CPP03)
|
Loading…
x
Reference in New Issue
Block a user