Added Spirit.X3 based parse.

It uses iterator pair instead of data and size.
This commit is contained in:
Takatoshi Kondo 2017-01-04 17:58:27 +09:00
parent 9b141fa9b6
commit 84ad9a2634
17 changed files with 2124 additions and 212 deletions

View File

@ -3,18 +3,28 @@ cache:
- apt
before_install:
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:h-rayflood/llvm-upper; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y 'deb http://apt.llvm.org/precise/ llvm-toolchain-precise-3.8 main'; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update; fi
install:
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-4.8-multilib g++-4.8-multilib; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install --allow-unauthenticated -qq clang-3.6; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 90; fi
- if [ "$CXX" == "clang++" ]; then export CXXFLAGS="-stdlib=libc++"; fi
- if [ "$CXX" == "clang++" ]; then svn co --quiet http://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_380/final libcxx; fi
- if [ "$CXX" == "clang++" ]; then cd libcxx/lib && bash buildit; fi
- if [ "$CXX" == "clang++" ]; then sudo cp ./libc++.so.1.0 /usr/lib/; fi
- if [ "$CXX" == "clang++" ]; then sudo mkdir /usr/include/c++/v1; fi
- if [ "$CXX" == "clang++" ]; then cd .. && sudo cp -r include/* /usr/include/c++/v1/; fi
- if [ "$CXX" == "clang++" ]; then cd /usr/lib && sudo ln -sf libc++.so.1.0 libc++.so; fi
- if [ "$CXX" == "clang++" ]; then sudo ln -sf libc++.so.1.0 libc++.so.1 && cd $cwd; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-5-multilib g++-5-multilib; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install --allow-unauthenticated -qq clang-3.8; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 90; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 90; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -y lib32gcc1; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -y libc6-i386; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -y lib32z1-dev; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -y lib32stdc++6; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -y lib32stdc++6-6-dbg; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -y bzip2; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -y libc6-dbg; fi
- wget https://github.com/google/googletest/archive/release-1.7.0.zip -O googletest-release-1.7.0.zip
@ -36,7 +46,7 @@ matrix:
env: ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="64" LIBPATH="/usr/local/lib" BOOST="boost" BOOST_INC="/usr/local/boost" CHAR_SIGN="unsigned" API_VERSION="1"
- os: osx
compiler: clang
env: ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" BOOST="boost" BOOST_INC="/usr/local/boost" CHAR_SIGN="signed" API_VERSION="2"
env: ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" BOOST="boost" BOOST_INC="/usr/local/boost" CHAR_SIGN="signed" API_VERSION="2" X3_PARSE="ON"
- os: osx
compiler: clang
env: ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" BOOST="" BOOST_INC="" CHAR_SIGN="signed" API_VERSION="2"
@ -51,7 +61,7 @@ matrix:
env: ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="" BOOST_INC="" CHAR_SIGN="signed" API_VERSION="2"
- os: linux
compiler: clang
env: ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" BOOST="boost" BOOST_INC="/usr/local/boost" CHAR_SIGN="signed" API_VERSION="2"
env: ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" BOOST="boost" BOOST_INC="/usr/local/boost" CHAR_SIGN="signed" API_VERSION="2" X3_PARSE="ON"
- os: linux
compiler: clang
env: ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="" BOOST_INC="" SHARED="OFF" CHAR_SIGN="unsigned" API_VERSION="2"
@ -60,7 +70,7 @@ matrix:
env: ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib" BOOST="" BOOST_INC="" CHAR_SIGN="signed" API_VERSION="2"
- os: linux
compiler: gcc
env: ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="boost" BOOST_INC="/usr/local/boost" CHAR_SIGN="unsigned" API_VERSION="2"
env: ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="boost" BOOST_INC="/usr/local/boost" CHAR_SIGN="unsigned" API_VERSION="2" X3_PARSE="ON"
- os: linux
compiler: gcc
env: ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="64" LIBPATH="/usr/local/lib" BOOST="" BOOST_INC="" CHAR_SIGN="unsigned" API_VERSION="2"
@ -72,4 +82,4 @@ matrix:
env: ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="32" LIBPATH="/usr/local/lib32" BOOST="boost" BOOST_INC="/usr/local/boost" SHARED="OFF" CHAR_SIGN="signed" API_VERSION="2"
script:
- git clean -xdf && CMAKE_LIBRARY_PATH=${LIBPATH} ${ACTION} ${VERSION} ${ARCH} ${BOOST} ${BOOST_INC} ${CHAR_SIGN}
- git clean -xdf && CMAKE_LIBRARY_PATH=${LIBPATH} ${ACTION} ${VERSION} ${ARCH} ${BOOST} ${BOOST_INC}

View File

@ -38,7 +38,19 @@ IF (APPLE)
ENDIF ()
ENDIF ()
IF (MSGPACK_CXX11)
IF (MSGPACK_USE_X3_PARSE)
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
SET (CMAKE_CXX_FLAGS "-DMSGPACK_USE_X3_PARSE -std=c++1y ${CMAKE_CXX_FLAGS}")
ELSEIF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
SET (CMAKE_CXX_FLAGS "-DMSGPACK_USE_X3_PARSE -std=c++1y ${CMAKE_CXX_FLAGS}")
ELSEIF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
SET (CMAKE_CXX_FLAGS "-DMSGPACK_USE_X3_PARSE ${CMAKE_CXX_FLAGS}")
IF (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19)
MESSAGE ( FATAL_ERROR "MSVC doesn't support C++14.")
ENDIF ()
ENDIF ()
ELSE ()
IF (MSGPACK_CXX11)
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
SET (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
ELSEIF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
@ -48,7 +60,7 @@ IF (MSGPACK_CXX11)
MESSAGE ( FATAL_ERROR "MSVC doesn't support C++11.")
ENDIF ()
ENDIF ()
ELSE ()
ELSE ()
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
IF ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER ${GNUCXX_STD_SUPPORT_VERSION}) OR
(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL ${GNUCXX_STD_SUPPORT_VERSION}))
@ -61,6 +73,7 @@ ELSE ()
SET (CMAKE_CXX_FLAGS "-DMSGPACK_USE_CPP03 ${CMAKE_CXX_FLAGS}")
ENDIF ()
ENDIF ()
ENDIF ()
ENDIF ()
IF (MSGPACK_32BIT)

View File

@ -33,10 +33,10 @@ build_script:
- cmake --build . --config Release
- cd ..
- cd ..
- appveyor DownloadFile http://zlib.net/zlib-1.2.9.tar.gz -FileName zlib-1.2.9.tar.gz
- 7z x zlib-1.2.9.tar.gz > NUL
- 7z x zlib-1.2.9.tar > NUL
- cd zlib-1.2.9
- appveyor DownloadFile http://zlib.net/zlib-1.2.10.tar.gz -FileName zlib-1.2.10.tar.gz
- 7z x zlib-1.2.10.tar.gz > NUL
- 7z x zlib-1.2.10.tar > NUL
- cd zlib-1.2.10
- md build
- cd build
- cmake -G %msvc% ..
@ -46,9 +46,9 @@ build_script:
- cd ..
- md build
- cd build
- cmake -G %msvc% %cpp11% %boost% -DMSGPACK_BOOST_DIR=C:\Libraries\\boost_1_60_0 -DGTEST_LIBRARY=%APPVEYOR_BUILD_FOLDER%\googletest-release-1.7.0\build\Release\gtest.lib -DGTEST_MAIN_LIBRARY=%APPVEYOR_BUILD_FOLDER%\googletest-release-1.7.0\build\Release\gtest_main.lib -DGTEST_INCLUDE_DIR=%APPVEYOR_BUILD_FOLDER%\googletest-release-1.7.0\include -DZLIB_LIBRARY=%APPVEYOR_BUILD_FOLDER%\zlib-1.2.9\build\Release\zlib.lib -DZLIB_INCLUDE_DIR=%APPVEYOR_BUILD_FOLDER%\zlib-1.2.9 -DCMAKE_CXX_FLAGS='"/D_VARIADIC_MAX=10 /EHsc"' ..
- cmake -G %msvc% %cpp11% %boost% %x3_parse% -DMSGPACK_BOOST_DIR=C:\Libraries\\boost_1_60_0 -DGTEST_LIBRARY=%APPVEYOR_BUILD_FOLDER%\googletest-release-1.7.0\build\Release\gtest.lib -DGTEST_MAIN_LIBRARY=%APPVEYOR_BUILD_FOLDER%\googletest-release-1.7.0\build\Release\gtest_main.lib -DGTEST_INCLUDE_DIR=%APPVEYOR_BUILD_FOLDER%\googletest-release-1.7.0\include -DZLIB_LIBRARY=%APPVEYOR_BUILD_FOLDER%\zlib-1.2.10\build\Release\zlib.lib -DZLIB_INCLUDE_DIR=%APPVEYOR_BUILD_FOLDER%\zlib-1.2.10 -DCMAKE_CXX_FLAGS='"/D_VARIADIC_MAX=10 /EHsc"' ..
- cmake --build . --config Release
test_script:
- set PATH=%PATH%;%APPVEYOR_BUILD_FOLDER%\googletest-release-1.7.0\build\Release;%APPVEYOR_BUILD_FOLDER%\zlib-1.2.9\build\Release;%APPVEYOR_BUILD_FOLDER%\build\release
- set PATH=%PATH%;%APPVEYOR_BUILD_FOLDER%\googletest-release-1.7.0\build\Release;%APPVEYOR_BUILD_FOLDER%\zlib-1.2.10\build\Release;%APPVEYOR_BUILD_FOLDER%\build\release
- ctest -V

View File

@ -51,7 +51,7 @@ else
shared=""
fi
cmake $cpp11 $bit32 $boost $boost_dir $shared -DMSGPACK_CHAR_SIGN=${CHAR_SIGN} -DMSGPACK_DEFAULT_API_VERSION=${API_VERSION} ..
cmake $cpp11 $bit32 $boost $boost_dir $shared -DMSGPACK_CHAR_SIGN=${CHAR_SIGN} -DMSGPACK_DEFAULT_API_VERSION=${API_VERSION} -DMSGPACK_USE_X3_PARSE=${X3_PARSE} ..
ret=$?
if [ $ret -ne 0 ]
@ -59,7 +59,7 @@ then
exit $ret
fi
make
make msgpack_x3_parse VERBOSE=1
ret=$?
if [ $ret -ne 0 ]
@ -67,6 +67,7 @@ then
exit $ret
fi
test/msgpack_x3_parse
make test
ret=$?

View File

@ -0,0 +1,16 @@
//
// MessagePack for C++ deserializing routine
//
// Copyright (C) 2017 KONDO Takatoshi
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef MSGPACK_PARSE_RETURN_HPP
#define MSGPACK_PARSE_RETURN_HPP
#include "msgpack/v1/parse_return.hpp"
#include "msgpack/v2/parse_return.hpp"
#endif // MSGPACK_PARSE_RETURN_HPP

View File

@ -14,5 +14,6 @@
#include "msgpack/v1/unpack.hpp"
#include "msgpack/v2/unpack.hpp"
#include "msgpack/v2/x3_unpack.hpp"
#endif // MSGPACK_UNPACK_HPP

View File

@ -0,0 +1,36 @@
//
// MessagePack for C++ deserializing routine
//
// Copyright (C) 2008-2016 FURUHASHI Sadayuki and KONDO Takatoshi
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef MSGPACK_V1_PARSE_RETURN_HPP
#define MSGPACK_V1_PARSE_RETURN_HPP
#include "msgpack/versioning.hpp"
namespace msgpack {
/// @cond
MSGPACK_API_VERSION_NAMESPACE(v1) {
/// @endcond
// for internal use
typedef enum {
PARSE_SUCCESS = 2,
PARSE_EXTRA_BYTES = 1,
PARSE_CONTINUE = 0,
PARSE_PARSE_ERROR = -1
} parse_return;
/// @cond
} // MSGPACK_API_VERSION_NAMESPACE(v1)
/// @endcond
} // namespace msgpack
#endif // MSGPACK_V1_PARSE_RETURN_HPP

View File

@ -1335,7 +1335,7 @@ inline void unpacker::remove_nonparsed_buffer()
namespace detail {
inline unpack_return
inline parse_return
unpack_imp(const char* data, std::size_t len, std::size_t& off,
msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR,
@ -1345,7 +1345,7 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
if(len <= noff) {
// FIXME
return UNPACK_CONTINUE;
return PARSE_CONTINUE;
}
detail::context ctx(f, user_data, limit);
@ -1357,23 +1357,23 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
int e = ctx.execute(data, len, noff);
if(e < 0) {
return UNPACK_PARSE_ERROR;
return PARSE_PARSE_ERROR;
}
referenced = ctx.user().referenced();
off = noff;
if(e == 0) {
return UNPACK_CONTINUE;
return PARSE_CONTINUE;
}
result = ctx.data();
if(noff < len) {
return UNPACK_EXTRA_BYTES;
return PARSE_EXTRA_BYTES;
}
return UNPACK_SUCCESS;
return PARSE_SUCCESS;
}
} // detail
@ -1390,19 +1390,19 @@ inline msgpack::object_handle unpack(
msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
referenced = false;
std::size_t noff = off;
unpack_return ret = detail::unpack_imp(
parse_return ret = detail::unpack_imp(
data, len, noff, *z, obj, referenced, f, user_data, limit);
switch(ret) {
case UNPACK_SUCCESS:
case PARSE_SUCCESS:
off = noff;
return msgpack::object_handle(obj, msgpack::move(z));
case UNPACK_EXTRA_BYTES:
case PARSE_EXTRA_BYTES:
off = noff;
return msgpack::object_handle(obj, msgpack::move(z));
case UNPACK_CONTINUE:
case PARSE_CONTINUE:
throw msgpack::insufficient_bytes("insufficient bytes");
case UNPACK_PARSE_ERROR:
case PARSE_PARSE_ERROR:
default:
throw msgpack::parse_error("parse error");
}
@ -1447,23 +1447,23 @@ inline void unpack(
msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
referenced = false;
std::size_t noff = off;
unpack_return ret = detail::unpack_imp(
parse_return ret = detail::unpack_imp(
data, len, noff, *z, obj, referenced, f, user_data, limit);
switch(ret) {
case UNPACK_SUCCESS:
case PARSE_SUCCESS:
off = noff;
result.set(obj);
result.zone() = msgpack::move(z);
return;
case UNPACK_EXTRA_BYTES:
case PARSE_EXTRA_BYTES:
off = noff;
result.set(obj);
result.zone() = msgpack::move(z);
return;
case UNPACK_CONTINUE:
case PARSE_CONTINUE:
throw msgpack::insufficient_bytes("insufficient bytes");
case UNPACK_PARSE_ERROR:
case PARSE_PARSE_ERROR:
default:
throw msgpack::parse_error("parse error");
}
@ -1510,19 +1510,19 @@ inline msgpack::object unpack(
msgpack::object obj;
std::size_t noff = off;
referenced = false;
unpack_return ret = detail::unpack_imp(
parse_return ret = detail::unpack_imp(
data, len, noff, z, obj, referenced, f, user_data, limit);
switch(ret) {
case UNPACK_SUCCESS:
case PARSE_SUCCESS:
off = noff;
return obj;
case UNPACK_EXTRA_BYTES:
case PARSE_EXTRA_BYTES:
off = noff;
return obj;
case UNPACK_CONTINUE:
case PARSE_CONTINUE:
throw msgpack::insufficient_bytes("insufficient bytes");
case UNPACK_PARSE_ERROR:
case PARSE_PARSE_ERROR:
default:
throw msgpack::parse_error("parse error");
}

View File

@ -16,6 +16,7 @@
#include "msgpack/zone.hpp"
#include "msgpack/cpp_config.hpp"
#include "msgpack/sysdep.h"
#include "msgpack/parse_return.hpp"
#include <memory>
#include <stdexcept>
@ -433,17 +434,9 @@ void unpack(
unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR, unpack_limit const& limit = unpack_limit());
// for internal use
typedef enum {
UNPACK_SUCCESS = 2,
UNPACK_EXTRA_BYTES = 1,
UNPACK_CONTINUE = 0,
UNPACK_PARSE_ERROR = -1
} unpack_return;
namespace detail {
unpack_return
parse_return
unpack_imp(const char* data, std::size_t len, std::size_t& off,
msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
unpack_reference_func f, void* user_data,

View File

@ -37,7 +37,7 @@ public:
holder().visitor().init();
}
unpack_return execute(const char* data, std::size_t len, std::size_t& off);
parse_return execute(const char* data, std::size_t len, std::size_t& off);
private:
template <typename T>
@ -51,7 +51,7 @@ private:
}
template <typename T, typename StartVisitor, typename EndVisitor>
unpack_return start_aggregate(
parse_return start_aggregate(
StartVisitor const& sv,
EndVisitor const& ev,
const char* load_pos,
@ -62,14 +62,14 @@ private:
if (size == 0) {
if (!sv(size)) {
off = m_current - m_start;
return UNPACK_STOP_VISITOR;
return PARSE_STOP_VISITOR;
}
if (!ev()) {
off = m_current - m_start;
return UNPACK_STOP_VISITOR;
return PARSE_STOP_VISITOR;
}
unpack_return ret = m_stack.consume(holder());
if (ret != UNPACK_CONTINUE) {
parse_return ret = m_stack.consume(holder());
if (ret != PARSE_CONTINUE) {
off = m_current - m_start;
return ret;
}
@ -78,21 +78,21 @@ private:
m_stack.push(sv.type(), static_cast<uint32_t>(size));
if (!sv(size)) {
off = m_current - m_start;
return UNPACK_STOP_VISITOR;
return PARSE_STOP_VISITOR;
}
}
m_cs = MSGPACK_CS_HEADER;
return UNPACK_CONTINUE;
return PARSE_CONTINUE;
}
unpack_return after_visit_proc(bool visit_result, std::size_t& off) {
parse_return after_visit_proc(bool visit_result, std::size_t& off) {
++m_current;
if (!visit_result) {
off = m_current - m_start;
return UNPACK_STOP_VISITOR;
return PARSE_STOP_VISITOR;
}
unpack_return ret = m_stack.consume(holder());
if (ret == UNPACK_CONTINUE) {
parse_return ret = m_stack.consume(holder());
if (ret == PARSE_CONTINUE) {
m_cs = MSGPACK_CS_HEADER;
}
else {
@ -148,41 +148,41 @@ private:
void push(msgpack_container_type type, uint32_t rest) {
m_stack.push_back(stack_elem(type, rest));
}
unpack_return consume(VisitorHolder& visitor_holder) {
parse_return consume(VisitorHolder& visitor_holder) {
while (!m_stack.empty()) {
stack_elem& e = m_stack.back();
switch (e.m_type) {
case MSGPACK_CT_ARRAY_ITEM:
if (!visitor_holder.visitor().end_array_item()) return UNPACK_STOP_VISITOR;
if (!visitor_holder.visitor().end_array_item()) return PARSE_STOP_VISITOR;
if (--e.m_rest == 0) {
m_stack.pop_back();
if (!visitor_holder.visitor().end_array()) return UNPACK_STOP_VISITOR;
if (!visitor_holder.visitor().end_array()) return PARSE_STOP_VISITOR;
}
else {
if (!visitor_holder.visitor().start_array_item()) return UNPACK_STOP_VISITOR;
return UNPACK_CONTINUE;
if (!visitor_holder.visitor().start_array_item()) return PARSE_STOP_VISITOR;
return PARSE_CONTINUE;
}
break;
case MSGPACK_CT_MAP_KEY:
if (!visitor_holder.visitor().end_map_key()) return UNPACK_STOP_VISITOR;
if (!visitor_holder.visitor().start_map_value()) return UNPACK_STOP_VISITOR;
if (!visitor_holder.visitor().end_map_key()) return PARSE_STOP_VISITOR;
if (!visitor_holder.visitor().start_map_value()) return PARSE_STOP_VISITOR;
e.m_type = MSGPACK_CT_MAP_VALUE;
return UNPACK_CONTINUE;
return PARSE_CONTINUE;
case MSGPACK_CT_MAP_VALUE:
if (!visitor_holder.visitor().end_map_value()) return UNPACK_STOP_VISITOR;
if (!visitor_holder.visitor().end_map_value()) return PARSE_STOP_VISITOR;
if (--e.m_rest == 0) {
m_stack.pop_back();
if (!visitor_holder.visitor().end_map()) return UNPACK_STOP_VISITOR;
if (!visitor_holder.visitor().end_map()) return PARSE_STOP_VISITOR;
}
else {
e.m_type = MSGPACK_CT_MAP_KEY;
if (!visitor_holder.visitor().start_map_key()) return UNPACK_STOP_VISITOR;
return UNPACK_CONTINUE;
if (!visitor_holder.visitor().start_map_key()) return PARSE_STOP_VISITOR;
return PARSE_CONTINUE;
}
break;
}
}
return UNPACK_SUCCESS;
return PARSE_SUCCESS;
}
bool empty() const { return m_stack.empty(); }
void clear() { m_stack.clear(); }
@ -209,7 +209,7 @@ inline void check_ext_size<4>(std::size_t size) {
}
template <typename VisitorHolder>
inline unpack_return context<VisitorHolder>::execute(const char* data, std::size_t len, std::size_t& off)
inline parse_return context<VisitorHolder>::execute(const char* data, std::size_t len, std::size_t& off)
{
assert(len >= off);
@ -222,7 +222,7 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
if(m_current == pe) {
off = m_current - m_start;
return UNPACK_CONTINUE;
return PARSE_CONTINUE;
}
bool fixed_trail_again = false;
do {
@ -232,13 +232,13 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
if (0x00 <= selector && selector <= 0x7f) { // Positive Fixnum
uint8_t tmp = *reinterpret_cast<const uint8_t*>(m_current);
bool visret = holder().visitor().visit_positive_integer(tmp);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} else if(0xe0 <= selector && selector <= 0xff) { // Negative Fixnum
int8_t tmp = *reinterpret_cast<const int8_t*>(m_current);
bool visret = holder().visitor().visit_negative_integer(tmp);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} else if (0xc4 <= selector && selector <= 0xdf) {
const uint32_t trail[] = {
1, // bin 8 0xc4
@ -277,37 +277,37 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
m_trail = static_cast<uint32_t>(*m_current) & 0x1f;
if(m_trail == 0) {
bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
}
else {
m_cs = MSGPACK_ACS_STR_VALUE;
fixed_trail_again = true;
}
} else if(0x90 <= selector && selector <= 0x9f) { // FixArray
unpack_return ret = start_aggregate<fix_tag>(array_sv(holder()), array_ev(holder()), m_current, off);
if (ret != UNPACK_CONTINUE) return ret;
if (!holder().visitor().start_array_item()) return UNPACK_STOP_VISITOR;
parse_return ret = start_aggregate<fix_tag>(array_sv(holder()), array_ev(holder()), m_current, off);
if (ret != PARSE_CONTINUE) return ret;
if (!holder().visitor().start_array_item()) return PARSE_STOP_VISITOR;
} else if(0x80 <= selector && selector <= 0x8f) { // FixMap
unpack_return ret = start_aggregate<fix_tag>(map_sv(holder()), map_ev(holder()), m_current, off);
if (ret != UNPACK_CONTINUE) return ret;
if (!holder().visitor().start_map_key()) return UNPACK_STOP_VISITOR;
parse_return ret = start_aggregate<fix_tag>(map_sv(holder()), map_ev(holder()), m_current, off);
if (ret != PARSE_CONTINUE) return ret;
if (!holder().visitor().start_map_key()) return PARSE_STOP_VISITOR;
} else if(selector == 0xc2) { // false
bool visret = holder().visitor().visit_boolean(false);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} else if(selector == 0xc3) { // true
bool visret = holder().visitor().visit_boolean(true);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} else if(selector == 0xc0) { // nil
bool visret = holder().visitor().visit_nil();
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} else {
off = m_current - m_start;
holder().visitor().parse_error(off - 1, off);
return UNPACK_PARSE_ERROR;
return PARSE_PARSE_ERROR;
}
// end MSGPACK_CS_HEADER
}
@ -318,7 +318,7 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
}
if(static_cast<std::size_t>(pe - m_current) < m_trail) {
off = m_current - m_start;
return UNPACK_CONTINUE;
return PARSE_CONTINUE;
}
n = m_current;
m_current += m_trail - 1;
@ -329,8 +329,8 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
union { uint32_t i; float f; } mem;
load<uint32_t>(mem.i, n);
bool visret = holder().visitor().visit_float(mem.f);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_DOUBLE: {
union { uint64_t i; double f; } mem;
@ -342,89 +342,89 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
#endif
bool visret = holder().visitor().visit_float(mem.f);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_UINT_8: {
uint8_t tmp;
load<uint8_t>(tmp, n);
bool visret = holder().visitor().visit_positive_integer(tmp);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_UINT_16: {
uint16_t tmp;
load<uint16_t>(tmp, n);
bool visret = holder().visitor().visit_positive_integer(tmp);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_UINT_32: {
uint32_t tmp;
load<uint32_t>(tmp, n);
bool visret = holder().visitor().visit_positive_integer(tmp);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_UINT_64: {
uint64_t tmp;
load<uint64_t>(tmp, n);
bool visret = holder().visitor().visit_positive_integer(tmp);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_INT_8: {
int8_t tmp;
load<int8_t>(tmp, n);
bool visret = holder().visitor().visit_negative_integer(tmp);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_INT_16: {
int16_t tmp;
load<int16_t>(tmp, n);
bool visret = holder().visitor().visit_negative_integer(tmp);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_INT_32: {
int32_t tmp;
load<int32_t>(tmp, n);
bool visret = holder().visitor().visit_negative_integer(tmp);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_INT_64: {
int64_t tmp;
load<int64_t>(tmp, n);
bool visret = holder().visitor().visit_negative_integer(tmp);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_FIXEXT_1: {
bool visret = holder().visitor().visit_ext(n, 1+1);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_FIXEXT_2: {
bool visret = holder().visitor().visit_ext(n, 2+1);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_FIXEXT_4: {
bool visret = holder().visitor().visit_ext(n, 4+1);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_FIXEXT_8: {
bool visret = holder().visitor().visit_ext(n, 8+1);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_FIXEXT_16: {
bool visret = holder().visitor().visit_ext(n, 16+1);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_STR_8: {
uint8_t tmp;
@ -432,8 +432,8 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
m_trail = tmp;
if(m_trail == 0) {
bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
}
else {
m_cs = MSGPACK_ACS_STR_VALUE;
@ -446,8 +446,8 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
m_trail = tmp;
if(m_trail == 0) {
bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
}
else {
m_cs = MSGPACK_ACS_BIN_VALUE;
@ -460,8 +460,8 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
m_trail = tmp + 1;
if(m_trail == 0) {
bool visret = holder().visitor().visit_ext(n, m_trail);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
}
else {
m_cs = MSGPACK_ACS_EXT_VALUE;
@ -474,8 +474,8 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
m_trail = tmp;
if(m_trail == 0) {
bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
}
else {
m_cs = MSGPACK_ACS_STR_VALUE;
@ -488,8 +488,8 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
m_trail = tmp;
if(m_trail == 0) {
bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
}
else {
m_cs = MSGPACK_ACS_BIN_VALUE;
@ -502,8 +502,8 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
m_trail = tmp + 1;
if(m_trail == 0) {
bool visret = holder().visitor().visit_ext(n, m_trail);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
}
else {
m_cs = MSGPACK_ACS_EXT_VALUE;
@ -516,8 +516,8 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
m_trail = tmp;
if(m_trail == 0) {
bool visret = holder().visitor().visit_str(n, static_cast<uint32_t>(m_trail));
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
}
else {
m_cs = MSGPACK_ACS_STR_VALUE;
@ -530,8 +530,8 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
m_trail = tmp;
if(m_trail == 0) {
bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
}
else {
m_cs = MSGPACK_ACS_BIN_VALUE;
@ -546,8 +546,8 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
++m_trail;
if(m_trail == 0) {
bool visret = holder().visitor().visit_ext(n, m_trail);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
}
else {
m_cs = MSGPACK_ACS_EXT_VALUE;
@ -556,50 +556,50 @@ inline unpack_return context<VisitorHolder>::execute(const char* data, std::size
} break;
case MSGPACK_ACS_STR_VALUE: {
bool visret = holder().visitor().visit_str(n, m_trail);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_ACS_BIN_VALUE: {
bool visret = holder().visitor().visit_bin(n, static_cast<uint32_t>(m_trail));
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_ACS_EXT_VALUE: {
bool visret = holder().visitor().visit_ext(n, m_trail);
unpack_return upr = after_visit_proc(visret, off);
if (upr != UNPACK_CONTINUE) return upr;
parse_return upr = after_visit_proc(visret, off);
if (upr != PARSE_CONTINUE) return upr;
} break;
case MSGPACK_CS_ARRAY_16: {
unpack_return ret = start_aggregate<uint16_t>(array_sv(holder()), array_ev(holder()), n, off);
if (ret != UNPACK_CONTINUE) return ret;
if (!holder().visitor().start_array_item()) return UNPACK_STOP_VISITOR;
parse_return ret = start_aggregate<uint16_t>(array_sv(holder()), array_ev(holder()), n, off);
if (ret != PARSE_CONTINUE) return ret;
if (!holder().visitor().start_array_item()) return PARSE_STOP_VISITOR;
} break;
case MSGPACK_CS_ARRAY_32: {
unpack_return ret = start_aggregate<uint32_t>(array_sv(holder()), array_ev(holder()), n, off);
if (ret != UNPACK_CONTINUE) return ret;
if (!holder().visitor().start_array_item()) return UNPACK_STOP_VISITOR;
parse_return ret = start_aggregate<uint32_t>(array_sv(holder()), array_ev(holder()), n, off);
if (ret != PARSE_CONTINUE) return ret;
if (!holder().visitor().start_array_item()) return PARSE_STOP_VISITOR;
} break;
case MSGPACK_CS_MAP_16: {
unpack_return ret = start_aggregate<uint16_t>(map_sv(holder()), map_ev(holder()), n, off);
if (ret != UNPACK_CONTINUE) return ret;
if (!holder().visitor().start_map_key()) return UNPACK_STOP_VISITOR;
parse_return ret = start_aggregate<uint16_t>(map_sv(holder()), map_ev(holder()), n, off);
if (ret != PARSE_CONTINUE) return ret;
if (!holder().visitor().start_map_key()) return PARSE_STOP_VISITOR;
} break;
case MSGPACK_CS_MAP_32: {
unpack_return ret = start_aggregate<uint32_t>(map_sv(holder()), map_ev(holder()), n, off);
if (ret != UNPACK_CONTINUE) return ret;
if (!holder().visitor().start_map_key()) return UNPACK_STOP_VISITOR;
parse_return ret = start_aggregate<uint32_t>(map_sv(holder()), map_ev(holder()), n, off);
if (ret != PARSE_CONTINUE) return ret;
if (!holder().visitor().start_map_key()) return PARSE_STOP_VISITOR;
} break;
default:
off = m_current - m_start;
holder().visitor().parse_error(n - m_start - 1, n - m_start);
return UNPACK_PARSE_ERROR;
return PARSE_PARSE_ERROR;
}
}
} while(m_current != pe);
off = m_current - m_start;
return UNPACK_CONTINUE;
return PARSE_CONTINUE;
}
} // detail
@ -743,7 +743,7 @@ protected:
}
private:
void expand_buffer(std::size_t size);
unpack_return execute_imp();
parse_return execute_imp();
private:
char* m_buffer;
@ -930,15 +930,15 @@ inline void parser<VisitorHolder, ReferencedBufferHook>::buffer_consumed(std::si
template <typename VisitorHolder, typename ReferencedBufferHook>
inline bool parser<VisitorHolder, ReferencedBufferHook>::next()
{
unpack_return ret = execute_imp();
return ret == UNPACK_SUCCESS;
parse_return ret = execute_imp();
return ret == PARSE_SUCCESS;
}
template <typename VisitorHolder, typename ReferencedBufferHook>
inline unpack_return parser<VisitorHolder, ReferencedBufferHook>::execute_imp()
inline parse_return parser<VisitorHolder, ReferencedBufferHook>::execute_imp()
{
std::size_t off = m_off;
unpack_return ret = context_type::execute(m_buffer, m_used, m_off);
parse_return ret = context_type::execute(m_buffer, m_used, m_off);
if(m_off > off) {
m_parsed += m_off - off;
}
@ -991,8 +991,8 @@ inline void parser<VisitorHolder, ReferencedBufferHook>::remove_nonparsed_buffer
template <typename Visitor>
inline bool parse(const char* data, size_t len, size_t& off, Visitor& v) {
unpack_return ret = detail::parse_imp(data, len, off, v);
return ret == UNPACK_SUCCESS || ret == UNPACK_EXTRA_BYTES;
parse_return ret = detail::parse_imp(data, len, off, v);
return ret == PARSE_SUCCESS || ret == PARSE_EXTRA_BYTES;
}
template <typename Visitor>
@ -1006,7 +1006,7 @@ namespace detail {
template <typename Visitor>
struct parse_helper : context<parse_helper<Visitor> > {
parse_helper(Visitor& v):m_visitor(v) {}
unpack_return execute(const char* data, std::size_t len, std::size_t& off) {
parse_return execute(const char* data, std::size_t len, std::size_t& off) {
return context<parse_helper<Visitor> >::execute(data, len, off);
}
Visitor& visitor() const { return m_visitor; }
@ -1014,26 +1014,26 @@ struct parse_helper : context<parse_helper<Visitor> > {
};
template <typename Visitor>
inline unpack_return
inline parse_return
parse_imp(const char* data, size_t len, size_t& off, Visitor& v) {
std::size_t noff = off;
if(len <= noff) {
// FIXME
v.insufficient_bytes(noff, noff);
return UNPACK_CONTINUE;
return PARSE_CONTINUE;
}
detail::parse_helper<Visitor> h(v);
unpack_return ret = h.execute(data, len, noff);
parse_return ret = h.execute(data, len, noff);
switch (ret) {
case UNPACK_CONTINUE:
case PARSE_CONTINUE:
off = noff;
v.insufficient_bytes(noff - 1, noff);
return ret;
case UNPACK_SUCCESS:
case PARSE_SUCCESS:
off = noff;
if(noff < len) {
return UNPACK_EXTRA_BYTES;
return PARSE_EXTRA_BYTES;
}
return ret;
default:

View File

@ -0,0 +1,37 @@
//
// MessagePack for C++ deserializing routine
//
// Copyright (C) 2008-2016 FURUHASHI Sadayuki and KONDO Takatoshi
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef MSGPACK_V2_PARSE_RETURN_HPP
#define MSGPACK_V2_PARSE_RETURN_HPP
#include "msgpack/v1/parse_return.hpp"
namespace msgpack {
/// @cond
MSGPACK_API_VERSION_NAMESPACE(v2) {
/// @endcond
// for internal use
typedef enum {
PARSE_SUCCESS = v1::PARSE_SUCCESS,
PARSE_EXTRA_BYTES = v1::PARSE_EXTRA_BYTES,
PARSE_CONTINUE = v1::PARSE_CONTINUE,
PARSE_PARSE_ERROR = v1::PARSE_PARSE_ERROR,
PARSE_STOP_VISITOR = -2
} parse_return;
/// @cond
} // MSGPACK_API_VERSION_NAMESPACE(v2)
/// @endcond
} // namespace msgpack
#endif // MSGPACK_V2_PARSE_RETURN_HPP

View File

@ -152,14 +152,14 @@ inline msgpack::object_handle unpack(
msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
referenced = false;
std::size_t noff = off;
unpack_return ret = detail::unpack_imp(
parse_return ret = detail::unpack_imp(
data, len, noff, *z, obj, referenced, f, user_data, limit);
switch(ret) {
case UNPACK_SUCCESS:
case PARSE_SUCCESS:
off = noff;
return msgpack::object_handle(obj, msgpack::move(z));
case UNPACK_EXTRA_BYTES:
case PARSE_EXTRA_BYTES:
off = noff;
return msgpack::object_handle(obj, msgpack::move(z));
default:
@ -206,16 +206,16 @@ inline void unpack(
msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
referenced = false;
std::size_t noff = off;
unpack_return ret = detail::unpack_imp(
parse_return ret = detail::unpack_imp(
data, len, noff, *z, obj, referenced, f, user_data, limit);
switch(ret) {
case UNPACK_SUCCESS:
case PARSE_SUCCESS:
off = noff;
result.set(obj);
result.zone() = msgpack::move(z);
return;
case UNPACK_EXTRA_BYTES:
case PARSE_EXTRA_BYTES:
off = noff;
result.set(obj);
result.zone() = msgpack::move(z);
@ -266,14 +266,14 @@ inline msgpack::object unpack(
msgpack::object obj;
std::size_t noff = off;
referenced = false;
unpack_return ret = detail::unpack_imp(
parse_return ret = detail::unpack_imp(
data, len, noff, z, obj, referenced, f, user_data, limit);
switch(ret) {
case UNPACK_SUCCESS:
case PARSE_SUCCESS:
off = noff;
return obj;
case UNPACK_EXTRA_BYTES:
case PARSE_EXTRA_BYTES:
off = noff;
return obj;
default:
@ -315,7 +315,7 @@ inline msgpack::object unpack(
namespace detail {
inline unpack_return
inline parse_return
unpack_imp(const char* data, std::size_t len, std::size_t& off,
msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR,
@ -325,13 +325,13 @@ unpack_imp(const char* data, std::size_t len, std::size_t& off,
v.set_zone(result_zone);
referenced = false;
v.set_referenced(referenced);
unpack_return ret = parse_imp(data, len, off, v);
parse_return ret = parse_imp(data, len, off, v);
referenced = v.referenced();
result = v.data();
return ret;
}
} // detail
} // namespace detail
/// @cond

View File

@ -87,14 +87,6 @@ class unpacker;
template <typename unpack_visitor, typename referenced_buffer_hook>
class basic_unpacker;
typedef enum unpack_return {
UNPACK_SUCCESS = v1::UNPACK_SUCCESS,
UNPACK_EXTRA_BYTES = v1::UNPACK_EXTRA_BYTES,
UNPACK_CONTINUE = v1::UNPACK_CONTINUE,
UNPACK_PARSE_ERROR = v1::UNPACK_PARSE_ERROR,
UNPACK_STOP_VISITOR = -2
} unpack_return;
/// Unpack msgpack::object from a buffer.
/**
* @param data The pointer to the buffer.
@ -327,14 +319,14 @@ bool parse(const char* data, size_t len, Visitor& v);
namespace detail {
unpack_return
parse_return
unpack_imp(const char* data, std::size_t len, std::size_t& off,
msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
unpack_reference_func f, void* user_data,
unpack_limit const& limit);
template <typename UnpackVisitor>
unpack_return
parse_return
parse_imp(const char* data, size_t len, size_t& off, UnpackVisitor& v);
} // detail

View File

@ -0,0 +1,859 @@
//
// MessagePack for C++ deserializing routine
//
// Copyright (C) 2017 KONDO Takatoshi
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef MSGPACK_V2_X3_PARSE_HPP
#define MSGPACK_V2_X3_PARSE_HPP
#if defined(MSGPACK_USE_X3_PARSE)
#include <boost/version.hpp>
#if BOOST_VERSION >= 106100
#include "msgpack/versioning.hpp"
#if __GNUC__ >= 4
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif // __GNUC__ >= 4
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/binary.hpp>
namespace msgpack {
/// @cond
MSGPACK_API_VERSION_NAMESPACE(v2) {
/// @endcond
namespace detail {
namespace x3 = boost::spirit::x3;
using x3::byte_;
// byte range utility
const auto byte_range = [](const std::uint8_t from, const std::uint8_t to) {
const auto check = [from, to](auto& ctx)
{
const std::uint8_t value = x3::_attr(ctx);
x3::_val(ctx) = value;
x3::_pass(ctx) = from <= value && value <= to;
};
return x3::byte_ [check];
};
// MessagePack rule
const auto mp_positive_fixint = byte_range(0x00, 0x7f);
const auto mp_fixmap = byte_range(0x80, 0x8f);
const auto mp_fixarray = byte_range(0x90, 0x9f);
const auto mp_fixstr = byte_range(0xa0, 0xbf);
const auto mp_nil = x3::byte_(0xc0);
const auto mp_false = x3::byte_(0xc2);
const auto mp_true = x3::byte_(0xc3);
const auto mp_bin8 = x3::byte_(0xc4);
const auto mp_bin16 = x3::byte_(0xc5);
const auto mp_bin32 = x3::byte_(0xc6);
const auto mp_ext8 = x3::byte_(0xc7);
const auto mp_ext16 = x3::byte_(0xc8);
const auto mp_ext32 = x3::byte_(0xc9);
const auto mp_float32 = x3::byte_(0xca);
const auto mp_float64 = x3::byte_(0xcb);
const auto mp_uint8 = x3::byte_(0xcc);
const auto mp_uint16 = x3::byte_(0xcd);
const auto mp_uint32 = x3::byte_(0xce);
const auto mp_uint64 = x3::byte_(0xcf);
const auto mp_int8 = x3::byte_(0xd0);
const auto mp_int16 = x3::byte_(0xd1);
const auto mp_int32 = x3::byte_(0xd2);
const auto mp_int64 = x3::byte_(0xd3);
const auto mp_fixext1 = x3::byte_(0xd4);
const auto mp_fixext2 = x3::byte_(0xd5);
const auto mp_fixext4 = x3::byte_(0xd6);
const auto mp_fixext8 = x3::byte_(0xd7);
const auto mp_fixext16 = x3::byte_(0xd8);
const auto mp_str8 = x3::byte_(0xd9);
const auto mp_str16 = x3::byte_(0xda);
const auto mp_str32 = x3::byte_(0xdb);
const auto mp_array16 = x3::byte_(0xdc);
const auto mp_array32 = x3::byte_(0xdd);
const auto mp_map16 = x3::byte_(0xde);
const auto mp_map32 = x3::byte_(0xdf);
const auto mp_negative_fixint = byte_range(0xe0, 0xff);
const auto mp_d_uint8 = x3::byte_;
const auto mp_d_uint16 = x3::big_word;
const auto mp_d_uint32 = x3::big_dword;
const auto mp_d_uint64 = x3::big_qword;
const auto mp_d_int8 = x3::byte_;
const auto mp_d_int16 = x3::big_word;
const auto mp_d_int32 = x3::big_dword;
const auto mp_d_int64 = x3::big_qword;
x3::rule<class mp_object> const mp_object("mp_object");
x3::rule<class array_items> const array_item("array_item");
x3::rule<class map_items> const map_item("map_item");
x3::rule<class kv> const kv("kv");
struct tag_app_specific {};
struct index_size {
enum struct type_t {
array,
map,
other
};
index_size(std::size_t size, type_t type = type_t::other):size(size), type(type) {}
std::size_t index = 0;
std::size_t size;
type_t type;
};
template <typename Visitor>
struct app_specific {
template <typename Vis>
app_specific(Vis&& vis):vis(vis) {}
std::vector<index_size> index_sizes;
Visitor vis;
};
template <typename Visitor>
app_specific<Visitor> make_app_specific(Visitor&& vis) {
return app_specific<Visitor>(std::forward<Visitor>(vis));
}
const auto more = [](auto &ctx) {
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
_pass(ctx) = app_specific.index_sizes.back().index++ < app_specific.index_sizes.back().size;
};
const auto done = [](auto &ctx) {
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
if (app_specific.index_sizes.back().index == app_specific.index_sizes.back().size + 1) {
_pass(ctx) = true;
switch (app_specific.index_sizes.back().type) {
case index_size::type_t::array:
app_specific.vis.end_array();
break;
case index_size::type_t::map:
app_specific.vis.end_map();
break;
case index_size::type_t::other:
break;
}
app_specific.index_sizes.pop_back();
}
else {
_pass(ctx) = false;
}
};
const auto mp_object_def =
// -----------------------------------------------
mp_nil [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.visit_nil();
}
)
]
|
// -----------------------------------------------
mp_true [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.visit_boolean(true);
}
)
]
|
// -----------------------------------------------
mp_false [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.visit_boolean(false);
}
)
]
|
// -----------------------------------------------
mp_positive_fixint [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.visit_positive_integer(_attr(ctx));
}
)
]
|
// -----------------------------------------------
mp_negative_fixint [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::int8_t val = _attr(ctx);
app_specific.vis.visit_negative_integer(val);
}
)
]
|
// -----------------------------------------------
mp_uint8 >> mp_d_uint8 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.visit_negative_integer(_attr(ctx));
}
)
]
|
// -----------------------------------------------
mp_uint16 >> mp_d_uint16 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.visit_positive_integer(_attr(ctx));
}
)
]
|
// -----------------------------------------------
mp_uint32 >> mp_d_uint32 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.visit_positive_integer(_attr(ctx));
}
)
]
|
// -----------------------------------------------
mp_uint64 >> mp_d_uint64 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.visit_positive_integer(_attr(ctx));
}
)
]
|
// -----------------------------------------------
mp_int8 >> mp_d_int8 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::int8_t val = _attr(ctx);
app_specific.vis.visit_negative_integer(val);
}
)
]
|
// -----------------------------------------------
mp_int16 >> mp_d_int16 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::int16_t val = _attr(ctx);
app_specific.vis.visit_negative_integer(val);
}
)
]
|
// -----------------------------------------------
mp_int32 >> mp_d_int32 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::int32_t val = _attr(ctx);
app_specific.vis.visit_negative_integer(val);
}
)
]
|
// -----------------------------------------------
mp_int64 >> mp_d_int64 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::int64_t val = _attr(ctx);
app_specific.vis.visit_negative_integer(val);
}
)
]
|
// -----------------------------------------------
mp_float32 >> mp_d_uint32 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
union { uint32_t i; float f; } mem;
mem.i = _attr(ctx);
app_specific.vis.visit_float(mem.f);
}
)
]
|
// -----------------------------------------------
mp_float64 >> mp_d_uint64 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
union { uint64_t i; double f; } mem;
mem.i = _attr(ctx);
#if defined(TARGET_OS_IPHONE)
// ok
#elif defined(__arm__) && !(__ARM_EABI__) // arm-oabi
// https://github.com/msgpack/msgpack-perl/pull/1
mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
#endif
app_specific.vis.visit_float(mem.f);
}
)
]
|
// -----------------------------------------------
mp_fixstr [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::size_t size = _attr(ctx) & 0b00011111;
app_specific.index_sizes.emplace_back(size);
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& str = _attr(ctx);
app_specific.vis.visit_str(str.size() ? &str[0] : nullptr, str.size());
}
)
]
|
// -----------------------------------------------
mp_str8 >> mp_d_uint8 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(_attr(ctx));
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& str = _attr(ctx);
app_specific.vis.visit_str(str.size() ? &str[0] : nullptr, str.size());
}
)
]
|
// -----------------------------------------------
mp_str16 >> mp_d_uint16 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(_attr(ctx));
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& str = _attr(ctx);
app_specific.vis.visit_str(str.size() ? &str[0] : nullptr, str.size());
}
)
]
|
// -----------------------------------------------
mp_str32 >> mp_d_uint32 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(_attr(ctx));
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& str = _attr(ctx);
app_specific.vis.visit_str(str.size() ? &str[0] : nullptr, str.size());
}
)
]
|
// -----------------------------------------------
mp_bin8 >> mp_d_uint8 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(_attr(ctx));
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& bin = _attr(ctx);
app_specific.vis.visit_bin(bin.size() ? &bin[0] : nullptr, bin.size());
}
)
]
|
// -----------------------------------------------
mp_bin16 >> mp_d_uint16 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(_attr(ctx));
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& bin = _attr(ctx);
app_specific.vis.visit_bin(bin.size() ? &bin[0] : nullptr, bin.size());
}
)
]
|
// -----------------------------------------------
mp_bin32 >> mp_d_uint32 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(_attr(ctx));
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& bin = _attr(ctx);
app_specific.vis.visit_bin(bin.size() ? &bin[0] : nullptr, bin.size());
}
)
]
|
// -----------------------------------------------
mp_fixarray [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::size_t size = _attr(ctx) & 0b00001111;
app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
app_specific.vis.start_array(size);
}
)
]
>> *(x3::eps [more] >> array_item)
>> x3::eps [done]
|
// -----------------------------------------------
mp_array16 >> mp_d_uint16 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::size_t size = _attr(ctx);
app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
app_specific.vis.start_array(size);
}
)
]
>> *(x3::eps [more] >> array_item)
>> x3::eps [done]
|
// -----------------------------------------------
mp_array32 >> mp_d_uint32 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::size_t size = _attr(ctx);
app_specific.index_sizes.emplace_back(size, index_size::type_t::array);
app_specific.vis.start_array(size);
}
)
]
>> *(x3::eps [more] >> array_item)
>> x3::eps [done]
|
// -----------------------------------------------
mp_fixmap [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::size_t size = _attr(ctx) & 0b00001111;
app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
app_specific.vis.start_map(size);
}
)
]
>> *(x3::eps [more] >> map_item)
>> x3::eps [done]
|
// -----------------------------------------------
mp_map16 >> mp_d_uint16 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::size_t size = _attr(ctx);
app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
app_specific.vis.start_map(size);
}
)
]
>> *(x3::eps [more] >> map_item)
>> x3::eps [done]
|
// -----------------------------------------------
mp_map32 >> mp_d_uint32 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
std::size_t size = _attr(ctx);
app_specific.index_sizes.emplace_back(size, index_size::type_t::map);
app_specific.vis.start_map(size);
}
)
]
>> *(x3::eps [more] >> map_item)
>> x3::eps [done]
|
// -----------------------------------------------
mp_fixext1 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(1+1);
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& ext = _attr(ctx);
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
}
)
]
|
// -----------------------------------------------
mp_fixext2 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(2+1);
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& ext = _attr(ctx);
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
}
)
]
|
// -----------------------------------------------
mp_fixext4 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(4+1);
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& ext = _attr(ctx);
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
}
)
]
|
// -----------------------------------------------
mp_fixext8 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(8+1);
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& ext = _attr(ctx);
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
}
)
]
|
// -----------------------------------------------
mp_fixext16 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(16+1);
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& ext = _attr(ctx);
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
}
)
]
|
// -----------------------------------------------
mp_ext8 >> mp_d_uint8 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(_attr(ctx)+1);
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& ext = _attr(ctx);
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
}
)
]
|
// -----------------------------------------------
mp_ext16 >> mp_d_uint16 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(_attr(ctx)+1);
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& ext = _attr(ctx);
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
}
)
]
|
// -----------------------------------------------
mp_ext32 >> mp_d_uint32 [
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.index_sizes.emplace_back(_attr(ctx)+1);
}
)
]
>>
x3:: raw [
*(x3::eps [more] >> x3::char_)
>> x3::eps [done]
][
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
auto const& ext = _attr(ctx);
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
}
)
];
const auto array_item_def =
x3::eps[
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.start_array_item();
_pass(ctx) = true;
}
)
]
>>
mp_object
>>
x3::eps[
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.end_array_item();
_pass(ctx) = true;
}
)
];
const auto map_item_def = kv;
const auto kv_def =
x3::eps[
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.start_map_key();
_pass(ctx) = true;
}
)
]
>>
mp_object
>>
x3::eps[
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.end_map_key();
_pass(ctx) = true;
}
)
]
>>
x3::eps[
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.start_map_value();
_pass(ctx) = true;
}
)
]
>>
mp_object
>>
x3::eps[
(
[](auto& ctx){
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
app_specific.vis.end_map_value();
_pass(ctx) = true;
}
)
];
BOOST_SPIRIT_DEFINE(
mp_object, array_item, map_item, kv
);
const auto rule = mp_object;
} // namespace detail
template <typename Iterator, typename Visitor>
inline bool parse(Iterator&& begin, Iterator&& end, Visitor&& vis) {
auto data = detail::make_app_specific(std::forward<Visitor>(vis));
return detail::x3::parse(
std::forward<Iterator>(begin),
std::forward<Iterator>(end),
detail::x3::with<detail::tag_app_specific>(std::ref(data))[detail::rule]
);
}
/// @cond
} // MSGPACK_API_VERSION_NAMESPACE(v2)
/// @endcond
} // namespace msgpack
#if __GNUC__ >= 4
#pragma GCC diagnostic pop
#endif // __GNUC__ >= 4
#else // BOOST_VERSION >= 106100
#error Boost 1.61.0 or later is required to use x3 parse
#endif // BOOST_VERSION >= 106100
#endif // defined(MSGPACK_USE_X3_PARSE)
#endif // MSGPACK_V2_X3_PARSE_HPP

View File

@ -0,0 +1,119 @@
//
// MessagePack for C++ deserializing routine
//
// Copyright (C) 2017 KONDO Takatoshi
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef MSGPACK_V2_X3_UNPACK_HPP
#define MSGPACK_V2_X3_UNPACK_HPP
#if defined(MSGPACK_USE_X3_PARSE)
#include <boost/version.hpp>
#if BOOST_VERSION >= 106100
#include "msgpack/versioning.hpp"
#include "msgpack/v2/create_object_visitor.hpp"
#include "msgpack/v2/x3_parse.hpp"
namespace msgpack {
/// @cond
MSGPACK_API_VERSION_NAMESPACE(v2) {
/// @endcond
namespace detail {
template <typename Iterator>
inline void
unpack_imp(Iterator&& begin, Iterator&& end,
msgpack::zone& result_zone, msgpack::object& result, bool& referenced,
unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR,
unpack_limit const& limit = unpack_limit())
{
create_object_visitor v(f, user_data, limit);
v.set_zone(result_zone);
referenced = false;
v.set_referenced(referenced);
if (!parse(std::forward<Iterator>(begin), std::forward<Iterator>(end), v)) {
throw msgpack::parse_error("parse error");
}
referenced = v.referenced();
result = v.data();
}
} // namespace detail
template <typename Iterator>
inline msgpack::object_handle unpack(
Iterator&& begin, Iterator&& end,
bool& referenced,
unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR,
unpack_limit const& limit = unpack_limit())
{
msgpack::object obj;
msgpack::unique_ptr<msgpack::zone> z(new msgpack::zone);
referenced = false;
detail::unpack_imp(
std::forward<Iterator>(begin), std::forward<Iterator>(end), *z, obj, referenced, f, user_data, limit);
return msgpack::object_handle(obj, msgpack::move(z));
}
template <typename Iterator>
inline msgpack::object_handle unpack(
Iterator&& begin, Iterator&& end,
unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR,
unpack_limit const& limit = unpack_limit())
{
bool referenced;
return unpack(std::forward<Iterator>(begin), std::forward<Iterator>(end), referenced, f, user_data, limit);
}
template <typename Iterator>
inline msgpack::object unpack(
msgpack::zone& z,
Iterator&& begin, Iterator&& end,
bool& referenced,
unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR,
unpack_limit const& limit = unpack_limit())
{
msgpack::object obj;
referenced = false;
detail::unpack_imp(
std::forward<Iterator>(begin), std::forward<Iterator>(end), z, obj, referenced, f, user_data, limit);
return obj;
}
template <typename Iterator>
inline msgpack::object unpack(
msgpack::zone& z,
Iterator&& begin, Iterator&& end,
unpack_reference_func f = MSGPACK_NULLPTR, void* user_data = MSGPACK_NULLPTR,
unpack_limit const& limit = unpack_limit())
{
bool referenced;
return unpack(
z, std::forward<Iterator>(begin), std::forward<Iterator>(end), referenced, f, user_data, limit);
}
/// @cond
} // MSGPACK_API_VERSION_NAMESPACE(v2)
/// @endcond
} // namespace msgpack
#else // BOOST_VERSION >= 106100
#error Boost 1.61.0 or later is required to use x3 parse
#endif // BOOST_VERSION >= 106100
#endif // defined(MSGPACK_USE_X3_PARSE)
#endif // MSGPACK_V2_X3_UNPACK_HPP

View File

@ -48,6 +48,12 @@ IF (MSGPACK_BOOST)
)
ENDIF ()
IF (MSGPACK_USE_X3_PARSE)
LIST (APPEND check_PROGRAMS
msgpack_x3_parse.cpp
)
ENDIF ()
IF (MSGPACK_CXX11)
LIST (APPEND check_PROGRAMS
iterator_cpp11.cpp

829
test/msgpack_x3_parse.cpp Normal file
View File

@ -0,0 +1,829 @@
#include "msgpack.hpp"
#include <sstream>
#include <limits>
#if defined(MSGPACK_USE_X3_PARSE)
#include <gtest/gtest.h>
using namespace std;
const double kEPS = 1e-10;
TEST(MSGPACK_X3_PARSE, nil_t)
{
msgpack::type::nil_t v;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_TRUE(oh.get().is_nil());
}
TEST(MSGPACK_X3_PARSE, bool_false)
{
bool v = false;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<bool>());
}
TEST(MSGPACK_X3_PARSE, bool_true)
{
bool v = true;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<bool>());
}
TEST(MSGPACK_X3_PARSE, positive_fixint_1)
{
uint8_t v = 0;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<uint8_t>());
}
TEST(MSGPACK_X3_PARSE, positive_fixint_2)
{
uint8_t v = 127;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<uint8_t>());
}
TEST(MSGPACK_X3_PARSE, negative_fixint_1)
{
int8_t v = -1;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<int8_t>());
}
TEST(MSGPACK_X3_PARSE, negative_fixint_2)
{
int8_t v = -32;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<int8_t>());
}
TEST(MSGPACK_X3_PARSE, uint8_1)
{
uint8_t v = 128U;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<uint8_t>());
}
TEST(MSGPACK_X3_PARSE, uint8_2)
{
uint8_t v = 0xffU;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<uint8_t>());
}
TEST(MSGPACK_X3_PARSE, uint16_1)
{
uint16_t v = 0x100U;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<uint16_t>());
}
TEST(MSGPACK_X3_PARSE, uint16_2)
{
uint16_t v = 0xffffU;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<uint16_t>());
}
TEST(MSGPACK_X3_PARSE, uint32_1)
{
uint32_t v = 0x10000UL;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<uint32_t>());
}
TEST(MSGPACK_X3_PARSE, uint32_2)
{
uint32_t v = 0xffffffffUL;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<uint32_t>());
}
TEST(MSGPACK_X3_PARSE, uint64_1)
{
uint64_t v = 0x100000000ULL;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<uint64_t>());
}
TEST(MSGPACK_X3_PARSE, uint64_2)
{
uint64_t v = 0xffffffffffffffffULL;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<uint64_t>());
}
TEST(MSGPACK_X3_PARSE, int8_1)
{
int8_t v = 0b11011111;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<int8_t>());
}
TEST(MSGPACK_X3_PARSE, int8_2)
{
int8_t v = 0b10000000;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<int8_t>());
}
TEST(MSGPACK_X3_PARSE, int16_1)
{
int16_t v = 0xff00;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<int16_t>());
}
TEST(MSGPACK_X3_PARSE, int16_2)
{
int16_t v = 0x8000;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<int16_t>());
}
TEST(MSGPACK_X3_PARSE, int32_1)
{
int32_t v = 0xff000000L;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<int32_t>());
}
TEST(MSGPACK_X3_PARSE, int32_2)
{
int32_t v = 0x80000000L;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<int32_t>());
}
TEST(MSGPACK_X3_PARSE, int64_1)
{
int64_t v = 0xff00000000000000LL;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<int64_t>());
}
TEST(MSGPACK_X3_PARSE, int64_2)
{
int64_t v = 0x8000000000000000LL;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<int64_t>());
}
TEST(MSGPACK_X3_PARSE, array_1)
{
std::vector<int> v;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<int> >());
}
TEST(MSGPACK_X3_PARSE, array_2)
{
std::vector<int> v;
std::stringstream ss;
for (int i = 0; i != 0xffU; ++i) v.push_back(i);
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<int> >());
}
TEST(MSGPACK_X3_PARSE, array_3)
{
std::vector<int> v;
std::stringstream ss;
for (int i = 0; i != 0xffU+1U; ++i) v.push_back(i);
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<int> >());
}
TEST(MSGPACK_X3_PARSE, array_4)
{
std::vector<int> v;
std::stringstream ss;
for (int i = 0; i != 0xffffU; ++i) v.push_back(i);
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<int> >());
}
TEST(MSGPACK_X3_PARSE, array_5)
{
std::vector<uint32_t> v;
std::stringstream ss;
for (uint32_t i = 0; i != 0xffffU+1U; ++i) v.push_back(i);
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<uint32_t> >());
}
TEST(MSGPACK_X3_PARSE, map_1)
{
std::map<int, int> v;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, (oh.get().as<std::map<int, int> >()));
}
TEST(MSGPACK_X3_PARSE, map_2)
{
std::map<int, int> v;
std::stringstream ss;
for (int i = 0; i != 0xffU; ++i) v.emplace(i, i);
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, (oh.get().as<std::map<int, int> >()));
}
TEST(MSGPACK_X3_PARSE, map_3)
{
std::map<int, int> v;
std::stringstream ss;
for (int i = 0; i != 0xffU+1U; ++i) v.emplace(i, i);
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, (oh.get().as<std::map<int, int> >()));
}
TEST(MSGPACK_X3_PARSE, map_4)
{
std::map<int, int> v;
std::stringstream ss;
for (int i = 0; i != 0xffffU; ++i) v.emplace(i, i);
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, (oh.get().as<std::map<int, int> >()));
}
TEST(MSGPACK_X3_PARSE, map_5)
{
std::map<uint32_t, uint32_t> v;
std::stringstream ss;
for (uint32_t i = 0; i != 0xffffU+1U; ++i) v.emplace(i, i);
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, (oh.get().as<std::map<uint32_t, uint32_t> >()));
}
TEST(MSGPACK_X3_PARSE, float_1)
{
std::vector<float> v;
v.push_back(0.0);
v.push_back(-0.0);
v.push_back(1.0);
v.push_back(-1.0);
v.push_back(numeric_limits<float>::min());
v.push_back(numeric_limits<float>::max());
v.push_back(nanf("tag"));
if (numeric_limits<float>::has_infinity) {
v.push_back(numeric_limits<float>::infinity());
v.push_back(-numeric_limits<float>::infinity());
}
if (numeric_limits<float>::has_quiet_NaN) {
v.push_back(numeric_limits<float>::quiet_NaN());
}
if (numeric_limits<float>::has_signaling_NaN) {
v.push_back(numeric_limits<float>::signaling_NaN());
}
for (unsigned int i = 0; i < v.size() ; i++) {
std::stringstream ss;
float val1 = v[i];
msgpack::pack(ss, val1);
msgpack::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
float val2 = oh.get().as<float>();
if (std::isnan(val1))
EXPECT_TRUE(std::isnan(val2));
else if (std::isinf(val1))
EXPECT_TRUE(std::isinf(val2));
else
EXPECT_TRUE(fabs(val2 - val1) <= kEPS);
}
}
TEST(MSGPACK_X3_PARSE, double_1)
{
std::vector<double> v;
v.push_back(0.0);
v.push_back(-0.0);
v.push_back(1.0);
v.push_back(-1.0);
v.push_back(numeric_limits<double>::min());
v.push_back(numeric_limits<double>::max());
v.push_back(nanf("tag"));
if (numeric_limits<double>::has_infinity) {
v.push_back(numeric_limits<double>::infinity());
v.push_back(-numeric_limits<double>::infinity());
}
if (numeric_limits<double>::has_quiet_NaN) {
v.push_back(numeric_limits<double>::quiet_NaN());
}
if (numeric_limits<double>::has_signaling_NaN) {
v.push_back(numeric_limits<double>::signaling_NaN());
}
for (unsigned int i = 0; i < v.size() ; i++) {
std::stringstream ss;
double val1 = v[i];
msgpack::pack(ss, val1);
msgpack::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
double val2 = oh.get().as<double>();
if (std::isnan(val1))
EXPECT_TRUE(std::isnan(val2));
else if (std::isinf(val1))
EXPECT_TRUE(std::isinf(val2));
else
EXPECT_TRUE(fabs(val2 - val1) <= kEPS);
}
}
TEST(MSGPACK_X3_PARSE, string_1)
{
std::string v;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::string>());
}
TEST(MSGPACK_X3_PARSE, string_2)
{
std::string v;
for (uint64_t i = 0; i != 0x1fU; ++i) v.push_back('0'+(i%10));
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::string>());
}
TEST(MSGPACK_X3_PARSE, string_3)
{
std::string v;
for (uint64_t i = 0; i != 0xffU; ++i) v.push_back('0'+(i%10));
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::string>());
}
TEST(MSGPACK_X3_PARSE, string_4)
{
std::string v;
for (uint64_t i = 0; i != 0xffU+1U; ++i) v.push_back('0'+(i%10));
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::string>());
}
TEST(MSGPACK_X3_PARSE, string_5)
{
std::string v;
for (uint64_t i = 0; i != 0xffffU; ++i) v.push_back('0'+(i%10));
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::string>());
}
TEST(MSGPACK_X3_PARSE, string_6)
{
std::string v;
for (uint64_t i = 0; i != 0xffffUL + 1UL; ++i) v.push_back('0'+(i%10));
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::string>());
}
TEST(MSGPACK_X3_PARSE, bin_1)
{
std::vector<char> v;
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<char>>());
}
TEST(MSGPACK_X3_PARSE, bin_2)
{
std::vector<char> v;
for (uint64_t i = 0; i != 0x1fU; ++i) v.push_back(i%0xff);
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<char>>());
}
TEST(MSGPACK_X3_PARSE, bin_3)
{
std::vector<char> v;
for (uint64_t i = 0; i != 0xffU; ++i) v.push_back(i%0xff);
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<char>>());
}
TEST(MSGPACK_X3_PARSE, bin_4)
{
std::vector<char> v;
for (uint64_t i = 0; i != 0xffU+1U; ++i) v.push_back(i%0xff);
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<char>>());
}
TEST(MSGPACK_X3_PARSE, bin_5)
{
std::vector<char> v;
for (uint64_t i = 0; i != 0xffffU; ++i) v.push_back(i%0xff);
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<char>>());
}
TEST(MSGPACK_X3_PARSE, bin_6)
{
std::vector<char> v;
for (uint64_t i = 0; i != 0xffffUL + 1UL; ++i) v.push_back(i%0xff);
std::stringstream ss;
msgpack::pack(ss, v);
auto oh = msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(v, oh.get().as<std::vector<char>>());
}
TEST(MSGPACK_X3_PARSE, fixext1)
{
std::stringstream ss;
msgpack::packer<std::stringstream> packer(ss);
char const buf [] = { 2 };
packer.pack_ext(sizeof(buf), 1);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(1ul, oh.get().via.ext.size);
EXPECT_EQ(1, oh.get().via.ext.type());
EXPECT_EQ(2, oh.get().via.ext.data()[0]);
}
TEST(MSGPACK_X3_PARSE, fixext2)
{
std::stringstream ss;
msgpack::packer<std::stringstream> packer(ss);
char const buf [] = { 2, 3 };
packer.pack_ext(sizeof(buf), 0);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(2ul, oh.get().via.ext.size);
EXPECT_EQ(0, oh.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), oh.get().via.ext.data()));
}
TEST(MSGPACK_X3_PARSE, fixext4)
{
std::stringstream ss;
msgpack::packer<std::stringstream> packer(ss);
char const buf [] = { 2, 3, 4, 5 };
packer.pack_ext(sizeof(buf), 1);
packer.pack_ext_body(buf, sizeof(buf));
msgpack::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(4ul, oh.get().via.ext.size);
EXPECT_EQ(1, oh.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), oh.get().via.ext.data()));
}
TEST(MSGPACK_X3_PARSE, fixext8)
{
std::stringstream ss;
msgpack::packer<std::stringstream> packer(ss);
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::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(8ul, oh.get().via.ext.size);
EXPECT_EQ(1, oh.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), oh.get().via.ext.data()));
}
TEST(MSGPACK_X3_PARSE, fixext16)
{
std::stringstream ss;
msgpack::packer<std::stringstream> packer(ss);
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::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(16ul, oh.get().via.ext.size);
EXPECT_EQ(1, oh.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), oh.get().via.ext.data()));
}
TEST(MSGPACK_X3_PARSE, ext_0)
{
std::size_t const size = 0;
std::stringstream ss;
msgpack::packer<std::stringstream> packer(ss);
packer.pack_ext(size, 77);
msgpack::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(size, oh.get().via.ext.size);
EXPECT_EQ(77, oh.get().via.ext.type());
}
TEST(MSGPACK_X3_PARSE, ext_255)
{
std::size_t const size = 255;
std::stringstream ss;
msgpack::packer<std::stringstream> packer(ss);
char buf[size];
for (std::size_t 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::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(size, oh.get().via.ext.size);
EXPECT_EQ(77, oh.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), oh.get().via.ext.data()));
}
TEST(MSGPACK_X3_PARSE, ext_256)
{
std::size_t const size = 256;
std::stringstream ss;
msgpack::packer<std::stringstream> packer(ss);
char buf[size];
for (std::size_t 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::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(size, oh.get().via.ext.size);
EXPECT_EQ(77, oh.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), oh.get().via.ext.data()));
}
TEST(MSGPACK_X3_PARSE, ext_65535)
{
std::size_t const size = 65535;
std::stringstream ss;
msgpack::packer<std::stringstream> packer(ss);
char buf[size];
for (std::size_t 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::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(size, oh.get().via.ext.size);
EXPECT_EQ(77, oh.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), oh.get().via.ext.data()));
}
TEST(MSGPACK_X3_PARSE, ext_65536)
{
std::size_t const size = 65536;
std::stringstream ss;
msgpack::packer<std::stringstream> packer(ss);
char buf[size];
for (std::size_t 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::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end());
EXPECT_EQ(size, oh.get().via.ext.size);
EXPECT_EQ(77, oh.get().via.ext.type());
EXPECT_TRUE(
std::equal(buf, buf + sizeof(buf), oh.get().via.ext.data()));
}
TEST(MSGPACK_X3_PARSE, unpack_referenced_1)
{
std::string v = "ABC";
std::stringstream ss;
msgpack::pack(ss, v);
bool r;
msgpack::object_handle oh =
msgpack::unpack(ss.str().begin(), ss.str().end(), r);
EXPECT_FALSE(r);
EXPECT_EQ(v, oh.get().as<std::string>());
}
TEST(MSGPACK_X3_PARSE, unpack_referenced_2)
{
std::string v = "ABC";
std::stringstream ss;
msgpack::pack(ss, v);
// copy is required because ss.str() returns temporary object.
std::string str = ss.str();
bool r;
msgpack::object_handle oh =
msgpack::unpack(
str.begin(),
str.end(),
r,
[](msgpack::type::object_type, std::size_t, void*) {
return true;
}
);
EXPECT_TRUE(r);
EXPECT_EQ(v, oh.get().as<std::string>());
}
TEST(MSGPACK_X3_PARSE, unpack_zone_1)
{
std::string v = "ABC";
std::stringstream ss;
msgpack::pack(ss, v);
msgpack::zone z;
msgpack::object obj =
msgpack::unpack(z, ss.str().begin(), ss.str().end());
EXPECT_EQ(v, obj.as<std::string>());
}
TEST(MSGPACK_X3_PARSE, unpack_zone_2)
{
std::string v = "ABC";
std::stringstream ss;
msgpack::pack(ss, v);
msgpack::zone z;
bool r;
msgpack::object obj =
msgpack::unpack(z, ss.str().begin(), ss.str().end(), r);
EXPECT_EQ(v, obj.as<std::string>());
EXPECT_FALSE(r);
EXPECT_EQ(v, obj.as<std::string>());
}
TEST(MSGPACK_X3_PARSE, unpack_zone_3)
{
std::string v = "ABC";
std::stringstream ss;
msgpack::pack(ss, v);
// copy is required because ss.str() returns temporary object.
std::string str = ss.str();
msgpack::zone z;
bool r;
msgpack::object obj =
msgpack::unpack(
z,
str.begin(),
str.end(),
r,
[](msgpack::type::object_type, std::size_t, void*) {
return true;
}
);
EXPECT_TRUE(r);
EXPECT_EQ(v, obj.as<std::string>());
}
#endif // defined(MSGPACK_USE_X3_PARSE)