Fixed end_map_value() calling point.

Renamed names that related to a visitor.
Renamed test name from json to json_like because I omit escape.
Added end_map_value() and end_map() implementation.
This commit is contained in:
Takatoshi Kondo
2016-05-05 10:53:14 +09:00
parent d5b515899c
commit 6593cba284
5 changed files with 113 additions and 105 deletions

View File

@@ -283,7 +283,7 @@ public:
bool m_referenced; bool m_referenced;
}; };
template <typename UnpackVisitorHolder> template <typename VisitorHolder>
class context { class context {
public: public:
context() context()
@@ -308,8 +308,8 @@ private:
return static_cast<uint32_t>(*p) & 0x1f; return static_cast<uint32_t>(*p) & 0x1f;
} }
UnpackVisitorHolder& holder() { VisitorHolder& holder() {
return static_cast<UnpackVisitorHolder&>(*this); return static_cast<VisitorHolder&>(*this);
} }
template <typename T, typename StartVisitor, typename EndVisitor> template <typename T, typename StartVisitor, typename EndVisitor>
@@ -364,38 +364,38 @@ private:
} }
struct array_sv { struct array_sv {
array_sv(UnpackVisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {} array_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
bool operator()(uint32_t size) const { bool operator()(uint32_t size) const {
return m_visitor_holder.visitor().start_array(size); return m_visitor_holder.visitor().start_array(size);
} }
msgpack_container_type type() const { return MSGPACK_CT_ARRAY_ITEM; } msgpack_container_type type() const { return MSGPACK_CT_ARRAY_ITEM; }
private: private:
UnpackVisitorHolder& m_visitor_holder; VisitorHolder& m_visitor_holder;
}; };
struct array_ev { struct array_ev {
array_ev(UnpackVisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {} array_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
bool operator()() const { bool operator()() const {
return m_visitor_holder.visitor().end_array(); return m_visitor_holder.visitor().end_array();
} }
private: private:
UnpackVisitorHolder& m_visitor_holder; VisitorHolder& m_visitor_holder;
}; };
struct map_sv { struct map_sv {
map_sv(UnpackVisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {} map_sv(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
bool operator()(uint32_t size) const { bool operator()(uint32_t size) const {
return m_visitor_holder.visitor().start_map(size); return m_visitor_holder.visitor().start_map(size);
} }
msgpack_container_type type() const { return MSGPACK_CT_MAP_KEY; } msgpack_container_type type() const { return MSGPACK_CT_MAP_KEY; }
private: private:
UnpackVisitorHolder& m_visitor_holder; VisitorHolder& m_visitor_holder;
}; };
struct map_ev { struct map_ev {
map_ev(UnpackVisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {} map_ev(VisitorHolder& visitor_holder):m_visitor_holder(visitor_holder) {}
bool operator()() const { bool operator()() const {
return m_visitor_holder.visitor().end_map(); return m_visitor_holder.visitor().end_map();
} }
private: private:
UnpackVisitorHolder& m_visitor_holder; VisitorHolder& m_visitor_holder;
}; };
struct unpack_stack { struct unpack_stack {
@@ -410,7 +410,7 @@ private:
void push(msgpack_container_type type, uint32_t rest) { void push(msgpack_container_type type, uint32_t rest) {
m_stack.push_back(stack_elem(type, rest)); m_stack.push_back(stack_elem(type, rest));
} }
unpack_return consume(UnpackVisitorHolder& visitor_holder) { unpack_return consume(VisitorHolder& visitor_holder) {
while (!m_stack.empty()) { while (!m_stack.empty()) {
stack_elem& e = m_stack.back(); stack_elem& e = m_stack.back();
switch (e.m_type) { switch (e.m_type) {
@@ -431,13 +431,13 @@ private:
e.m_type = MSGPACK_CT_MAP_VALUE; e.m_type = MSGPACK_CT_MAP_VALUE;
return UNPACK_CONTINUE; return UNPACK_CONTINUE;
case MSGPACK_CT_MAP_VALUE: case MSGPACK_CT_MAP_VALUE:
if (!visitor_holder.visitor().end_map_value()) return UNPACK_STOP_VISITOR;
if (--e.m_rest == 0) { if (--e.m_rest == 0) {
m_stack.pop_back(); m_stack.pop_back();
if (!visitor_holder.visitor().end_map()) return UNPACK_STOP_VISITOR; if (!visitor_holder.visitor().end_map()) return UNPACK_STOP_VISITOR;
} }
else { else {
e.m_type = MSGPACK_CT_MAP_KEY; e.m_type = MSGPACK_CT_MAP_KEY;
if (!visitor_holder.visitor().end_map_value()) return UNPACK_STOP_VISITOR;
if (!visitor_holder.visitor().start_map_key()) return UNPACK_STOP_VISITOR; if (!visitor_holder.visitor().start_map_key()) return UNPACK_STOP_VISITOR;
return UNPACK_CONTINUE; return UNPACK_CONTINUE;
} }
@@ -470,8 +470,8 @@ inline void check_ext_size<4>(std::size_t size) {
if (size == 0xffffffff) throw msgpack::ext_size_overflow("ext size overflow"); if (size == 0xffffffff) throw msgpack::ext_size_overflow("ext size overflow");
} }
template <typename UnpackVisitorHolder> template <typename VisitorHolder>
inline unpack_return context<UnpackVisitorHolder>::execute(const char* data, std::size_t len, std::size_t& off) inline unpack_return context<VisitorHolder>::execute(const char* data, std::size_t len, std::size_t& off)
{ {
assert(len >= off); assert(len >= off);
@@ -869,10 +869,10 @@ inline unpack_return context<UnpackVisitorHolder>::execute(const char* data, std
/// Unpacking class for a stream deserialization. /// Unpacking class for a stream deserialization.
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
class basic_unpacker : public detail::context<UnpackVisitorHolder> { class parser : public detail::context<VisitorHolder> {
typedef basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook> this_type; typedef parser<VisitorHolder, ReferencedBufferHook> this_type;
typedef detail::context<UnpackVisitorHolder> context_type; typedef detail::context<VisitorHolder> context_type;
public: public:
/// Constructor /// Constructor
/** /**
@@ -883,15 +883,15 @@ public:
* @param limit The size limit information of msgpack::object. * @param limit The size limit information of msgpack::object.
* *
*/ */
basic_unpacker(ReferencedBufferHook& hook, parser(ReferencedBufferHook& hook,
std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE); std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
#if !defined(MSGPACK_USE_CPP03) #if !defined(MSGPACK_USE_CPP03)
basic_unpacker(this_type&& other); parser(this_type&& other);
this_type& operator=(this_type&& other); this_type& operator=(this_type&& other);
#endif // !defined(MSGPACK_USE_CPP03) #endif // !defined(MSGPACK_USE_CPP03)
~basic_unpacker(); ~parser();
public: public:
/// Reserve a buffer memory. /// Reserve a buffer memory.
@@ -1018,17 +1018,17 @@ private:
#if defined(MSGPACK_USE_CPP03) #if defined(MSGPACK_USE_CPP03)
private: private:
basic_unpacker(const this_type&); parser(const this_type&);
this_type& operator=(const this_type&); this_type& operator=(const this_type&);
#else // defined(MSGPACK_USE_CPP03) #else // defined(MSGPACK_USE_CPP03)
public: public:
basic_unpacker(const this_type&) = delete; parser(const this_type&) = delete;
this_type& operator=(const this_type&) = delete; this_type& operator=(const this_type&) = delete;
#endif // defined(MSGPACK_USE_CPP03) #endif // defined(MSGPACK_USE_CPP03)
}; };
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::basic_unpacker( inline parser<VisitorHolder, ReferencedBufferHook>::parser(
ReferencedBufferHook& hook, ReferencedBufferHook& hook,
std::size_t initial_buffer_size) std::size_t initial_buffer_size)
:m_referenced_buffer_hook(hook) :m_referenced_buffer_hook(hook)
@@ -1055,8 +1055,8 @@ inline basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::basic_unpacker
#if !defined(MSGPACK_USE_CPP03) #if !defined(MSGPACK_USE_CPP03)
// Move constructor and move assignment operator // Move constructor and move assignment operator
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::basic_unpacker(this_type&& other) inline parser<VisitorHolder, ReferencedBufferHook>::parser(this_type&& other)
:context_type(std::move(other)), :context_type(std::move(other)),
m_buffer(other.m_buffer), m_buffer(other.m_buffer),
m_used(other.m_used), m_used(other.m_used),
@@ -1072,9 +1072,9 @@ inline basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::basic_unpacker
other.m_parsed = 0; other.m_parsed = 0;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>& basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::operator=(this_type&& other) { inline parser<VisitorHolder, ReferencedBufferHook>& parser<VisitorHolder, ReferencedBufferHook>::operator=(this_type&& other) {
this->~basic_unpacker(); this->~parser();
new (this) this_type(std::move(other)); new (this) this_type(std::move(other));
return *this; return *this;
} }
@@ -1082,26 +1082,26 @@ inline basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>& basic_unpacker
#endif // !defined(MSGPACK_USE_CPP03) #endif // !defined(MSGPACK_USE_CPP03)
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::~basic_unpacker() inline parser<VisitorHolder, ReferencedBufferHook>::~parser()
{ {
// These checks are required for move operations. // These checks are required for move operations.
if (m_buffer) detail::decr_count(m_buffer); if (m_buffer) detail::decr_count(m_buffer);
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline void basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::reserve_buffer(std::size_t size) inline void parser<VisitorHolder, ReferencedBufferHook>::reserve_buffer(std::size_t size)
{ {
if(m_free >= size) return; if(m_free >= size) return;
expand_buffer(size); expand_buffer(size);
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline void basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::expand_buffer(std::size_t size) inline void parser<VisitorHolder, ReferencedBufferHook>::expand_buffer(std::size_t size)
{ {
if(m_used == m_off && detail::get_count(m_buffer) == 1 if(m_used == m_off && detail::get_count(m_buffer) == 1
&& static_cast<UnpackVisitorHolder&>(*this).visitor().referenced()) { && static_cast<VisitorHolder&>(*this).visitor().referenced()) {
// rewind buffer // rewind buffer
m_free += m_used - COUNTER_SIZE; m_free += m_used - COUNTER_SIZE;
m_used = COUNTER_SIZE; m_used = COUNTER_SIZE;
@@ -1150,7 +1150,7 @@ inline void basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::expand_bu
std::memcpy(tmp+COUNTER_SIZE, m_buffer + m_off, not_parsed); std::memcpy(tmp+COUNTER_SIZE, m_buffer + m_off, not_parsed);
if(static_cast<UnpackVisitorHolder&>(*this).referenced()) { if(static_cast<VisitorHolder&>(*this).referenced()) {
try { try {
m_referenced_buffer_hook(m_buffer); m_referenced_buffer_hook(m_buffer);
} }
@@ -1158,7 +1158,7 @@ inline void basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::expand_bu
::free(tmp); ::free(tmp);
throw; throw;
} }
static_cast<UnpackVisitorHolder&>(*this).set_referenced(false); static_cast<VisitorHolder&>(*this).set_referenced(false);
} else { } else {
detail::decr_count(m_buffer); detail::decr_count(m_buffer);
} }
@@ -1170,34 +1170,34 @@ inline void basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::expand_bu
} }
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline char* basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::buffer() inline char* parser<VisitorHolder, ReferencedBufferHook>::buffer()
{ {
return m_buffer + m_used; return m_buffer + m_used;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline std::size_t basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::buffer_capacity() const inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::buffer_capacity() const
{ {
return m_free; return m_free;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline void basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::buffer_consumed(std::size_t size) inline void parser<VisitorHolder, ReferencedBufferHook>::buffer_consumed(std::size_t size)
{ {
m_used += size; m_used += size;
m_free -= size; m_free -= size;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline bool basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::next() inline bool parser<VisitorHolder, ReferencedBufferHook>::next()
{ {
unpack_return ret = execute_imp(); unpack_return ret = execute_imp();
return ret == UNPACK_SUCCESS; return ret == UNPACK_SUCCESS;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline unpack_return basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::execute_imp() inline unpack_return parser<VisitorHolder, ReferencedBufferHook>::execute_imp()
{ {
std::size_t off = m_off; std::size_t off = m_off;
unpack_return ret = context_type::execute(m_buffer, m_used, m_off); unpack_return ret = context_type::execute(m_buffer, m_used, m_off);
@@ -1207,46 +1207,46 @@ inline unpack_return basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::
return ret; return ret;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline void basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::reset() inline void parser<VisitorHolder, ReferencedBufferHook>::reset()
{ {
context_type::init(); context_type::init();
// don't reset referenced flag // don't reset referenced flag
m_parsed = 0; m_parsed = 0;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline std::size_t basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::message_size() const inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::message_size() const
{ {
return m_parsed - m_off + m_used; return m_parsed - m_off + m_used;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline std::size_t basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::parsed_size() const inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::parsed_size() const
{ {
return m_parsed; return m_parsed;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline char* basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::nonparsed_buffer() inline char* parser<VisitorHolder, ReferencedBufferHook>::nonparsed_buffer()
{ {
return m_buffer + m_off; return m_buffer + m_off;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline std::size_t basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::nonparsed_size() const inline std::size_t parser<VisitorHolder, ReferencedBufferHook>::nonparsed_size() const
{ {
return m_used - m_off; return m_used - m_off;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline void basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::skip_nonparsed_buffer(std::size_t size) inline void parser<VisitorHolder, ReferencedBufferHook>::skip_nonparsed_buffer(std::size_t size)
{ {
m_off += size; m_off += size;
} }
template <typename UnpackVisitorHolder, typename ReferencedBufferHook> template <typename VisitorHolder, typename ReferencedBufferHook>
inline void basic_unpacker<UnpackVisitorHolder, ReferencedBufferHook>::remove_nonparsed_buffer() inline void parser<VisitorHolder, ReferencedBufferHook>::remove_nonparsed_buffer()
{ {
m_used = m_off; m_used = m_off;
} }
@@ -1260,15 +1260,15 @@ struct zone_push_finalizer {
msgpack::zone* m_z; msgpack::zone* m_z;
}; };
class unpacker : public basic_unpacker<unpacker, zone_push_finalizer>, class unpacker : public parser<unpacker, zone_push_finalizer>,
public detail::create_object_visitor { public detail::create_object_visitor {
typedef basic_unpacker<unpacker, zone_push_finalizer> basic; typedef parser<unpacker, zone_push_finalizer> parser;
public: public:
unpacker(unpack_reference_func f = &unpacker::default_reference_func, unpacker(unpack_reference_func f = &unpacker::default_reference_func,
void* user_data = nullptr, void* user_data = nullptr,
std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE, std::size_t initial_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE,
unpack_limit const& limit = unpack_limit()) unpack_limit const& limit = unpack_limit())
:basic(m_finalizer, initial_buffer_size), :parser(m_finalizer, initial_buffer_size),
detail::create_object_visitor(f, user_data, limit), detail::create_object_visitor(f, user_data, limit),
m_z(new msgpack::zone), m_z(new msgpack::zone),
m_finalizer(*m_z) { m_finalizer(*m_z) {
@@ -1318,7 +1318,7 @@ private:
}; };
inline bool unpacker::next(msgpack::object_handle& result, bool& referenced) { inline bool unpacker::next(msgpack::object_handle& result, bool& referenced) {
bool ret = basic::next(); bool ret = parser::next();
if (ret) { if (ret) {
referenced = detail::create_object_visitor::referenced(); referenced = detail::create_object_visitor::referenced();
result.zone().reset( release_zone() ); result.zone().reset( release_zone() );
@@ -1544,33 +1544,33 @@ inline msgpack::object unpack(
return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit); return msgpack::v2::unpack(z, data, len, off, referenced, f, user_data, limit);
} }
template <typename UnpackVisitor> template <typename Visitor>
inline bool unpack_visit(const char* data, size_t len, size_t& off, UnpackVisitor& v) { inline bool parse(const char* data, size_t len, size_t& off, Visitor& v) {
unpack_return ret = detail::unpack_visit_imp(data, len, off, v); unpack_return ret = detail::parse_imp(data, len, off, v);
return ret == UNPACK_SUCCESS || ret == UNPACK_EXTRA_BYTES; return ret == UNPACK_SUCCESS || ret == UNPACK_EXTRA_BYTES;
} }
template <typename UnpackVisitor> template <typename Visitor>
inline bool unpack_visit(const char* data, size_t len, UnpackVisitor& v) { inline bool parse(const char* data, size_t len, Visitor& v) {
std::size_t off = 0; std::size_t off = 0;
return unpack_visit(data, len, off, v); return parse(data, len, off, v);
} }
namespace detail { namespace detail {
template <typename UnpackVisitor> template <typename Visitor>
struct unpack_helper : context<unpack_helper<UnpackVisitor> > { struct parse_helper : context<parse_helper<Visitor> > {
unpack_helper(UnpackVisitor& v):m_visitor(v) {} parse_helper(Visitor& v):m_visitor(v) {}
unpack_return execute(const char* data, std::size_t len, std::size_t& off) { unpack_return execute(const char* data, std::size_t len, std::size_t& off) {
return context<unpack_helper<UnpackVisitor> >::execute(data, len, off); return context<parse_helper<Visitor> >::execute(data, len, off);
} }
UnpackVisitor& visitor() const { return m_visitor; } Visitor& visitor() const { return m_visitor; }
UnpackVisitor& m_visitor; Visitor& m_visitor;
}; };
template <typename UnpackVisitor> template <typename Visitor>
inline unpack_return inline unpack_return
unpack_visit_imp(const char* data, size_t len, size_t& off, UnpackVisitor& v) { parse_imp(const char* data, size_t len, size_t& off, Visitor& v) {
std::size_t noff = off; std::size_t noff = off;
if(len <= noff) { if(len <= noff) {
@@ -1578,7 +1578,7 @@ unpack_visit_imp(const char* data, size_t len, size_t& off, UnpackVisitor& v) {
v.insufficient_bytes(noff, noff); v.insufficient_bytes(noff, noff);
return UNPACK_CONTINUE; return UNPACK_CONTINUE;
} }
detail::unpack_helper<UnpackVisitor> h(v); detail::parse_helper<Visitor> h(v);
unpack_return ret = h.execute(data, len, noff); unpack_return ret = h.execute(data, len, noff);
switch (ret) { switch (ret) {
case UNPACK_CONTINUE: case UNPACK_CONTINUE:
@@ -1606,7 +1606,7 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
v.set_zone(result_zone); v.set_zone(result_zone);
referenced = false; referenced = false;
v.set_referenced(referenced); v.set_referenced(referenced);
unpack_return ret = unpack_visit_imp(data, len, off, v); unpack_return ret = parse_imp(data, len, off, v);
referenced = v.referenced(); referenced = v.referenced();
result = v.data(); result = v.data();
return ret; return ret;

View File

@@ -305,23 +305,25 @@ msgpack::object unpack(
* @param data The pointer to the buffer. * @param data The pointer to the buffer.
* @param len The length of the buffer. * @param len The length of the buffer.
* @param off The offset position of the buffer. It is read and overwritten. * @param off The offset position of the buffer. It is read and overwritten.
* @param v The visitor that satisfies visitor concept. https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_visitor#visitor-concept
* *
* @return if unpacking process finishs without error then return true, otherwise return false. * @return if unpacking process finishs without error then return true, otherwise return false.
* *
*/ */
template <typename UnpackVisitor> template <typename Visitor>
bool unpack_visit(const char* data, size_t len, size_t& off, UnpackVisitor&); bool parse(const char* data, size_t len, size_t& off, Visitor& v);
/// Unpack msgpack formatted data via a visitor /// Unpack msgpack formatted data via a visitor
/** /**
* @param data The pointer to the buffer. * @param data The pointer to the buffer.
* @param len The length of the buffer. * @param len The length of the buffer.
* @param v The visitor that satisfies visitor concept. https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_visitor#visitor-concept
* *
* @return if unpacking process finishs without error then return true, otherwise return false. * @return if unpacking process finishs without error then return true, otherwise return false.
* *
*/ */
template <typename UnpackVisitor> template <typename Visitor>
bool unpack_visit(const char* data, size_t len, UnpackVisitor& v); bool parse(const char* data, size_t len, Visitor& v);
namespace detail { namespace detail {
@@ -333,7 +335,7 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
template <typename UnpackVisitor> template <typename UnpackVisitor>
unpack_return unpack_return
unpack_visit_imp(const char* data, size_t len, size_t& off, UnpackVisitor& v); parse_imp(const char* data, size_t len, size_t& off, UnpackVisitor& v);
} // detail } // detail

View File

@@ -30,9 +30,9 @@ LIST (APPEND check_PROGRAMS
reference.cpp reference.cpp
streaming.cpp streaming.cpp
streaming_c.cpp streaming_c.cpp
unpack_visitor.cpp
user_class.cpp user_class.cpp
version.cpp version.cpp
visitor.cpp
zone.cpp zone.cpp
) )

View File

@@ -25,9 +25,9 @@ check_PROGRAMS = \
reference \ reference \
streaming \ streaming \
streaming_c \ streaming_c \
unpack_visitor \
user_class \ user_class \
version \ version \
visitor \
zone zone
check_PROGRAMS += \ check_PROGRAMS += \
@@ -71,9 +71,9 @@ raw_SOURCES = raw.cpp
reference_SOURCES = reference.cpp reference_SOURCES = reference.cpp
streaming_SOURCES = streaming.cpp streaming_SOURCES = streaming.cpp
streaming_c_SOURCES = streaming_c.cpp streaming_c_SOURCES = streaming_c.cpp
unpack_visitor_SOURCES = unpack_visitor.cpp
user_class_SOURCES = user_class.cpp user_class_SOURCES = user_class.cpp
version_SOURCES = version.cpp version_SOURCES = version.cpp
visitor_SOURCES = visitor.cpp
zone_SOURCES = zone.cpp zone_SOURCES = zone.cpp
iterator_cpp11_SOURCES = iterator_cpp11.cpp iterator_cpp11_SOURCES = iterator_cpp11.cpp

View File

@@ -3,14 +3,14 @@
#include <sstream> #include <sstream>
// To avoid link error // To avoid link error
TEST(unpack_visitor, dummy) TEST(visitor, dummy)
{ {
} }
#if MSGPACK_DEFAULT_API_VERSION >= 2 #if MSGPACK_DEFAULT_API_VERSION >= 2
struct json_visitor : msgpack::v2::null_visitor { struct json_like_visitor : msgpack::v2::null_visitor {
json_visitor(std::string& s):m_s(s) {} json_like_visitor(std::string& s):m_s(s) {}
bool visit_nil() { bool visit_nil() {
m_s += "null"; m_s += "null";
@@ -34,6 +34,7 @@ struct json_visitor : msgpack::v2::null_visitor {
return true; return true;
} }
bool visit_str(const char* v, uint32_t size) { bool visit_str(const char* v, uint32_t size) {
// I omit escape process.
m_s += '"' + std::string(v, size) + '"'; m_s += '"' + std::string(v, size) + '"';
return true; return true;
} }
@@ -58,7 +59,12 @@ struct json_visitor : msgpack::v2::null_visitor {
m_s += ":"; m_s += ":";
return true; return true;
} }
bool end_map_value() {
m_s += ",";
return true;
}
bool end_map() { bool end_map() {
m_s.erase(m_s.size() - 1, 1); // remove the last ','
m_s += "}"; m_s += "}";
return true; return true;
} }
@@ -71,7 +77,7 @@ struct json_visitor : msgpack::v2::null_visitor {
std::string& m_s; std::string& m_s;
}; };
TEST(unpack_visitor, json) TEST(visitor, json_like)
{ {
std::stringstream ss; std::stringstream ss;
msgpack::packer<std::stringstream> p(ss); msgpack::packer<std::stringstream> p(ss);
@@ -82,12 +88,12 @@ TEST(unpack_visitor, json)
p.pack_nil(); p.pack_nil();
p.pack(true); p.pack(true);
std::string json; std::string json_like;
json_visitor v(json); json_like_visitor v(json_like);
std::size_t off = 0; std::size_t off = 0;
bool ret = msgpack::v2::unpack_visit(ss.str().data(), ss.str().size(), off, v); bool ret = msgpack::v2::parse(ss.str().data(), ss.str().size(), off, v);
EXPECT_TRUE(ret); EXPECT_TRUE(ret);
EXPECT_EQ("{\"key\":[42,null,true]}", json); EXPECT_EQ("{\"key\":[42,null,true]}", json_like);
} }
struct parse_error_check_visitor : msgpack::v2::null_visitor { struct parse_error_check_visitor : msgpack::v2::null_visitor {
@@ -100,13 +106,13 @@ struct parse_error_check_visitor : msgpack::v2::null_visitor {
bool& m_called; bool& m_called;
}; };
TEST(unpack_visitor, parse_error) TEST(visitor, parse_error)
{ {
bool called = false; bool called = false;
parse_error_check_visitor v(called); parse_error_check_visitor v(called);
std::size_t off = 0; std::size_t off = 0;
char const data[] = { static_cast<char>(0x93u), 0x01u, static_cast<char>(0xc1u), 0x03u }; char const data[] = { static_cast<char>(0x93u), 0x01u, static_cast<char>(0xc1u), 0x03u };
bool ret = msgpack::v2::unpack_visit(data, sizeof(data), off, v); bool ret = msgpack::v2::parse(data, sizeof(data), off, v);
EXPECT_FALSE(ret); EXPECT_FALSE(ret);
EXPECT_TRUE(called); EXPECT_TRUE(called);
} }
@@ -121,13 +127,13 @@ struct insuf_bytes_check_visitor : msgpack::v2::null_visitor {
bool& m_called; bool& m_called;
}; };
TEST(unpack_visitor, insuf_bytes) TEST(visitor, insuf_bytes)
{ {
bool called = false; bool called = false;
insuf_bytes_check_visitor v(called); insuf_bytes_check_visitor v(called);
std::size_t off = 0; std::size_t off = 0;
char const data[] = { static_cast<char>(0x93u), 0x01u, 0x01u }; char const data[] = { static_cast<char>(0x93u), 0x01u, 0x01u };
bool ret = msgpack::v2::unpack_visit(data, sizeof(data), off, v); bool ret = msgpack::v2::parse(data, sizeof(data), off, v);
EXPECT_FALSE(ret); EXPECT_FALSE(ret);
EXPECT_TRUE(called); EXPECT_TRUE(called);
} }