diff options
author | Antonio Juarez <antonio.maria.juarez@live.com> | 2014-03-03 22:07:58 +0000 |
---|---|---|
committer | Antonio Juarez <antonio.maria.juarez@live.com> | 2014-03-03 22:07:58 +0000 |
commit | 296ae46ed8f8f6e5f986f978febad302e3df231a (patch) | |
tree | 1629164454a239308f33c9e12afb22e7f3cd8eeb /contrib/epee/demo | |
parent | changed name (diff) | |
download | monero-296ae46ed8f8f6e5f986f978febad302e3df231a.tar.xz |
moved all stuff to github
Diffstat (limited to 'contrib/epee/demo')
-rw-r--r-- | contrib/epee/demo/.gitignore | 1 | ||||
-rw-r--r-- | contrib/epee/demo/CMakeLists.txt | 49 | ||||
-rw-r--r-- | contrib/epee/demo/README.txt | 0 | ||||
-rw-r--r-- | contrib/epee/demo/demo_http_server/demo_http_server.cpp | 217 | ||||
-rw-r--r-- | contrib/epee/demo/demo_http_server/demo_http_server.h | 101 | ||||
-rw-r--r-- | contrib/epee/demo/demo_http_server/stdafx.cpp | 8 | ||||
-rw-r--r-- | contrib/epee/demo/demo_http_server/stdafx.h | 40 | ||||
-rw-r--r-- | contrib/epee/demo/demo_http_server/targetver.h | 13 | ||||
-rw-r--r-- | contrib/epee/demo/demo_levin_server/demo_levin_server.cpp | 200 | ||||
-rw-r--r-- | contrib/epee/demo/demo_levin_server/demo_levin_server.h | 76 | ||||
-rw-r--r-- | contrib/epee/demo/demo_levin_server/stdafx.cpp | 30 | ||||
-rw-r--r-- | contrib/epee/demo/demo_levin_server/stdafx.h | 41 | ||||
-rw-r--r-- | contrib/epee/demo/demo_levin_server/targetver.h | 13 | ||||
-rw-r--r-- | contrib/epee/demo/generate_gcc.sh | 4 | ||||
-rw-r--r-- | contrib/epee/demo/generate_vc_proj.bat | 7 | ||||
-rw-r--r-- | contrib/epee/demo/iface/transport_defs.h | 213 |
16 files changed, 1013 insertions, 0 deletions
diff --git a/contrib/epee/demo/.gitignore b/contrib/epee/demo/.gitignore new file mode 100644 index 000000000..d9b4f015d --- /dev/null +++ b/contrib/epee/demo/.gitignore @@ -0,0 +1 @@ +/build/* diff --git a/contrib/epee/demo/CMakeLists.txt b/contrib/epee/demo/CMakeLists.txt new file mode 100644 index 000000000..b4ac2cc8b --- /dev/null +++ b/contrib/epee/demo/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 2.8) +set(Boost_USE_MULTITHREADED ON) +#set(Boost_DEBUG 1) +find_package(Boost COMPONENTS system filesystem thread date_time chrono regex ) + +include_directories( ${Boost_INCLUDE_DIRS} ) + + +IF (MSVC) + add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /nologo /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /bigobj" ) +ELSE() + # set stuff for other systems + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wno-reorder -D_GNU_SOURCE") +ENDIF() + + +include_directories(.) +include_directories(../include) +include_directories(iface) + + +# Add folders to filters +file(GLOB_RECURSE LEVIN_GENERAL_SECTION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/demo_levin_server/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/demo_levin_server/*.inl + ${CMAKE_CURRENT_SOURCE_DIR}/demo_levin_server/*.cpp) + +file(GLOB_RECURSE HTTP_GENERAL_SECTION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/demo_http_server/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/demo_http_server/*.inl + ${CMAKE_CURRENT_SOURCE_DIR}/demo_http_server/*.cpp) + + + +source_group(general FILES ${LEVIN_GENERAL_SECTION} FILES ${HTTP_GENERAL_SECTION}) +#source_group(general FILES ${HTTP_GENERAL_SECTION}) + +add_executable(demo_http_server ${HTTP_GENERAL_SECTION} ) +add_executable(demo_levin_server ${LEVIN_GENERAL_SECTION} ) + +target_link_libraries( demo_http_server ${Boost_LIBRARIES} ) +target_link_libraries( demo_levin_server ${Boost_LIBRARIES} ) + +IF (NOT WIN32) + target_link_libraries (demo_http_server rt) + target_link_libraries (demo_levin_server rt) +ENDIF() + + diff --git a/contrib/epee/demo/README.txt b/contrib/epee/demo/README.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/contrib/epee/demo/README.txt diff --git a/contrib/epee/demo/demo_http_server/demo_http_server.cpp b/contrib/epee/demo/demo_http_server/demo_http_server.cpp new file mode 100644 index 000000000..f614da6c5 --- /dev/null +++ b/contrib/epee/demo/demo_http_server/demo_http_server.cpp @@ -0,0 +1,217 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#include "stdafx.h" +#include "console_handler.h" +#include "demo_http_server.h" +#include "net/http_client.h" +#include "storages/http_abstract_invoke.h" + + +template<class t_request, class t_response> +bool communicate(const std::string url, t_request& req, t_response& rsp, const std::string& ip, const std::string& port, bool use_json, bool use_jrpc = false) +{ + epee::net_utils::http::http_simple_client http_client; + bool r = http_client.connect(ip, port, 1000); + CHECK_AND_ASSERT_MES(r, false, "failed to connect"); + if(use_json) + { + if(use_jrpc) + { + epee::json_rpc::request<t_request> req_t = AUTO_VAL_INIT(req_t); + req_t.params = req; + req_t.id = "10"; + req_t.method = "command_example_1"; + req_t.version = "1.1"; + epee::json_rpc::response<t_response, std::string> resp_t = AUTO_VAL_INIT(resp_t); + if(!epee::net_utils::invoke_http_json_remote_command2("/request_json_rpc", req_t, resp_t, http_client)) + { + return false; + } + rsp = resp_t.result; + return true; + }else + return epee::net_utils::invoke_http_json_remote_command2(url, req, rsp, http_client); + } + else + return epee::net_utils::invoke_http_bin_remote_command2(url, req, rsp, http_client); +} + + +int main(int argc, char* argv[]) +{ + TRY_ENTRY(); + string_tools::set_module_name_and_folder(argv[0]); + + //set up logging options + log_space::get_set_log_detalisation_level(true, LOG_LEVEL_2); + log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL); + log_space::log_singletone::add_logger(LOGGER_FILE, + log_space::log_singletone::get_default_log_file().c_str(), + log_space::log_singletone::get_default_log_folder().c_str()); + + + + LOG_PRINT("Demo server starting ...", LOG_LEVEL_0); + + + demo::demo_http_server srv; + + start_default_console(&srv); + + std::string bind_param = "0.0.0.0"; + std::string port = "83"; + + if(!srv.init(port, bind_param)) + { + LOG_ERROR("Failed to initialize srv!"); + return 1; + } + + //log loop + srv.run(); + size_t count = 0; + while (!srv.is_stop()) + { + + demo::COMMAND_EXAMPLE_1::request req; + req.sub = demo::get_test_data(); + demo::COMMAND_EXAMPLE_1::response rsp; + bool r = false; + if(count%2) + {//invoke json + r = communicate("/request_api_json_1", req, rsp, "127.0.0.1", port, true, true); + }else{ + r = communicate("/request_api_bin_1", req, rsp, "127.0.0.1", port, false); + } + CHECK_AND_ASSERT_MES(r, false, "failed to invoke http request"); + CHECK_AND_ASSERT_MES(rsp.m_success, false, "wrong response"); + CHECK_AND_ASSERT_MES(rsp.subs.size()==1, false, "wrong response"); + CHECK_AND_ASSERT_MES(rsp.subs.front() == demo::get_test_data(), false, "wrong response"); + //misc_utils::sleep_no_w(1000); + ++count; + } + bool r = srv.wait_stop(); + CHECK_AND_ASSERT_MES(r, 1, "failed to wait server stop"); + srv.deinit(); + + LOG_PRINT("Demo server stoped.", LOG_LEVEL_0); + return 1; + + CATCH_ENTRY_L0("main", 1); +} + +/************************************************************************/ +/* */ +/************************************************************************/ +namespace demo +{ + bool demo_http_server::init(const std::string& bind_port, const std::string& bind_ip) + { + + + //set self as callback handler + m_net_server.get_config_object().m_phandler = this; + + //here set folder for hosting reqests + m_net_server.get_config_object().m_folder = ""; + + LOG_PRINT_L0("Binding on " << bind_ip << ":" << bind_port); + return m_net_server.init_server(bind_port, bind_ip); + } + + bool demo_http_server::run() + { + m_stop = false; + //here you can set worker threads count + int thrds_count = 4; + + //go to loop + LOG_PRINT("Run net_service loop( " << thrds_count << " threads)...", LOG_LEVEL_0); + if(!m_net_server.run_server(thrds_count, false)) + { + LOG_ERROR("Failed to run net tcp server!"); + } + + return true; + } + + bool demo_http_server::deinit() + { + return m_net_server.deinit_server(); + } + + bool demo_http_server::send_stop_signal() + { + m_stop = true; + m_net_server.send_stop_signal(); + return true; + } + + bool demo_http_server::on_requestr_uri_1(const net_utils::http::http_request_info& query_info, + net_utils::http::http_response_info& response, + const net_utils::connection_context_base& m_conn_context) + { + return true; + } + + + bool demo_http_server::on_requestr_uri_2(const net_utils::http::http_request_info& query_info, + net_utils::http::http_response_info& response, + const net_utils::connection_context_base& m_conn_context) + { + return true; + } + + + bool demo_http_server::on_hosting_request( const net_utils::http::http_request_info& query_info, + net_utils::http::http_response_info& response, + const net_utils::connection_context_base& m_conn_context) + { + //read file from filesystem here + return true; + } + + bool demo_http_server::on_request_api_1(const COMMAND_EXAMPLE_1::request& req, COMMAND_EXAMPLE_1::response& res) + { + CHECK_AND_ASSERT_MES(req.sub == demo::get_test_data(), false, "wrong request"); + res.m_success = true; + res.subs.push_back(req.sub); + return true; + } + + bool demo_http_server::on_request_api_1_with_error(const COMMAND_EXAMPLE_1::request& req, COMMAND_EXAMPLE_1::response& res, epee::json_rpc::error& error_resp) + { + error_resp.code = 232432; + error_resp.message = "bla bla bla"; + return false; + } + + bool demo_http_server::on_request_api_2(const COMMAND_EXAMPLE_2::request& req, COMMAND_EXAMPLE_2::response& res) + { + return true; + } +} diff --git a/contrib/epee/demo/demo_http_server/demo_http_server.h b/contrib/epee/demo/demo_http_server/demo_http_server.h new file mode 100644 index 000000000..bb8f9bffa --- /dev/null +++ b/contrib/epee/demo/demo_http_server/demo_http_server.h @@ -0,0 +1,101 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + + +#pragma once +#include <boost/thread.hpp> +#include <boost/bind.hpp> + +#include "net/http_server_cp2.h" +#include "transport_defs.h" +#include "net/http_server_handlers_map2.h" + +using namespace epee; + +namespace demo +{ + + class demo_http_server: public net_utils::http::i_http_server_handler + { + public: + demo_http_server():m_stop(false){} + bool run(); + bool init(const std::string& bind_port = "11112", const std::string& bind_ip = "0.0.0.0"); + bool deinit(); + bool send_stop_signal(); + bool is_stop(){return m_stop;} + bool wait_stop(){return m_net_server.timed_wait_server_stop(100000);} + private: + + + CHAIN_HTTP_TO_MAP2(); //forward http requests to uri map + + BEGIN_URI_MAP2() + MAP_URI2("/requestr_uri_1", on_requestr_uri_1) + MAP_URI2("/requestr_uri_2", on_requestr_uri_1) + //MAP_URI_AUTO_XML2("/request_api_xml_1", on_request_api_1, COMMAND_EXAMPLE_1) + //MAP_URI_AUTO_XML2("/request_api_xml_2", on_request_api_2, COMMAND_EXAMPLE_2) + MAP_URI_AUTO_JON2("/request_api_json_1", on_request_api_1, COMMAND_EXAMPLE_1) + MAP_URI_AUTO_JON2("/request_api_json_2", on_request_api_2, COMMAND_EXAMPLE_2) + MAP_URI_AUTO_BIN2("/request_api_bin_1", on_request_api_1, COMMAND_EXAMPLE_1) + MAP_URI_AUTO_BIN2("/request_api_bin_2", on_request_api_2, COMMAND_EXAMPLE_2) + BEGIN_JSON_RPC_MAP("/request_json_rpc") + MAP_JON_RPC("command_example_1", on_request_api_1, COMMAND_EXAMPLE_1) + MAP_JON_RPC("command_example_2", on_request_api_2, COMMAND_EXAMPLE_2) + MAP_JON_RPC_WE("command_example_1_we", on_request_api_1_with_error, COMMAND_EXAMPLE_1) + END_JSON_RPC_MAP() + CHAIN_URI_MAP2(on_hosting_request) + END_URI_MAP2() + + + + bool on_requestr_uri_1(const net_utils::http::http_request_info& query_info, + net_utils::http::http_response_info& response, + const net_utils::connection_context_base& m_conn_context); + + + bool on_requestr_uri_2(const net_utils::http::http_request_info& query_info, + net_utils::http::http_response_info& response, + const net_utils::connection_context_base& m_conn_context); + + + + + bool on_hosting_request( const net_utils::http::http_request_info& query_info, + net_utils::http::http_response_info& response, + const net_utils::connection_context_base& m_conn_context); + + bool on_request_api_1(const COMMAND_EXAMPLE_1::request& req, COMMAND_EXAMPLE_1::response& res); + bool on_request_api_2(const COMMAND_EXAMPLE_2::request& req, COMMAND_EXAMPLE_2::response& res); + + bool on_request_api_1_with_error(const COMMAND_EXAMPLE_1::request& req, COMMAND_EXAMPLE_1::response& res, epee::json_rpc::error& error_resp); + + net_utils::boosted_http_server_custum_handling m_net_server; + std::atomic<bool> m_stop; + }; +} + diff --git a/contrib/epee/demo/demo_http_server/stdafx.cpp b/contrib/epee/demo/demo_http_server/stdafx.cpp new file mode 100644 index 000000000..ecec24657 --- /dev/null +++ b/contrib/epee/demo/demo_http_server/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// demo_http_server.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/contrib/epee/demo/demo_http_server/stdafx.h b/contrib/epee/demo/demo_http_server/stdafx.h new file mode 100644 index 000000000..e28883202 --- /dev/null +++ b/contrib/epee/demo/demo_http_server/stdafx.h @@ -0,0 +1,40 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + +#pragma once + +#include "targetver.h" + + +#include <stdio.h> + + +#define BOOST_FILESYSTEM_VERSION 3 +#define ENABLE_RELEASE_LOGGING +#include "misc_log_ex.h" + + diff --git a/contrib/epee/demo/demo_http_server/targetver.h b/contrib/epee/demo/demo_http_server/targetver.h new file mode 100644 index 000000000..6fe8eb79e --- /dev/null +++ b/contrib/epee/demo/demo_http_server/targetver.h @@ -0,0 +1,13 @@ +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + diff --git a/contrib/epee/demo/demo_levin_server/demo_levin_server.cpp b/contrib/epee/demo/demo_levin_server/demo_levin_server.cpp new file mode 100644 index 000000000..215b1dd48 --- /dev/null +++ b/contrib/epee/demo/demo_levin_server/demo_levin_server.cpp @@ -0,0 +1,200 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + + +#include "stdafx.h" +#include "demo_levin_server.h" +#include "console_handler.h" + + +template<class t_request> +bool communicate(net_utils::boosted_levin_async_server& transport, int id, t_request& req, const std::string& ip, const std::string& port, bool use_async) +{ + if(use_async) + { + //IMPORTANT: do not pass local parameters from stack by reference! connect_async returns immediately, and callback will call in any thread later + transport.connect_async(ip, port, 10000, [&transport, id, req, ip, port](net_utils::connection_context_base& ctx, const boost::system::error_code& ec_) + { + if(!!ec_) + { + LOG_ERROR("Failed to connect to " << ip << ":" << port); + }else + {//connected ok! + + epee::net_utils::async_invoke_remote_command2<demo::COMMAND_EXAMPLE_1::response>(ctx.m_connection_id, id, req, transport.get_config_object(), [&transport, ip, port](int res_code, demo::COMMAND_EXAMPLE_1::response& rsp, net_utils::connection_context_base& ctx) + { + if(res_code < 0) + { + LOG_ERROR("Failed to invoke to " << ip << ":" << port); + }else + {//invoked ok + CHECK_AND_ASSERT_MES(rsp.m_success, false, "wrong response"); + CHECK_AND_ASSERT_MES(rsp.subs.size()==1, false, "wrong response"); + CHECK_AND_ASSERT_MES(rsp.subs.front() == demo::get_test_data(), false, "wrong response"); + LOG_PRINT_GREEN("Client COMMAND_EXAMPLE_1 async invoked ok", LOG_LEVEL_0); + } + transport.get_config_object().close(ctx.m_connection_id); + return true; + }); + LOG_PRINT_GREEN("Client COMMAND_EXAMPLE_1 async invoke requested", LOG_LEVEL_0); + } + }); + }else + { + net_utils::connection_context_base ctx = AUTO_VAL_INIT(ctx); + bool r = transport.connect(ip, port, 10000, ctx); + CHECK_AND_ASSERT_MES(r, false, "failed to connect to " << ip << ":" << port); + demo::COMMAND_EXAMPLE_1::response rsp = AUTO_VAL_INIT(rsp); + LOG_PRINT_GREEN("Client COMMAND_EXAMPLE_1 sync invoke requested", LOG_LEVEL_0); + r = epee::net_utils::invoke_remote_command2(ctx.m_connection_id, id, req, rsp, transport.get_config_object()); + CHECK_AND_ASSERT_MES(r, false, "failed to invoke levin request"); + CHECK_AND_ASSERT_MES(rsp.m_success, false, "wrong response"); + CHECK_AND_ASSERT_MES(rsp.subs.size()==1, false, "wrong response"); + CHECK_AND_ASSERT_MES(rsp.subs.front() == demo::get_test_data(), false, "wrong response"); + transport.get_config_object().close(ctx.m_connection_id); + LOG_PRINT_GREEN("Client COMMAND_EXAMPLE_1 sync invoked ok", LOG_LEVEL_0); + } + return true; +} + + +int main(int argc, char* argv[]) +{ + TRY_ENTRY(); + string_tools::set_module_name_and_folder(argv[0]); + + //set up logging options + log_space::get_set_log_detalisation_level(true, LOG_LEVEL_2); + log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL); + log_space::log_singletone::add_logger(LOGGER_FILE, + log_space::log_singletone::get_default_log_file().c_str(), + log_space::log_singletone::get_default_log_folder().c_str()); + + + + LOG_PRINT("Demo server starting ...", LOG_LEVEL_0); + + + demo::demo_levin_server srv; + + start_default_console(&srv); + + std::string bind_param = "0.0.0.0"; + std::string port = "12345"; + + if(!srv.init(port, bind_param)) + { + LOG_ERROR("Failed to initialize srv!"); + return 1; + } + + srv.run(); + + size_t c = 1; + while (!srv.is_stop()) + { + + demo::COMMAND_EXAMPLE_1::request req; + req.sub = demo::get_test_data(); + bool r = communicate(srv.get_server(), demo::COMMAND_EXAMPLE_1::ID, req, "127.0.0.1", port, (c%2 == 0)); + misc_utils::sleep_no_w(1000); + ++c; + } + bool r = srv.wait_stop(); + CHECK_AND_ASSERT_MES(r, 1, "failed to wait server stop"); + + + srv.deinit(); + + LOG_PRINT("Demo server stoped.", LOG_LEVEL_0); + return 1; + + CATCH_ENTRY_L0("main", 1); +} + +/************************************************************************/ +/* */ +/************************************************************************/ +namespace demo +{ + bool demo_levin_server::init(const std::string& bind_port, const std::string& bind_ip) + { + m_net_server.get_config_object().m_pcommands_handler = this; + LOG_PRINT_L0("Binding on " << bind_ip << ":" << bind_port); + return m_net_server.init_server(bind_port, bind_ip); + } + + bool demo_levin_server::run() + { + m_stop = false; + //here you can set worker threads count + int thrds_count = 4; + m_net_server.get_config_object().m_invoke_timeout = 10000; + m_net_server.get_config_object().m_pcommands_handler = this; + + //go to loop + LOG_PRINT("Run net_service loop( " << thrds_count << " threads)...", LOG_LEVEL_0); + if(!m_net_server.run_server(thrds_count, false)) + { + LOG_ERROR("Failed to run net tcp server!"); + } + + LOG_PRINT("net_service loop stopped.", LOG_LEVEL_0); + return true; + } + + bool demo_levin_server::deinit() + { + return m_net_server.deinit_server(); + } + + bool demo_levin_server::send_stop_signal() + { + m_net_server.send_stop_signal(); + return true; + } + int demo_levin_server::handle_command_1(int command, COMMAND_EXAMPLE_1::request& arg, COMMAND_EXAMPLE_1::response& rsp, const net_utils::connection_context_base& context) + { + CHECK_AND_ASSERT_MES(arg.sub == demo::get_test_data(), false, "wrong request"); + rsp.m_success = true; + rsp.subs.push_back(arg.sub); + LOG_PRINT_GREEN("Server COMMAND_EXAMPLE_1 ok", LOG_LEVEL_0); + return 1; + } + int demo_levin_server::handle_command_2(int command, COMMAND_EXAMPLE_2::request& arg, COMMAND_EXAMPLE_2::response& rsp, const net_utils::connection_context_base& context) + { + return 1; + } + int demo_levin_server::handle_notify_1(int command, COMMAND_EXAMPLE_1::request& arg, const net_utils::connection_context_base& context) + { + return 1; + } + int demo_levin_server::handle_notify_2(int command, COMMAND_EXAMPLE_2::request& arg, const net_utils::connection_context_base& context) + { + return 1; + } +} diff --git a/contrib/epee/demo/demo_levin_server/demo_levin_server.h b/contrib/epee/demo/demo_levin_server/demo_levin_server.h new file mode 100644 index 000000000..5a6f68f2d --- /dev/null +++ b/contrib/epee/demo/demo_levin_server/demo_levin_server.h @@ -0,0 +1,76 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + + +#pragma once +#include <boost/thread.hpp> +#include <boost/bind.hpp> + +#include "net/levin_server_cp2.h" +#include "transport_defs.h" +#include "storages/levin_abstract_invoke2.h" + +using namespace epee; + +namespace demo +{ + + class demo_levin_server: public levin::levin_commands_handler<> + { + public: + bool run(); + bool init(const std::string& bind_port = "11112", const std::string& bind_ip = "0.0.0.0"); + bool deinit(); + bool send_stop_signal(); + bool is_stop(){return m_stop;} + bool wait_stop(){return m_net_server.timed_wait_server_stop(100000);} + net_utils::boosted_levin_async_server& get_server(){return m_net_server;} + private: + + + CHAIN_LEVIN_INVOKE_MAP(); //move levin_commands_handler interface invoke(...) callbacks into invoke map + CHAIN_LEVIN_NOTIFY_STUB(); //move levin_commands_handler interface notify(...) callbacks into nothing + + BEGIN_INVOKE_MAP2(demo_levin_server) + HANDLE_INVOKE_T2(COMMAND_EXAMPLE_1, &demo_levin_server::handle_command_1) + HANDLE_INVOKE_T2(COMMAND_EXAMPLE_2, &demo_levin_server::handle_command_2) + HANDLE_NOTIFY_T2(COMMAND_EXAMPLE_1, &demo_levin_server::handle_notify_1) + HANDLE_NOTIFY_T2(COMMAND_EXAMPLE_2, &demo_levin_server::handle_notify_2) + END_INVOKE_MAP2() + + //----------------- commands handlers ---------------------------------------------- + int handle_command_1(int command, COMMAND_EXAMPLE_1::request& arg, COMMAND_EXAMPLE_1::response& rsp, const net_utils::connection_context_base& context); + int handle_command_2(int command, COMMAND_EXAMPLE_2::request& arg, COMMAND_EXAMPLE_2::response& rsp, const net_utils::connection_context_base& context); + int handle_notify_1(int command, COMMAND_EXAMPLE_1::request& arg, const net_utils::connection_context_base& context); + int handle_notify_2(int command, COMMAND_EXAMPLE_2::request& arg, const net_utils::connection_context_base& context); + //---------------------------------------------------------------------------------- + net_utils::boosted_levin_async_server m_net_server; + std::atomic<bool> m_stop; + + }; +} + diff --git a/contrib/epee/demo/demo_levin_server/stdafx.cpp b/contrib/epee/demo/demo_levin_server/stdafx.cpp new file mode 100644 index 000000000..d6ea1c6f2 --- /dev/null +++ b/contrib/epee/demo/demo_levin_server/stdafx.cpp @@ -0,0 +1,30 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + + +#include "stdafx.h" + diff --git a/contrib/epee/demo/demo_levin_server/stdafx.h b/contrib/epee/demo/demo_levin_server/stdafx.h new file mode 100644 index 000000000..f69d5922b --- /dev/null +++ b/contrib/epee/demo/demo_levin_server/stdafx.h @@ -0,0 +1,41 @@ +// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the Andrey N. Sabelnikov nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + + +#pragma once + +#include "targetver.h" + + +#include <stdio.h> + + +#define BOOST_FILESYSTEM_VERSION 3 +#define ENABLE_RELEASE_LOGGING +#include "log_opt_defs.h" +#include "misc_log_ex.h" + + diff --git a/contrib/epee/demo/demo_levin_server/targetver.h b/contrib/epee/demo/demo_levin_server/targetver.h new file mode 100644 index 000000000..6fe8eb79e --- /dev/null +++ b/contrib/epee/demo/demo_levin_server/targetver.h @@ -0,0 +1,13 @@ +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + diff --git a/contrib/epee/demo/generate_gcc.sh b/contrib/epee/demo/generate_gcc.sh new file mode 100644 index 000000000..fcd0a8a7e --- /dev/null +++ b/contrib/epee/demo/generate_gcc.sh @@ -0,0 +1,4 @@ +mkdir build +cd build +cmake .. +#cmake -DBOOST_ROOT=/usr/local/proj/boost_1_49_0 -DBOOST_LIBRARYDIR=/usr/local/proj/boost_1_49_0/stage/lib .. diff --git a/contrib/epee/demo/generate_vc_proj.bat b/contrib/epee/demo/generate_vc_proj.bat new file mode 100644 index 000000000..111405981 --- /dev/null +++ b/contrib/epee/demo/generate_vc_proj.bat @@ -0,0 +1,7 @@ +mkdir build + +cd build + +cmake "-DBoost_USE_STATIC_LIBS=TRUE" -G "Visual Studio 11 Win64" .. +cd .. +pause
\ No newline at end of file diff --git a/contrib/epee/demo/iface/transport_defs.h b/contrib/epee/demo/iface/transport_defs.h new file mode 100644 index 000000000..97f6caadd --- /dev/null +++ b/contrib/epee/demo/iface/transport_defs.h @@ -0,0 +1,213 @@ +#pragma once + +#include "serialization/keyvalue_serialization.h" + + +namespace demo +{ + + struct some_test_subdata + { + std::string m_str; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(m_str) + END_KV_SERIALIZE_MAP() + }; + + struct some_test_data + { + std::string m_str; + uint64_t m_uint64; + uint32_t m_uint32; + uint16_t m_uint16; + uint8_t m_uint8; + int64_t m_int64; + int32_t m_int32; + int16_t m_int16; + int8_t m_int8; + double m_double; + bool m_bool; + std::list<std::string> m_list_of_str; + std::list<uint64_t> m_list_of_uint64_t; + std::list<uint32_t> m_list_of_uint32_t; + std::list<uint16_t> m_list_of_uint16_t; + std::list<uint8_t> m_list_of_uint8_t; + std::list<int64_t> m_list_of_int64_t; + std::list<int32_t> m_list_of_int32_t; + std::list<int16_t> m_list_of_int16_t; + std::list<int8_t> m_list_of_int8_t; + std::list<double> m_list_of_double; + std::list<bool> m_list_of_bool; + some_test_subdata m_subobj; + std::list<some_test_data> m_list_of_self; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(m_str) + KV_SERIALIZE(m_uint64) + KV_SERIALIZE(m_uint32) + KV_SERIALIZE(m_uint16) + KV_SERIALIZE(m_uint8) + KV_SERIALIZE(m_int64) + KV_SERIALIZE(m_int32) + KV_SERIALIZE(m_int16) + KV_SERIALIZE(m_int8) + KV_SERIALIZE(m_double) + KV_SERIALIZE(m_bool) + KV_SERIALIZE(m_subobj) + KV_SERIALIZE(m_list_of_str) + KV_SERIALIZE(m_list_of_uint64_t) + KV_SERIALIZE(m_list_of_uint32_t) + KV_SERIALIZE(m_list_of_uint16_t) + KV_SERIALIZE(m_list_of_uint8_t) + KV_SERIALIZE(m_list_of_int64_t) + KV_SERIALIZE(m_list_of_int32_t) + KV_SERIALIZE(m_list_of_int16_t) + KV_SERIALIZE(m_list_of_int8_t) + KV_SERIALIZE(m_list_of_double) + KV_SERIALIZE(m_list_of_bool) + KV_SERIALIZE(m_list_of_self) + END_KV_SERIALIZE_MAP() + }; + + /************************************************************************/ + /* */ + /************************************************************************/ + struct COMMAND_EXAMPLE_1 + { + const static int ID = 1000; + + struct request + { + std::string example_string_data; + some_test_data sub; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(example_string_data) + KV_SERIALIZE(sub) + END_KV_SERIALIZE_MAP() + }; + + + struct response + { + bool m_success; + std::list<some_test_data> subs; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(m_success) + KV_SERIALIZE(subs) + END_KV_SERIALIZE_MAP() + }; + }; + + + + struct COMMAND_EXAMPLE_2 + { + const static int ID = 1001; + + struct request + { + std::string example_string_data2; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(example_string_data2) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + bool m_success; + + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(m_success) + END_KV_SERIALIZE_MAP() + }; + }; + + + //------------------------------------------------------------------------------------- + //------------------------------------------------------------------------------------- + //in debug purpose + bool operator != (const some_test_subdata& a, const some_test_subdata& b) + { + return b.m_str != a.m_str; + } + + bool operator == (const some_test_data& a, const some_test_data& b) + { + if( b.m_str != a.m_str + || b.m_uint64 != a.m_uint64 + || b.m_uint32 != a.m_uint32 + || b.m_uint16 != a.m_uint16 + || b.m_uint8 != a.m_uint8 + || b.m_int64 != a.m_int64 + || b.m_int32 != a.m_int32 + || b.m_int16 != a.m_int16 + || b.m_int8 != a.m_int8 + || b.m_double != a.m_double + || b.m_bool != a.m_bool + || b.m_list_of_str != a.m_list_of_str + || b.m_list_of_uint64_t != a.m_list_of_uint64_t + || b.m_list_of_uint32_t != a.m_list_of_uint32_t + || b.m_list_of_uint16_t != a.m_list_of_uint16_t + || b.m_list_of_uint8_t != a.m_list_of_uint8_t + || b.m_list_of_int64_t != a.m_list_of_int64_t + || b.m_list_of_int32_t != a.m_list_of_int32_t + || b.m_list_of_int16_t != a.m_list_of_int16_t + || b.m_list_of_int8_t != a.m_list_of_int8_t + || b.m_list_of_double != a.m_list_of_double + || b.m_list_of_bool != a.m_list_of_bool + || b.m_subobj != a.m_subobj + || b.m_list_of_self != a.m_list_of_self + ) + return false; + return true; + } + + inline some_test_data get_test_data() + { + some_test_data s; + s.m_str = "zuzuzuzuzuz"; + s.m_uint64 = 111111111111111; + s.m_uint32 = 2222222; + s.m_uint16 = 2222; + s.m_uint8 = 22; + s.m_int64 = -111111111111111; + s.m_int32 = -2222222; + s.m_int16 = -2222; + s.m_int8 = -24; + s.m_double = 0.11111; + s.m_bool = true; + s.m_list_of_str.push_back("1112121"); + s.m_list_of_uint64_t.push_back(1111111111); + s.m_list_of_uint64_t.push_back(2222222222); + s.m_list_of_uint32_t.push_back(1111111); + s.m_list_of_uint32_t.push_back(2222222); + s.m_list_of_uint16_t.push_back(1111); + s.m_list_of_uint16_t.push_back(2222); + s.m_list_of_uint8_t.push_back(11); + s.m_list_of_uint8_t.push_back(22); + + + s.m_list_of_int64_t.push_back(-1111111111); + s.m_list_of_int64_t.push_back(-222222222); + s.m_list_of_int32_t.push_back(-1111111); + s.m_list_of_int32_t.push_back(-2222222); + s.m_list_of_int16_t.push_back(-1111); + s.m_list_of_int16_t.push_back(-2222); + s.m_list_of_int8_t.push_back(-11); + s.m_list_of_int8_t.push_back(-22); + + s.m_list_of_double.push_back(0.11111); + s.m_list_of_double.push_back(0.22222); + s.m_list_of_bool.push_back(true); + s.m_list_of_bool.push_back(false); + + s.m_subobj.m_str = "subszzzzzzzz"; + s.m_list_of_self.push_back(s); + return s; + } +}
\ No newline at end of file |