mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-05-19 12:49:08 +02:00
Added new example.
This commit is contained in:
parent
4466bda819
commit
c704d4bfab
@ -88,20 +88,25 @@ IF (MSGPACK_32BIT)
|
|||||||
ENDIF ()
|
ENDIF ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
OPTION (MSGPACK_BUILD_EXAMPLES "Build msgpack examples." ON)
|
||||||
|
|
||||||
IF (MSGPACK_BOOST)
|
IF (MSGPACK_BOOST)
|
||||||
SET (CMAKE_CXX_FLAGS "-DMSGPACK_USE_BOOST ${CMAKE_CXX_FLAGS}")
|
SET (CMAKE_CXX_FLAGS "-DMSGPACK_USE_BOOST ${CMAKE_CXX_FLAGS}")
|
||||||
SET (Boost_USE_STATIC_LIBS ON) # only find static libs
|
ENDIF ()
|
||||||
SET (Boost_USE_MULTITHREADED ON)
|
|
||||||
SET (Boost_USE_STATIC_RUNTIME OFF)
|
SET (Boost_USE_STATIC_LIBS ON) # only find static libs
|
||||||
FIND_PACKAGE (Boost COMPONENTS chrono timer system)
|
SET (Boost_USE_MULTITHREADED ON)
|
||||||
IF (Boost_INCLUDE_DIRS)
|
SET (Boost_USE_STATIC_RUNTIME OFF)
|
||||||
INCLUDE_DIRECTORIES (
|
FIND_PACKAGE (Boost COMPONENTS chrono context timer system)
|
||||||
${Boost_INCLUDE_DIRS}
|
IF (Boost_INCLUDE_DIRS)
|
||||||
)
|
INCLUDE_DIRECTORIES (
|
||||||
ENDIF ()
|
${Boost_INCLUDE_DIRS}
|
||||||
INCLUDE_DIRECTORIES (
|
)
|
||||||
${MSGPACK_BOOST_DIR}
|
ENDIF ()
|
||||||
)
|
IF (MSGPACK_BOOST_DIR)
|
||||||
|
INCLUDE_DIRECTORIES (
|
||||||
|
${MSGPACK_BOOST_DIR}
|
||||||
|
)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (MSGPACK_CHAR_SIGN)
|
IF (MSGPACK_CHAR_SIGN)
|
||||||
@ -141,7 +146,6 @@ FIND_PACKAGE (Threads)
|
|||||||
IF (GTEST_FOUND AND ZLIB_FOUND AND THREADS_FOUND)
|
IF (GTEST_FOUND AND ZLIB_FOUND AND THREADS_FOUND)
|
||||||
OPTION (MSGPACK_BUILD_TESTS "Build msgpack tests." ON)
|
OPTION (MSGPACK_BUILD_TESTS "Build msgpack tests." ON)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
OPTION (MSGPACK_BUILD_EXAMPLES "Build msgpack examples." ON)
|
|
||||||
|
|
||||||
OPTION (MSGPACK_ENABLE_CXX "Enable C++ interface." ON)
|
OPTION (MSGPACK_ENABLE_CXX "Enable C++ interface." ON)
|
||||||
OPTION (MSGPACK_ENABLE_SHARED "Build shared libaries in addition to static libraries." ON)
|
OPTION (MSGPACK_ENABLE_SHARED "Build shared libaries in addition to static libraries." ON)
|
||||||
|
@ -2,3 +2,4 @@ ADD_SUBDIRECTORY (c)
|
|||||||
ADD_SUBDIRECTORY (cpp03)
|
ADD_SUBDIRECTORY (cpp03)
|
||||||
ADD_SUBDIRECTORY (cpp11)
|
ADD_SUBDIRECTORY (cpp11)
|
||||||
ADD_SUBDIRECTORY (boost)
|
ADD_SUBDIRECTORY (boost)
|
||||||
|
ADD_SUBDIRECTORY (x3)
|
||||||
|
@ -22,13 +22,11 @@ IF (NOT MSVC)
|
|||||||
)
|
)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (MSGPACK_BOOST)
|
IF (Boost_TIMER_LIBRARY AND Boost_CHRONO_LIBRARY AND Boost_SYSTEM_LIBRARY)
|
||||||
IF (NOT MSVC)
|
LIST (APPEND with_boost_lib_PROGRAMS
|
||||||
LIST (APPEND with_boost_lib_PROGRAMS
|
speed_test.cpp
|
||||||
speed_test.cpp
|
speed_test_nested_array.cpp
|
||||||
speed_test_nested_array.cpp
|
)
|
||||||
)
|
|
||||||
ENDIF ()
|
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
FOREACH (source_file ${exec_PROGRAMS})
|
FOREACH (source_file ${exec_PROGRAMS})
|
||||||
@ -56,10 +54,10 @@ FOREACH (source_file ${with_pthread_PROGRAMS})
|
|||||||
${source_file}
|
${source_file}
|
||||||
)
|
)
|
||||||
TARGET_LINK_LIBRARIES (${source_file_we}
|
TARGET_LINK_LIBRARIES (${source_file_we}
|
||||||
pthread
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
)
|
)
|
||||||
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
SET_PROPERTY (TARGET ${source_file_we} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Werror -g -O3 -pthread")
|
SET_PROPERTY (TARGET ${source_file_we} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Werror -g -O3")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
IF (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
IF (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||||
|
64
example/x3/CMakeLists.txt
Normal file
64
example/x3/CMakeLists.txt
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
IF (MSGPACK_USE_X3_PARSE)
|
||||||
|
INCLUDE_DIRECTORIES (
|
||||||
|
../include
|
||||||
|
)
|
||||||
|
|
||||||
|
LIST (APPEND exec_PROGRAMS
|
||||||
|
unpack.cpp
|
||||||
|
parse.cpp
|
||||||
|
)
|
||||||
|
IF (Boost_CONTEXT_LIBRARY AND Boost_SYSTEM_LIBRARY AND CMAKE_THREAD_LIBS_INIT)
|
||||||
|
LIST (APPEND with_boost_PROGRAMS
|
||||||
|
stream_unpack.cpp
|
||||||
|
)
|
||||||
|
ENDIF ()
|
||||||
|
FOREACH (source_file ${exec_PROGRAMS})
|
||||||
|
GET_FILENAME_COMPONENT (source_file_we ${source_file} NAME_WE)
|
||||||
|
ADD_EXECUTABLE (
|
||||||
|
${source_file_we}
|
||||||
|
${source_file}
|
||||||
|
)
|
||||||
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
|
SET_PROPERTY (TARGET ${source_file_we} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Werror -g ")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
SET_PROPERTY (TARGET ${source_file_we} APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-mismatched-tags")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
IF (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||||
|
STRING(REGEX REPLACE "/W[0-4]" "/W3 /WX" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
ELSE ()
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX")
|
||||||
|
ENDIF ()
|
||||||
|
ENDIF ()
|
||||||
|
ENDFOREACH ()
|
||||||
|
FOREACH (source_file ${with_boost_PROGRAMS})
|
||||||
|
GET_FILENAME_COMPONENT (source_file_we ${source_file} NAME_WE)
|
||||||
|
ADD_EXECUTABLE (
|
||||||
|
${source_file_we}
|
||||||
|
${source_file}
|
||||||
|
)
|
||||||
|
TARGET_LINK_LIBRARIES (${source_file_we}
|
||||||
|
${Boost_CONTEXT_LIBRARY}
|
||||||
|
${Boost_SYSTEM_LIBRARY}
|
||||||
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
|
)
|
||||||
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
|
SET_PROPERTY (TARGET ${source_file_we} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Werror -g ")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
SET_PROPERTY (TARGET ${source_file_we} APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-mismatched-tags")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
IF (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||||
|
STRING(REGEX REPLACE "/W[0-4]" "/W3 /WX" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
ELSE ()
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX")
|
||||||
|
ENDIF ()
|
||||||
|
ENDIF ()
|
||||||
|
ENDFOREACH ()
|
||||||
|
ENDIF ()
|
119
example/x3/parse.cpp
Normal file
119
example/x3/parse.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// MessagePack for C++ example
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// MSGPACK_USE_X3_PARSE should be defined before including msgpack.hpp
|
||||||
|
// It usually defined as a compiler option as -DMSGPACK_USE_X3_PARSE.
|
||||||
|
|
||||||
|
#include <msgpack.hpp>
|
||||||
|
|
||||||
|
struct json_like_visitor : msgpack::v2::null_visitor {
|
||||||
|
json_like_visitor(std::string& s):m_s(s) {}
|
||||||
|
|
||||||
|
bool visit_nil() {
|
||||||
|
m_s += "null";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool visit_boolean(bool v) {
|
||||||
|
if (v) m_s += "true";
|
||||||
|
else m_s += "false";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool visit_positive_integer(uint64_t v) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
m_s += ss.str();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool visit_negative_integer(int64_t v) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
m_s += ss.str();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool visit_float(double v) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << v;
|
||||||
|
m_s += ss.str();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool visit_str(const char* v, uint32_t size) {
|
||||||
|
m_s += '"' + std::string(v, size) + '"';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool start_array(uint32_t /*num_elements*/) {
|
||||||
|
m_s += "[";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool end_array_item() {
|
||||||
|
m_s += ",";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool end_array() {
|
||||||
|
m_s.erase(m_s.size() - 1, 1); // remove the last ','
|
||||||
|
m_s += "]";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool start_map(uint32_t /*num_kv_pairs*/) {
|
||||||
|
m_s += "{";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool end_map_key() {
|
||||||
|
m_s += ":";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool end_map_value() {
|
||||||
|
m_s += ",";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool end_map() {
|
||||||
|
m_s.erase(m_s.size() - 1, 1); // remove the last ','
|
||||||
|
m_s += "}";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void parse_error(size_t /*parsed_offset*/, size_t /*error_offset*/) {
|
||||||
|
}
|
||||||
|
void insufficient_bytes(size_t /*parsed_offset*/, size_t /*error_offset*/) {
|
||||||
|
}
|
||||||
|
std::string& m_s;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::stringstream ss;
|
||||||
|
std::map<std::string, std::vector<int>> v1 {
|
||||||
|
{ "ABC", { 1, 2, 3 } },
|
||||||
|
{ "DEFG", { 4, 5 } }
|
||||||
|
};
|
||||||
|
std::vector<std::string> v2 {
|
||||||
|
"HIJ", "KLM", "NOP"
|
||||||
|
};
|
||||||
|
msgpack::pack(ss, v1);
|
||||||
|
msgpack::pack(ss, v2);
|
||||||
|
|
||||||
|
std::string const& buf = ss.str();
|
||||||
|
auto it = buf.begin();
|
||||||
|
auto end = buf.end();
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
bool ret = msgpack::parse(it, end, json_like_visitor(str));
|
||||||
|
// it is updated here.
|
||||||
|
assert(ret);
|
||||||
|
std::cout << str << std::endl;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
bool ret = msgpack::parse(it, end, json_like_visitor(str));
|
||||||
|
// it is updated here.
|
||||||
|
assert(ret);
|
||||||
|
std::cout << str << std::endl;
|
||||||
|
}
|
||||||
|
}
|
239
example/x3/stream_unpack.cpp
Normal file
239
example/x3/stream_unpack.cpp
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
// MessagePack for C++ example
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cassert>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
// MSGPACK_USE_X3_PARSE should be defined before including msgpack.hpp
|
||||||
|
// It usually defined as a compiler option as -DMSGPACK_USE_X3_PARSE.
|
||||||
|
|
||||||
|
//#define MSGPACK_USE_X3_PARSE
|
||||||
|
|
||||||
|
#include <msgpack.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/coroutine2/all.hpp>
|
||||||
|
#include <boost/spirit/home/support/multi_pass.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace as = boost::asio;
|
||||||
|
namespace x3 = boost::spirit::x3;
|
||||||
|
namespace coro2 = boost::coroutines2;
|
||||||
|
|
||||||
|
using pull_type = coro2::asymmetric_coroutine<std::shared_ptr<std::vector<char>>>::pull_type;
|
||||||
|
|
||||||
|
// iterator fetching data from coroutine2.
|
||||||
|
class buffered_iterator : public std::iterator<std::input_iterator_tag, char> {
|
||||||
|
public:
|
||||||
|
using pointer_t = typename iterator::pointer;
|
||||||
|
using reference_t = typename iterator::reference;
|
||||||
|
|
||||||
|
explicit buffered_iterator(pull_type& source) noexcept
|
||||||
|
: source_{ &source } {
|
||||||
|
fetch_();
|
||||||
|
}
|
||||||
|
buffered_iterator() = default;
|
||||||
|
|
||||||
|
bool operator==(buffered_iterator const& other) const noexcept {
|
||||||
|
if (!other.source_ && !source_ && !other.buf_ && !buf_) return true;
|
||||||
|
return other.it_ == it_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(buffered_iterator const& other) const noexcept {
|
||||||
|
return !(other == *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffered_iterator & operator++() {
|
||||||
|
increment_();
|
||||||
|
return * this;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffered_iterator operator++(int) = delete;
|
||||||
|
|
||||||
|
reference_t operator*() noexcept {
|
||||||
|
return *it_;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer_t operator->() noexcept {
|
||||||
|
return std::addressof(*it_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void fetch_() noexcept {
|
||||||
|
BOOST_ASSERT( nullptr != source_);
|
||||||
|
if (*source_) {
|
||||||
|
buf_ = source_->get();
|
||||||
|
it_ = buf_->begin();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
source_ = nullptr;
|
||||||
|
buf_.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment_() {
|
||||||
|
BOOST_ASSERT( nullptr != source_);
|
||||||
|
BOOST_ASSERT(*source_);
|
||||||
|
if (++it_ == buf_->end()) {
|
||||||
|
(*source_)();
|
||||||
|
fetch_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
pull_type* source_{ nullptr };
|
||||||
|
std::shared_ptr<std::vector<char>> buf_;
|
||||||
|
std::vector<char>::iterator it_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// session class that corresponding to each client
|
||||||
|
class session : public std::enable_shared_from_this<session> {
|
||||||
|
public:
|
||||||
|
session(as::ip::tcp::socket socket)
|
||||||
|
: socket_(std::move(socket)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
sink_ = std::make_shared<coro2::asymmetric_coroutine<std::shared_ptr<std::vector<char>>>::push_type>(
|
||||||
|
[&, this](pull_type& source) {
|
||||||
|
// *1 is started when the first sink is called.
|
||||||
|
|
||||||
|
std::cout << "session started" << std::endl;
|
||||||
|
do_read();
|
||||||
|
source();
|
||||||
|
|
||||||
|
// use buffered_iterator here
|
||||||
|
// b is incremented in msgpack::unpack() and fetch data from sink
|
||||||
|
// via coroutine2 mechanism
|
||||||
|
auto b = boost::spirit::make_default_multi_pass(buffered_iterator(source));
|
||||||
|
auto e = boost::spirit::make_default_multi_pass(buffered_iterator());
|
||||||
|
|
||||||
|
// This is usually an infinity look, but for test, loop is finished when
|
||||||
|
// two message pack data is processed.
|
||||||
|
for (int i = 0; i != 2; ++i) {
|
||||||
|
auto oh = msgpack::unpack(b, e);
|
||||||
|
std::cout << oh.get() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// send dummy data to start *1
|
||||||
|
(*sink_)({});
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void do_read() {
|
||||||
|
std::cout << "session do_read() is called" << std::endl;
|
||||||
|
auto self(shared_from_this());
|
||||||
|
auto data = std::make_shared<std::vector<char>>(static_cast<std::size_t>(max_length));
|
||||||
|
socket_.async_read_some(
|
||||||
|
boost::asio::buffer(*data),
|
||||||
|
[this, self, data]
|
||||||
|
(boost::system::error_code ec, std::size_t length) {
|
||||||
|
if (!ec) {
|
||||||
|
data->resize(length);
|
||||||
|
(*sink_)(data);
|
||||||
|
do_read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
as::ip::tcp::socket socket_;
|
||||||
|
static constexpr std::size_t const max_length = 1024;
|
||||||
|
std::shared_ptr<coro2::asymmetric_coroutine<std::shared_ptr<std::vector<char>>>::push_type> sink_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class server {
|
||||||
|
public:
|
||||||
|
server(
|
||||||
|
as::io_service& ios,
|
||||||
|
std::uint16_t port)
|
||||||
|
: acceptor_(ios, as::ip::tcp::endpoint(as::ip::tcp::v4(), port)),
|
||||||
|
socket_(ios) {
|
||||||
|
do_accept();
|
||||||
|
std::cout << "server start accept" << std::endl;
|
||||||
|
ios.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void do_accept() {
|
||||||
|
acceptor_.async_accept(
|
||||||
|
socket_,
|
||||||
|
[this](boost::system::error_code ec) {
|
||||||
|
if (!ec) {
|
||||||
|
std::make_shared<session>(std::move(socket_))->start();
|
||||||
|
}
|
||||||
|
// for test, only one session is accepted.
|
||||||
|
// do_accept();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
as::ip::tcp::acceptor acceptor_;
|
||||||
|
as::ip::tcp::socket socket_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::thread srv(
|
||||||
|
[]{
|
||||||
|
boost::asio::io_service ios;
|
||||||
|
server s(ios, 12345);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
std::thread cli(
|
||||||
|
[]{
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
std::cout << "client start" << std::endl;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
std::map<std::string, std::vector<int>> v1 {
|
||||||
|
{ "ABC", { 1, 2, 3 } },
|
||||||
|
{ "DEFG", { 4, 5 } }
|
||||||
|
};
|
||||||
|
std::vector<std::string> v2 {
|
||||||
|
"HIJ", "KLM", "NOP"
|
||||||
|
};
|
||||||
|
msgpack::pack(ss, v1);
|
||||||
|
msgpack::pack(ss, v2);
|
||||||
|
|
||||||
|
auto send_data = ss.str();
|
||||||
|
|
||||||
|
boost::asio::io_service ios;
|
||||||
|
as::ip::tcp::resolver::query q("127.0.0.1", "12345");
|
||||||
|
as::ip::tcp::resolver r(ios);
|
||||||
|
auto it = r.resolve(q);
|
||||||
|
|
||||||
|
std::cout << "client connect" << std::endl;
|
||||||
|
as::ip::tcp::socket s(ios);
|
||||||
|
as::connect(s, it);
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t const size = 5;
|
||||||
|
std::size_t rest = send_data.size();
|
||||||
|
std::size_t index = 0;
|
||||||
|
while (rest != 0) {
|
||||||
|
std::cout << "client send data" << std::endl;
|
||||||
|
auto send_size = size < rest ? size : rest;
|
||||||
|
as::write(s, as::buffer(&send_data[index], send_size));
|
||||||
|
rest -= send_size;
|
||||||
|
index += send_size;
|
||||||
|
std::cout << "client wait" << std::endl;
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
cli.join();
|
||||||
|
std::cout << "client joinded" << std::endl;
|
||||||
|
srv.join();
|
||||||
|
std::cout << "server joinded" << std::endl;
|
||||||
|
}
|
43
example/x3/unpack.cpp
Normal file
43
example/x3/unpack.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// MessagePack for C++ example
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// MSGPACK_USE_X3_PARSE should be defined before including msgpack.hpp
|
||||||
|
// It usually defined as a compiler option as -DMSGPACK_USE_X3_PARSE.
|
||||||
|
|
||||||
|
#include <msgpack.hpp>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::stringstream ss;
|
||||||
|
std::map<std::string, std::vector<int>> v1 {
|
||||||
|
{ "ABC", { 1, 2, 3 } },
|
||||||
|
{ "DEFG", { 4, 5 } }
|
||||||
|
};
|
||||||
|
std::vector<std::string> v2 {
|
||||||
|
"HIJ", "KLM", "NOP"
|
||||||
|
};
|
||||||
|
msgpack::pack(ss, v1);
|
||||||
|
msgpack::pack(ss, v2);
|
||||||
|
|
||||||
|
std::string const& buf = ss.str();
|
||||||
|
auto it = buf.begin();
|
||||||
|
auto end = buf.end();
|
||||||
|
{
|
||||||
|
auto oh = msgpack::unpack(it, end);
|
||||||
|
// it is updated here.
|
||||||
|
assert(v1 == (oh.get().as<std::map<std::string, std::vector<int>>>()));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto oh = msgpack::unpack(it, end);
|
||||||
|
assert(v2 == oh.get().as<std::vector<std::string>>());
|
||||||
|
}
|
||||||
|
}
|
@ -332,7 +332,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -340,7 +340,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& str = _attr(ctx);
|
auto const& str = _attr(ctx);
|
||||||
app_specific.vis.visit_str(str.size() ? &str[0] : nullptr, str.size());
|
std::size_t size = std::distance(str.begin(), str.end());
|
||||||
|
app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -355,7 +356,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -363,7 +364,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& str = _attr(ctx);
|
auto const& str = _attr(ctx);
|
||||||
app_specific.vis.visit_str(str.size() ? &str[0] : nullptr, str.size());
|
std::size_t size = std::distance(str.begin(), str.end());
|
||||||
|
app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -378,7 +380,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -386,7 +388,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& str = _attr(ctx);
|
auto const& str = _attr(ctx);
|
||||||
app_specific.vis.visit_str(str.size() ? &str[0] : nullptr, str.size());
|
std::size_t size = std::distance(str.begin(), str.end());
|
||||||
|
app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -401,7 +404,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -409,7 +412,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& str = _attr(ctx);
|
auto const& str = _attr(ctx);
|
||||||
app_specific.vis.visit_str(str.size() ? &str[0] : nullptr, str.size());
|
std::size_t size = std::distance(str.begin(), str.end());
|
||||||
|
app_specific.vis.visit_str(size ? &str.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -424,7 +428,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -432,7 +436,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& bin = _attr(ctx);
|
auto const& bin = _attr(ctx);
|
||||||
app_specific.vis.visit_bin(bin.size() ? &bin[0] : nullptr, bin.size());
|
std::size_t size = std::distance(bin.begin(), bin.end());
|
||||||
|
app_specific.vis.visit_bin(size ? &bin.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -447,7 +452,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -455,7 +460,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& bin = _attr(ctx);
|
auto const& bin = _attr(ctx);
|
||||||
app_specific.vis.visit_bin(bin.size() ? &bin[0] : nullptr, bin.size());
|
std::size_t size = std::distance(bin.begin(), bin.end());
|
||||||
|
app_specific.vis.visit_bin(size ? &bin.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -470,7 +476,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -478,7 +484,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& bin = _attr(ctx);
|
auto const& bin = _attr(ctx);
|
||||||
app_specific.vis.visit_bin(bin.size() ? &bin[0] : nullptr, bin.size());
|
std::size_t size = std::distance(bin.begin(), bin.end());
|
||||||
|
app_specific.vis.visit_bin(size ? &bin.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -577,7 +584,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -585,7 +592,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& ext = _attr(ctx);
|
auto const& ext = _attr(ctx);
|
||||||
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
|
std::size_t size = std::distance(ext.begin(), ext.end());
|
||||||
|
app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -600,7 +608,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -608,7 +616,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& ext = _attr(ctx);
|
auto const& ext = _attr(ctx);
|
||||||
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
|
std::size_t size = std::distance(ext.begin(), ext.end());
|
||||||
|
app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -623,7 +632,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -631,7 +640,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& ext = _attr(ctx);
|
auto const& ext = _attr(ctx);
|
||||||
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
|
std::size_t size = std::distance(ext.begin(), ext.end());
|
||||||
|
app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -646,7 +656,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -654,7 +664,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& ext = _attr(ctx);
|
auto const& ext = _attr(ctx);
|
||||||
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
|
std::size_t size = std::distance(ext.begin(), ext.end());
|
||||||
|
app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -669,7 +680,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -677,7 +688,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& ext = _attr(ctx);
|
auto const& ext = _attr(ctx);
|
||||||
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
|
std::size_t size = std::distance(ext.begin(), ext.end());
|
||||||
|
app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -692,7 +704,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -700,7 +712,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& ext = _attr(ctx);
|
auto const& ext = _attr(ctx);
|
||||||
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
|
std::size_t size = std::distance(ext.begin(), ext.end());
|
||||||
|
app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -715,7 +728,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -723,7 +736,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& ext = _attr(ctx);
|
auto const& ext = _attr(ctx);
|
||||||
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
|
std::size_t size = std::distance(ext.begin(), ext.end());
|
||||||
|
app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -738,7 +752,7 @@ const auto mp_object_def =
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
>>
|
>>
|
||||||
x3:: raw [
|
x3::raw [
|
||||||
*(x3::eps [more] >> x3::char_)
|
*(x3::eps [more] >> x3::char_)
|
||||||
>> x3::eps [done]
|
>> x3::eps [done]
|
||||||
][
|
][
|
||||||
@ -746,7 +760,8 @@ const auto mp_object_def =
|
|||||||
[](auto& ctx){
|
[](auto& ctx){
|
||||||
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
auto& app_specific = x3::get<tag_app_specific>(ctx).get();
|
||||||
auto const& ext = _attr(ctx);
|
auto const& ext = _attr(ctx);
|
||||||
app_specific.vis.visit_ext(ext.size() ? &ext[0] : nullptr, ext.size());
|
std::size_t size = std::distance(ext.begin(), ext.end());
|
||||||
|
app_specific.vis.visit_ext(size ? &ext.front() : nullptr, size);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user