mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-04-19 15:47:15 +02:00

- Enhance CMakeLists.txt files. - Move to Boost Test from Google Test to support pre-C++11 compilers. - Add more configurations on CI matrix builds. - Other minor fixes
489 lines
14 KiB
C++
489 lines
14 KiB
C++
#include <msgpack.hpp>
|
|
|
|
#define BOOST_TEST_MODULE visitor
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
#include <sstream>
|
|
|
|
BOOST_AUTO_TEST_CASE(dummy)
|
|
{
|
|
}
|
|
|
|
#if MSGPACK_DEFAULT_API_VERSION >= 2
|
|
|
|
struct json_like_visitor : msgpack::null_visitor {
|
|
json_like_visitor(std::string& s):m_s(s) {}
|
|
|
|
bool visit_nil() {
|
|
m_s += "null";
|
|
return true;
|
|
}
|
|
bool visit_boolean(bool v) {
|
|
if (v) m_s += "true";
|
|
else m_s += "false";
|
|
return true;
|
|
}
|
|
bool visit_positive_integer(uint64_t v) {
|
|
std::stringstream ss;
|
|
ss << v;
|
|
m_s += ss.str();
|
|
return true;
|
|
}
|
|
bool visit_negative_integer(int64_t v) {
|
|
std::stringstream ss;
|
|
ss << v;
|
|
m_s += ss.str();
|
|
return true;
|
|
}
|
|
bool visit_str(const char* v, uint32_t size) {
|
|
// I omit escape process.
|
|
m_s += '"' + std::string(v, size) + '"';
|
|
return true;
|
|
}
|
|
bool start_array(uint32_t /*num_elements*/) {
|
|
m_s += "[";
|
|
return true;
|
|
}
|
|
bool end_array_item() {
|
|
m_s += ",";
|
|
return true;
|
|
}
|
|
bool end_array() {
|
|
m_s.erase(m_s.size() - 1, 1); // remove the last ','
|
|
m_s += "]";
|
|
return true;
|
|
}
|
|
bool start_map(uint32_t /*num_kv_pairs*/) {
|
|
m_s += "{";
|
|
return true;
|
|
}
|
|
bool end_map_key() {
|
|
m_s += ":";
|
|
return true;
|
|
}
|
|
bool end_map_value() {
|
|
m_s += ",";
|
|
return true;
|
|
}
|
|
bool end_map() {
|
|
m_s.erase(m_s.size() - 1, 1); // remove the last ','
|
|
m_s += "}";
|
|
return true;
|
|
}
|
|
void parse_error(size_t /*parsed_offset*/, size_t /*error_offset*/) {
|
|
BOOST_CHECK(false);
|
|
}
|
|
void insufficient_bytes(size_t /*parsed_offset*/, size_t /*error_offset*/) {
|
|
BOOST_CHECK(false);
|
|
}
|
|
std::string& m_s;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(json_like)
|
|
{
|
|
std::stringstream ss;
|
|
msgpack::packer<std::stringstream> p(ss);
|
|
p.pack_map(1);
|
|
p.pack("key");
|
|
p.pack_array(3);
|
|
p.pack(42);
|
|
p.pack_nil();
|
|
p.pack(true);
|
|
|
|
std::string json_like;
|
|
json_like_visitor v(json_like);
|
|
std::size_t off = 0;
|
|
std::string const& str = ss.str();
|
|
bool ret = msgpack::parse(str.data(), str.size(), off, v);
|
|
BOOST_CHECK(ret);
|
|
BOOST_CHECK_EQUAL("{\"key\":[42,null,true]}", json_like);
|
|
}
|
|
|
|
struct parse_error_check_visitor : msgpack::null_visitor {
|
|
parse_error_check_visitor(bool& called):m_called(called) {}
|
|
void parse_error(size_t parsed_offset, size_t error_offset) {
|
|
BOOST_CHECK_EQUAL(static_cast<size_t>(1), parsed_offset);
|
|
BOOST_CHECK_EQUAL(static_cast<size_t>(2), error_offset);
|
|
m_called = true;
|
|
}
|
|
bool& m_called;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(parse_error)
|
|
{
|
|
bool called = false;
|
|
parse_error_check_visitor v(called);
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x93u), 0x01u, static_cast<char>(0xc1u), 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK(called);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(2u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct insuf_bytes_check_visitor : msgpack::null_visitor {
|
|
insuf_bytes_check_visitor(bool& called):m_called(called) {}
|
|
void insufficient_bytes(size_t parsed_offset, size_t error_offset) {
|
|
BOOST_CHECK_EQUAL(static_cast<size_t>(2), parsed_offset);
|
|
BOOST_CHECK_EQUAL(static_cast<size_t>(3), error_offset);
|
|
m_called = true;
|
|
}
|
|
bool& m_called;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(insuf_bytes)
|
|
{
|
|
bool called = false;
|
|
insuf_bytes_check_visitor v(called);
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x93u), 0x01u, 0x01u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK(called);
|
|
// Even if MSGPACK_DEFAULT_API_VERSION is 2, then off is updated
|
|
// in the case of insufficient bytes.
|
|
BOOST_CHECK_EQUAL(3u, off);
|
|
}
|
|
|
|
struct return_false_array_val_visitor : msgpack::null_visitor {
|
|
return_false_array_val_visitor(std::size_t& times):m_times(times) {}
|
|
bool visit_positive_integer(uint64_t) {
|
|
if (++m_times == 2) return false;
|
|
return true;
|
|
}
|
|
std::size_t& m_times;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_array_val)
|
|
{
|
|
std::size_t times = 0;
|
|
return_false_array_val_visitor v(times);
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x93u), 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(2u, times);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(2u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct return_false_start_array_item_visitor : msgpack::null_visitor {
|
|
return_false_start_array_item_visitor(std::size_t& times):m_times(times) {}
|
|
bool start_array_item() {
|
|
if (++m_times == 2) return false;
|
|
return true;
|
|
}
|
|
std::size_t& m_times;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_start_array_item)
|
|
{
|
|
std::size_t times = 0;
|
|
return_false_start_array_item_visitor v(times);
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x93u), 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(2u, times);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(2u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct return_false_end_array_item_visitor : msgpack::null_visitor {
|
|
return_false_end_array_item_visitor(std::size_t& times):m_times(times) {}
|
|
bool end_array_item() {
|
|
if (++m_times == 2) return false;
|
|
return true;
|
|
}
|
|
std::size_t& m_times;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_end_array_item)
|
|
{
|
|
std::size_t times = 0;
|
|
return_false_end_array_item_visitor v(times);
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x93u), 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(2u, times);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(2u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct return_false_start_array_visitor : msgpack::null_visitor {
|
|
bool start_array(uint32_t) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_start_array)
|
|
{
|
|
return_false_start_array_visitor v;
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x93u), 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
}
|
|
|
|
struct return_false_start_array0_visitor : msgpack::null_visitor {
|
|
bool start_array(uint32_t) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_start_array0)
|
|
{
|
|
return_false_start_array0_visitor v;
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x90u) };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
}
|
|
|
|
struct return_false_end_array_visitor : msgpack::null_visitor {
|
|
bool end_array() {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_end_array)
|
|
{
|
|
return_false_end_array_visitor v;
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x93u), 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(3u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct return_false_end_array0_visitor : msgpack::null_visitor {
|
|
bool end_array() {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_end_array0)
|
|
{
|
|
return_false_end_array0_visitor v;
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x90u) };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
}
|
|
|
|
struct return_false_map_val_visitor : msgpack::null_visitor {
|
|
return_false_map_val_visitor(std::size_t& times):m_times(times) {}
|
|
bool visit_positive_integer(uint64_t) {
|
|
if (++m_times == 2) return false;
|
|
return true;
|
|
}
|
|
std::size_t& m_times;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_map_val)
|
|
{
|
|
std::size_t times = 0;
|
|
return_false_map_val_visitor v(times);
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x83u), 0x01u, 0x02u, 0x03u, 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(2u, times);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(2u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct return_false_start_map_key_visitor : msgpack::null_visitor {
|
|
return_false_start_map_key_visitor(std::size_t& times):m_times(times) {}
|
|
bool start_map_key() {
|
|
if (++m_times == 2) return false;
|
|
return true;
|
|
}
|
|
std::size_t& m_times;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_start_map_key)
|
|
{
|
|
std::size_t times = 0;
|
|
return_false_start_map_key_visitor v(times);
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x83u), 0x01u, 0x02u, 0x03u, 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(2u, times);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(3u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct return_false_end_map_key_visitor : msgpack::null_visitor {
|
|
return_false_end_map_key_visitor(std::size_t& times):m_times(times) {}
|
|
bool end_map_key() {
|
|
if (++m_times == 2) return false;
|
|
return true;
|
|
}
|
|
std::size_t& m_times;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_end_map_key)
|
|
{
|
|
std::size_t times = 0;
|
|
return_false_end_map_key_visitor v(times);
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x83u), 0x01u, 0x02u, 0x03u, 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(2u, times);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(3u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct return_false_start_map_value_visitor : msgpack::null_visitor {
|
|
return_false_start_map_value_visitor(std::size_t& times):m_times(times) {}
|
|
bool start_map_value() {
|
|
if (++m_times == 2) return false;
|
|
return true;
|
|
}
|
|
std::size_t& m_times;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_start_map_value)
|
|
{
|
|
std::size_t times = 0;
|
|
return_false_start_map_value_visitor v(times);
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x83u), 0x01u, 0x02u, 0x03u, 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(2u, times);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(4u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct return_false_end_map_value_visitor : msgpack::null_visitor {
|
|
return_false_end_map_value_visitor(std::size_t& times):m_times(times) {}
|
|
bool end_map_value() {
|
|
if (++m_times == 2) return false;
|
|
return true;
|
|
}
|
|
std::size_t& m_times;
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_end_map_value)
|
|
{
|
|
std::size_t times = 0;
|
|
return_false_end_map_value_visitor v(times);
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x83u), 0x01u, 0x02u, 0x03u, 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(2u, times);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(4u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct return_false_start_map_visitor : msgpack::null_visitor {
|
|
bool start_map(uint32_t) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_start_map)
|
|
{
|
|
return_false_start_map_visitor v;
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x83u), 0x01u, 0x02u, 0x03u, 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
}
|
|
|
|
struct return_false_start_map0_visitor : msgpack::null_visitor {
|
|
bool start_map(uint32_t) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_start_map0)
|
|
{
|
|
return_false_start_map0_visitor v;
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x80u) };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
}
|
|
|
|
struct return_false_end_map_visitor : msgpack::null_visitor {
|
|
bool end_map() {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_end_map)
|
|
{
|
|
return_false_end_map_visitor v;
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x83u), 0x01u, 0x02u, 0x03u, 0x01u, 0x02u, 0x03u };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
#if MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
#else // MSGPACK_DEFAULT_API_VERSION < 3
|
|
BOOST_CHECK_EQUAL(6u, off);
|
|
#endif // MSGPACK_DEFAULT_API_VERSION < 3
|
|
}
|
|
|
|
struct return_false_end_map0_visitor : msgpack::null_visitor {
|
|
bool end_map() {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(return_false_end_map0)
|
|
{
|
|
return_false_end_map0_visitor v;
|
|
std::size_t off = 0;
|
|
char const data[] = { static_cast<char>(0x80u) };
|
|
bool ret = msgpack::parse(data, sizeof(data), off, v);
|
|
BOOST_CHECK(!ret);
|
|
BOOST_CHECK_EQUAL(0u, off);
|
|
}
|
|
|
|
#endif // MSGPACK_DEFAULT_API_VERSION >= 1
|