mirror of
https://git.wownero.com/wownero/wownero.git
synced 2024-08-15 01:03:23 +00:00
moved all stuff to github
This commit is contained in:
parent
095fbeeb67
commit
296ae46ed8
388 changed files with 95937 additions and 469 deletions
132
contrib/epee/include/storages/activity_notifier.h
Normal file
132
contrib/epee/include/storages/activity_notifier.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
// 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 "inmemtoxml.h"
|
||||
|
||||
//#include "levin/levin_server.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
|
||||
class activity_printer_base
|
||||
{
|
||||
public:
|
||||
activity_printer_base(){}
|
||||
virtual ~activity_printer_base(){}
|
||||
};
|
||||
|
||||
template<class A>
|
||||
class notify_activity_printer: public activity_printer_base
|
||||
{
|
||||
public:
|
||||
notify_activity_printer(int level, A& arg, bool is_notify_mode = true):m_ref_arg(arg), m_level(level), m_is_notify_mode(is_notify_mode)
|
||||
{
|
||||
m_command_name = typeid(m_ref_arg).name();
|
||||
m_command_name.erase(0, 7);
|
||||
m_command_name.erase(m_command_name.size()-10, m_command_name.size()-1);
|
||||
if(level == log_space::get_set_log_detalisation_level())
|
||||
{
|
||||
LOG_PRINT(m_command_name, level);
|
||||
}
|
||||
else if(level+1 == log_space::get_set_log_detalisation_level())
|
||||
{
|
||||
LOG_PRINT(" -->>" << m_command_name, level);
|
||||
}
|
||||
else if(level+2 == log_space::get_set_log_detalisation_level())
|
||||
{
|
||||
LOG_PRINT(" -->>" << m_command_name << "\n" << StorageNamed::xml::get_t_as_xml(m_ref_arg), level);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~notify_activity_printer()
|
||||
{
|
||||
if(m_is_notify_mode)
|
||||
{
|
||||
if(m_level+1 == log_space::get_set_log_detalisation_level())
|
||||
{
|
||||
LOG_PRINT(" <<--" << m_command_name, m_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
protected:
|
||||
std::string m_command_name;
|
||||
A& m_ref_arg;
|
||||
int m_level;
|
||||
bool m_is_notify_mode;
|
||||
};
|
||||
|
||||
template<class A, class R>
|
||||
class command_activity_printer: public notify_activity_printer<A>
|
||||
{
|
||||
public:
|
||||
command_activity_printer(int level, A& arg, R& rsp):notify_activity_printer(level, arg, false), m_ref_rsp(rsp)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~command_activity_printer()
|
||||
{
|
||||
if(m_level+1 == log_space::get_set_log_detalisation_level())
|
||||
{
|
||||
LOG_PRINT(" <<--" << m_command_name, m_level);
|
||||
}
|
||||
else if(m_level+2 == log_space::get_set_log_detalisation_level())
|
||||
{
|
||||
LOG_PRINT(" <<--" << m_command_name << "\n" << StorageNamed::trace_as_xml(m_ref_rsp), m_level);
|
||||
}
|
||||
}
|
||||
private:
|
||||
R& m_ref_rsp;
|
||||
};
|
||||
|
||||
template<class A, class R>
|
||||
activity_printer_base* create_activity_printer(int level, A& arg, R& rsp)
|
||||
{
|
||||
return new command_activity_printer<A, R>(level, arg, rsp);
|
||||
}
|
||||
|
||||
template<class A>
|
||||
activity_printer_base* create_activity_printer(int level, A& arg)
|
||||
{
|
||||
return new notify_activity_printer<A>(level, arg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define PRINT_COMMAND_ACTIVITY(level) boost::shared_ptr<activity_printer_base> local_activity_printer(create_activity_printer(level, in_struct, out_struct));
|
||||
#define PRINT_NOTIFY_ACTIVITY(level) boost::shared_ptr<activity_printer_base> local_activity_printer(create_activity_printer(level, in_struct));
|
||||
|
||||
#define PRINT_ACTIVITY(level) \
|
||||
{std::string some_str = typeid(in_struct).name(); \
|
||||
some_str.erase(0, 7); \
|
||||
some_str.erase(some_str.size()-10, some_str.size()-1); \
|
||||
LOG_PRINT(some_str, level);}
|
||||
|
||||
}
|
||||
|
62
contrib/epee/include/storages/crypted_storage.h
Normal file
62
contrib/epee/include/storages/crypted_storage.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef _CRYPTED_STORAGE_H_
|
||||
#define _CRYPTED_STORAGE_H_
|
||||
|
||||
#include "cryptopp_helper.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
template<class t_base_storage, class crypt_provider, class t_key_provider>
|
||||
class crypted_storage: public t_base_storage
|
||||
{
|
||||
public:
|
||||
size_t PackToSolidBuffer(std::string& targetObj)
|
||||
{
|
||||
size_t res = t_base_storage::PackToSolidBuffer(targetObj);
|
||||
if(res <= 0)
|
||||
return res;
|
||||
|
||||
if(!crypt_provider::encrypt(targetObj, t_key_provider::get_storage_default_key()))
|
||||
return 0;
|
||||
|
||||
return targetObj.size();
|
||||
}
|
||||
|
||||
size_t LoadFromSolidBuffer(const std::string& pTargetObj)
|
||||
{
|
||||
std::string buff_to_decrypt = pTargetObj;
|
||||
if(crypt_provider::decrypt(buff_to_decrypt, t_key_provider::get_storage_default_key()))
|
||||
return t_base_storage::LoadFromSolidBuffer(buff_to_decrypt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //_CRYPTED_STORAGE_H_
|
68
contrib/epee/include/storages/gzipped_inmemstorage.h
Normal file
68
contrib/epee/include/storages/gzipped_inmemstorage.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
// 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.
|
||||
//
|
||||
|
||||
|
||||
#ifndef _GZIPPED_INMEMSTORAGE_H_
|
||||
#define _GZIPPED_INMEMSTORAGE_H_
|
||||
|
||||
#include "zlib_helper.h"
|
||||
namespace epee
|
||||
{
|
||||
namespace StorageNamed
|
||||
{
|
||||
|
||||
template<class t_base_storage>
|
||||
class gziped_storage: public t_base_storage
|
||||
{
|
||||
public:
|
||||
size_t PackToSolidBuffer(std::string& targetObj)
|
||||
{
|
||||
size_t res = t_base_storage::PackToSolidBuffer(targetObj);
|
||||
if(res <= 0)
|
||||
return res;
|
||||
|
||||
if(!zlib_helper::pack(targetObj))
|
||||
return 0;
|
||||
|
||||
return targetObj.size();
|
||||
}
|
||||
|
||||
size_t LoadFromSolidBuffer(const std::string& pTargetObj)
|
||||
{
|
||||
std::string buff_to_ungzip = pTargetObj;
|
||||
if(zlib_helper::unpack(buff_to_ungzip))
|
||||
return t_base_storage::LoadFromSolidBuffer(buff_to_ungzip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
126
contrib/epee/include/storages/http_abstract_invoke.h
Normal file
126
contrib/epee/include/storages/http_abstract_invoke.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
|
||||
// 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 "portable_storage_template_helper.h"
|
||||
#include "net/http_base.h"
|
||||
#include "net/http_server_handlers_map2.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_json_remote_command2(const std::string& url, t_request& out_struct, t_response& result_struct, t_transport& transport, unsigned int timeout = 5000, const std::string& method = "GET")
|
||||
{
|
||||
std::string req_param;
|
||||
if(!serialization::store_t_to_json(out_struct, req_param))
|
||||
return false;
|
||||
|
||||
const http::http_response_info* pri = NULL;
|
||||
if(!invoke_request(url, transport, timeout, &pri, method, req_param))
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke http request to " << url);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!pri->m_response_code)
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke http request to " << url << ", internal error (null response ptr)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(pri->m_response_code != 200)
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke http request to " << url << ", wrong response code: " << pri->m_response_code);
|
||||
return false;
|
||||
}
|
||||
|
||||
return serialization::load_t_from_json(result_struct, pri->m_body);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_bin_remote_command2(const std::string& url, t_request& out_struct, t_response& result_struct, t_transport& transport, unsigned int timeout = 5000, const std::string& method = "GET")
|
||||
{
|
||||
std::string req_param;
|
||||
if(!serialization::store_t_to_binary(out_struct, req_param))
|
||||
return false;
|
||||
|
||||
const http::http_response_info* pri = NULL;
|
||||
if(!invoke_request(url, transport, timeout, &pri, method, req_param))
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke http request to " << url);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!pri->m_response_code)
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke http request to " << url << ", internal error (null response ptr)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(pri->m_response_code != 200)
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke http request to " << url << ", wrong response code: " << pri->m_response_code);
|
||||
return false;
|
||||
}
|
||||
|
||||
return serialization::load_t_from_binary(result_struct, pri->m_body);
|
||||
}
|
||||
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_json_rpc(const std::string& url, const std::string& method_name, t_request& out_struct, t_response& result_struct, t_transport& transport, unsigned int timeout = 5000, const std::string& http_method = "GET", const std::string& req_id = "0")
|
||||
{
|
||||
epee::json_rpc::request<t_request> req_t = AUTO_VAL_INIT(req_t);
|
||||
req_t.params = out_struct;
|
||||
req_t.id = req_id;
|
||||
req_t.method = method_name;
|
||||
req_t.version = "2.0";
|
||||
epee::json_rpc::response<t_response, epee::json_rpc::error> resp_t = AUTO_VAL_INIT(resp_t);
|
||||
if(!epee::net_utils::invoke_http_json_remote_command2(url, req_t, resp_t, transport, timeout, http_method))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(resp_t.error.code || resp_t.error.message.size())
|
||||
{
|
||||
LOG_ERROR("RPC call of \"" << method_name << "\" returned error: " << resp_t.error.code << ", message: " << resp_t.error.message);
|
||||
return false;
|
||||
}
|
||||
result_struct = resp_t.result;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class t_command, class t_transport>
|
||||
bool invoke_http_json_rpc(const std::string& url, typename t_command::request& out_struct, typename t_command::response& result_struct, t_transport& transport, unsigned int timeout = 5000, const std::string& http_method = "GET", const std::string& req_id = "0")
|
||||
{
|
||||
return invoke_http_json_rpc(url, t_command::methodname(), out_struct, result_struct, transport, timeout, http_method, req_id);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
289
contrib/epee/include/storages/levin_abstract_invoke2.h
Normal file
289
contrib/epee/include/storages/levin_abstract_invoke2.h
Normal file
|
@ -0,0 +1,289 @@
|
|||
// 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 "portable_storage_template_helper.h"
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include "net/levin_base.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
template<class t_arg, class t_result, class t_transport>
|
||||
bool invoke_remote_command2(int command, const t_arg& out_struct, t_result& result_struct, t_transport& transport)
|
||||
{
|
||||
if(!transport.is_connected())
|
||||
return false;
|
||||
|
||||
serialization::portable_storage stg;
|
||||
out_struct.store(stg);
|
||||
std::string buff_to_send, buff_to_recv;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
|
||||
int res = transport.invoke(command, buff_to_send, buff_to_recv);
|
||||
if( res <=0 )
|
||||
{
|
||||
LOG_PRINT_RED("Failed to invoke command " << command << " return code " << res, LOG_LEVEL_1);
|
||||
return false;
|
||||
}
|
||||
serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff_to_recv))
|
||||
{
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
return false;
|
||||
}
|
||||
result_struct.load(stg_ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class t_arg, class t_transport>
|
||||
bool notify_remote_command2(int command, const t_arg& out_struct, t_transport& transport)
|
||||
{
|
||||
if(!transport.is_connected())
|
||||
return false;
|
||||
|
||||
serialization::portable_storage stg;
|
||||
out_struct.store(&stg);
|
||||
std::string buff_to_send;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
|
||||
int res = transport.notify(command, buff_to_send);
|
||||
if(res <=0 )
|
||||
{
|
||||
LOG_ERROR("Failed to notify command " << command << " return code " << res);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class t_arg, class t_result, class t_transport>
|
||||
bool invoke_remote_command2(boost::uuids::uuid conn_id, int command, const t_arg& out_struct, t_result& result_struct, t_transport& transport)
|
||||
{
|
||||
|
||||
typename serialization::portable_storage stg;
|
||||
out_struct.store(stg);
|
||||
std::string buff_to_send, buff_to_recv;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
|
||||
int res = transport.invoke(command, buff_to_send, buff_to_recv, conn_id);
|
||||
if( res <=0 )
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke command " << command << " return code " << res);
|
||||
return false;
|
||||
}
|
||||
typename serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff_to_recv))
|
||||
{
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
return false;
|
||||
}
|
||||
result_struct.load(stg_ret);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class t_result, class t_arg, class callback_t, class t_transport>
|
||||
bool async_invoke_remote_command2(boost::uuids::uuid conn_id, int command, const t_arg& out_struct, t_transport& transport, callback_t cb, size_t inv_timeout = LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
|
||||
{
|
||||
typename serialization::portable_storage stg;
|
||||
const_cast<t_arg&>(out_struct).store(stg);//TODO: add true const support to searilzation
|
||||
std::string buff_to_send, buff_to_recv;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
int res = transport.invoke_async(command, buff_to_send, conn_id, [cb, command](int code, const std::string& buff, typename t_transport::connection_context& context)->bool
|
||||
{
|
||||
t_result result_struct = AUTO_VAL_INIT(result_struct);
|
||||
if( code <=0 )
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke command " << command << " return code " << code);
|
||||
cb(code, result_struct, context);
|
||||
return false;
|
||||
}
|
||||
serialization::portable_storage stg_ret;
|
||||
if(!stg_ret.load_from_binary(buff))
|
||||
{
|
||||
LOG_ERROR("Failed to load_from_binary on command " << command);
|
||||
cb(LEVIN_ERROR_FORMAT, result_struct, context);
|
||||
return false;
|
||||
}
|
||||
result_struct.load(stg_ret);
|
||||
cb(code, result_struct, context);
|
||||
return true;
|
||||
}, inv_timeout);
|
||||
if( res <=0 )
|
||||
{
|
||||
LOG_PRINT_L1("Failed to invoke command " << command << " return code " << res);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class t_arg, class t_transport>
|
||||
bool notify_remote_command2(boost::uuids::uuid conn_id, int command, const t_arg& out_struct, t_transport& transport)
|
||||
{
|
||||
|
||||
serialization::portable_storage stg;
|
||||
out_struct.store(stg);
|
||||
std::string buff_to_send, buff_to_recv;
|
||||
stg.store_to_binary(buff_to_send);
|
||||
|
||||
int res = transport.notify(command, buff_to_send, conn_id);
|
||||
if(res <=0 )
|
||||
{
|
||||
LOG_PRINT_RED_L0("Failed to notify command " << command << " return code " << res);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
template<class t_owner, class t_in_type, class t_out_type, class t_context, class callback_t>
|
||||
int buff_to_t_adapter(int command, const std::string& in_buff, std::string& buff_out, callback_t cb, t_context& context )
|
||||
{
|
||||
serialization::portable_storage strg;
|
||||
if(!strg.load_from_binary(in_buff))
|
||||
{
|
||||
LOG_ERROR("Failed to load_from_binary in command " << command);
|
||||
return -1;
|
||||
}
|
||||
boost::value_initialized<t_in_type> in_struct;
|
||||
boost::value_initialized<t_out_type> out_struct;
|
||||
|
||||
static_cast<t_in_type&>(in_struct).load(strg);
|
||||
int res = cb(command, static_cast<t_in_type&>(in_struct), static_cast<t_out_type&>(out_struct), context);
|
||||
serialization::portable_storage strg_out;
|
||||
static_cast<t_out_type&>(out_struct).store(strg_out);
|
||||
|
||||
if(!strg_out.store_to_binary(buff_out))
|
||||
{
|
||||
LOG_ERROR("Failed to store_to_binary in command" << command);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
template<class t_owner, class t_in_type, class t_context, class callback_t>
|
||||
int buff_to_t_adapter(t_owner* powner, int command, const std::string& in_buff, callback_t cb, t_context& context)
|
||||
{
|
||||
serialization::portable_storage strg;
|
||||
if(!strg.load_from_binary(in_buff))
|
||||
{
|
||||
LOG_ERROR("Failed to load_from_binary in notify " << command);
|
||||
return -1;
|
||||
}
|
||||
boost::value_initialized<t_in_type> in_struct;
|
||||
static_cast<t_in_type&>(in_struct).load(strg);
|
||||
return cb(command, in_struct, context);
|
||||
};
|
||||
|
||||
#define CHAIN_LEVIN_INVOKE_MAP2(context_type) \
|
||||
int invoke(int command, const std::string& in_buff, std::string& buff_out, context_type& context) \
|
||||
{ \
|
||||
bool handled = false; \
|
||||
return handle_invoke_map(false, command, in_buff, buff_out, context, handled); \
|
||||
}
|
||||
|
||||
#define CHAIN_LEVIN_NOTIFY_MAP2(context_type) \
|
||||
int notify(int command, const std::string& in_buff, context_type& context) \
|
||||
{ \
|
||||
bool handled = false; std::string fake_str;\
|
||||
return handle_invoke_map(true, command, in_buff, fake_str, context, handled); \
|
||||
}
|
||||
|
||||
|
||||
#define CHAIN_LEVIN_INVOKE_MAP() \
|
||||
int invoke(int command, const std::string& in_buff, std::string& buff_out, epee::net_utils::connection_context_base& context) \
|
||||
{ \
|
||||
bool handled = false; \
|
||||
return handle_invoke_map(false, command, in_buff, buff_out, context, handled); \
|
||||
}
|
||||
|
||||
#define CHAIN_LEVIN_NOTIFY_MAP() \
|
||||
int notify(int command, const std::string& in_buff, epee::net_utils::connection_context_base& context) \
|
||||
{ \
|
||||
bool handled = false; std::string fake_str;\
|
||||
return handle_invoke_map(true, command, in_buff, fake_str, context, handled); \
|
||||
}
|
||||
|
||||
#define CHAIN_LEVIN_NOTIFY_STUB() \
|
||||
int notify(int command, const std::string& in_buff, epee::net_utils::connection_context_base& context) \
|
||||
{ \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
#define BEGIN_INVOKE_MAP2(owner_type) \
|
||||
template <class t_context> int handle_invoke_map(bool is_notify, int command, const std::string& in_buff, std::string& buff_out, t_context& context, bool& handled) \
|
||||
{ \
|
||||
typedef owner_type internal_owner_type_name;
|
||||
|
||||
#define HANDLE_INVOKE2(command_id, func, type_name_in, typename_out) \
|
||||
if(!is_notify && command_id == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, type_name_in, typename_out>(this, command, in_buff, buff_out, boost::bind(func, this, _1, _2, _3, _4), context);}
|
||||
|
||||
#define HANDLE_INVOKE_T2(COMMAND, func) \
|
||||
if(!is_notify && COMMAND::ID == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, typename COMMAND::request, typename COMMAND::response>(command, in_buff, buff_out, boost::bind(func, this, _1, _2, _3, _4), context);}
|
||||
|
||||
|
||||
#define HANDLE_NOTIFY2(command_id, func, type_name_in) \
|
||||
if(is_notify && command_id == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, type_name_in>(this, command, in_buff, boost::bind(func, this, _1, _2, _3), context);}
|
||||
|
||||
#define HANDLE_NOTIFY_T2(NOTIFY, func) \
|
||||
if(is_notify && NOTIFY::ID == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, typename NOTIFY::request>(this, command, in_buff, boost::bind(func, this, _1, _2, _3), context);}
|
||||
|
||||
|
||||
#define CHAIN_INVOKE_MAP2(func) \
|
||||
{ \
|
||||
int res = func(is_notify, command, in_buff, buff_out, context, handled); \
|
||||
if(handled) \
|
||||
return res; \
|
||||
}
|
||||
|
||||
#define CHAIN_INVOKE_MAP_TO_OBJ2(obj) \
|
||||
{ \
|
||||
int res = obj.handle_invoke_map(is_notify, command, in_buff, buff_out, context, handled); \
|
||||
if(handled) \
|
||||
return res; \
|
||||
}
|
||||
|
||||
#define CHAIN_INVOKE_MAP_TO_OBJ_FORCE_CONTEXT(obj, context_type) \
|
||||
{ \
|
||||
int res = obj.handle_invoke_map(is_notify, command, in_buff, buff_out, static_cast<context_type>(context), handled); \
|
||||
if(handled) return res; \
|
||||
}
|
||||
|
||||
|
||||
#define END_INVOKE_MAP2() \
|
||||
LOG_ERROR("Unkonown command:" << command); \
|
||||
return LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED; \
|
||||
}
|
||||
}
|
||||
}
|
||||
|
260
contrib/epee/include/storages/parserse_base_utils.h
Normal file
260
contrib/epee/include/storages/parserse_base_utils.h
Normal file
|
@ -0,0 +1,260 @@
|
|||
// 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
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace misc_utils
|
||||
{
|
||||
namespace parse
|
||||
{
|
||||
inline std::string transform_to_escape_sequence(const std::string& src)
|
||||
{
|
||||
//std::stringstream res;
|
||||
std::string res;
|
||||
for(std::string::const_iterator it = src.begin(); it!=src.end(); ++it)
|
||||
{
|
||||
switch(*it)
|
||||
{
|
||||
case '\b': //Backspace (ascii code 08)
|
||||
res+="\\b"; break;
|
||||
case '\f': //Form feed (ascii code 0C)
|
||||
res+="\\f"; break;
|
||||
case '\n': //New line
|
||||
res+="\\n"; break;
|
||||
case '\r': //Carriage return
|
||||
res+="\\r"; break;
|
||||
case '\t': //Tab
|
||||
res+="\\t"; break;
|
||||
case '\v': //Vertical tab
|
||||
res+="\\v"; break;
|
||||
//case '\'': //Apostrophe or single quote
|
||||
// res+="\\'"; break;
|
||||
case '"': //Double quote
|
||||
res+="\\\""; break;
|
||||
case '\\': //Backslash caracter
|
||||
res+="\\\\"; break;
|
||||
case '/': //Backslash caracter
|
||||
res+="\\/"; break;
|
||||
default:
|
||||
res.push_back(*it);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/*
|
||||
|
||||
\b Backspace (ascii code 08)
|
||||
\f Form feed (ascii code 0C)
|
||||
\n New line
|
||||
\r Carriage return
|
||||
\t Tab
|
||||
\v Vertical tab
|
||||
\' Apostrophe or single quote
|
||||
\" Double quote
|
||||
\\ Backslash character
|
||||
|
||||
*/
|
||||
inline void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
val.clear();
|
||||
bool escape_mode = false;
|
||||
std::string::const_iterator it = star_end_string;
|
||||
++it;
|
||||
for(;it != buf_end;it++)
|
||||
{
|
||||
if(escape_mode/*prev_ch == '\\'*/)
|
||||
{
|
||||
switch(*it)
|
||||
{
|
||||
case 'b': //Backspace (ascii code 08)
|
||||
val.push_back(0x08);break;
|
||||
case 'f': //Form feed (ascii code 0C)
|
||||
val.push_back(0x0C);break;
|
||||
case 'n': //New line
|
||||
val.push_back('\n');break;
|
||||
case 'r': //Carriage return
|
||||
val.push_back('\r');break;
|
||||
case 't': //Tab
|
||||
val.push_back('\t');break;
|
||||
case 'v': //Vertical tab
|
||||
val.push_back('\v');break;
|
||||
case '\'': //Apostrophe or single quote
|
||||
val.push_back('\'');break;
|
||||
case '"': //Double quote
|
||||
val.push_back('"');break;
|
||||
case '\\': //Backslash character
|
||||
val.push_back('\\');break;
|
||||
case '/': //Slash character
|
||||
val.push_back('/');break;
|
||||
default:
|
||||
val.push_back(*it);
|
||||
LOG_PRINT_L0("Unknown escape sequence :\"\\" << *it << "\"");
|
||||
}
|
||||
escape_mode = false;
|
||||
}else if(*it == '"')
|
||||
{
|
||||
star_end_string = it;
|
||||
return;
|
||||
}else if(*it == '\\')
|
||||
{
|
||||
escape_mode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
val.push_back(*it);
|
||||
}
|
||||
}
|
||||
ASSERT_MES_AND_THROW("Failed to match string in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
inline bool match_string(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
match_string2(star_end_string, buf_end, val);
|
||||
return true;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
inline void match_number2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val, bool& is_float_val, bool& is_signed_val)
|
||||
{
|
||||
val.clear();
|
||||
is_float_val = false;
|
||||
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
||||
{
|
||||
if(isdigit(*it) || (it == star_end_string && *it == '-') || (val.size() && *it == '.' ) || (is_float_val && (*it == 'e' || *it == 'E' || *it == '-' || *it == '+' )) )
|
||||
{
|
||||
if(!val.size() && *it == '-')
|
||||
is_signed_val = true;
|
||||
if(*it == '.' )
|
||||
is_float_val = true;
|
||||
val.push_back(*it);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(val.size())
|
||||
{
|
||||
star_end_string = --it;
|
||||
return;
|
||||
}
|
||||
else
|
||||
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
}
|
||||
ASSERT_MES_AND_THROW("wrong number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
inline bool match_number(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool is_v_float = false;bool is_signed_val = false;
|
||||
match_number2(star_end_string, buf_end, val, is_v_float, is_signed_val);
|
||||
return !is_v_float;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
inline void match_word2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
val.clear();
|
||||
|
||||
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
||||
{
|
||||
if(!isalpha(*it))
|
||||
{
|
||||
val.assign(star_end_string, it);
|
||||
if(val.size())
|
||||
{
|
||||
star_end_string = --it;
|
||||
return;
|
||||
}else
|
||||
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
}
|
||||
ASSERT_MES_AND_THROW("failed to match word number in json entry: " << std::string(star_end_string, buf_end));
|
||||
}
|
||||
inline bool match_word(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
try
|
||||
{
|
||||
match_word2(star_end_string, buf_end, val);
|
||||
return true;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
inline bool match_word_with_extrasymb(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
|
||||
{
|
||||
val.clear();
|
||||
|
||||
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
||||
{
|
||||
if(!isalnum(*it) && *it != '-' && *it != '_')
|
||||
{
|
||||
val.assign(star_end_string, it);
|
||||
if(val.size())
|
||||
{
|
||||
star_end_string = --it;
|
||||
return true;
|
||||
}else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline bool match_word_til_equal_mark(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string::const_iterator& word_end)
|
||||
{
|
||||
word_end = star_end_string;
|
||||
|
||||
for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
|
||||
{
|
||||
if(isspace(*it))
|
||||
{
|
||||
|
||||
continue;
|
||||
}else if( *it == '=' )
|
||||
{
|
||||
star_end_string = it;
|
||||
word_end = it;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
463
contrib/epee/include/storages/portable_storage.h
Normal file
463
contrib/epee/include/storages/portable_storage.h
Normal file
|
@ -0,0 +1,463 @@
|
|||
// 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 "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
#include "portable_storage_to_bin.h"
|
||||
#include "portable_storage_from_bin.h"
|
||||
#include "portable_storage_to_json.h"
|
||||
#include "portable_storage_from_json.h"
|
||||
#include "portable_storage_val_converters.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
class portable_storage
|
||||
{
|
||||
public:
|
||||
typedef epee::serialization::hsection hsection;
|
||||
typedef epee::serialization::harray harray;
|
||||
|
||||
portable_storage(){}
|
||||
virtual ~portable_storage(){}
|
||||
hsection open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist = false);
|
||||
template<class t_value>
|
||||
bool get_value(const std::string& value_name, t_value& val, hsection hparent_section);
|
||||
template<class t_value>
|
||||
bool set_value(const std::string& value_name, const t_value& target, hsection hparent_section);
|
||||
|
||||
//serial access for arrays of values --------------------------------------
|
||||
//values
|
||||
template<class t_value>
|
||||
harray get_first_value(const std::string& value_name, t_value& target, hsection hparent_section);
|
||||
template<class t_value>
|
||||
bool get_next_value(harray hval_array, t_value& target);
|
||||
template<class t_value>
|
||||
harray insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section);
|
||||
template<class t_value>
|
||||
bool insert_next_value(harray hval_array, const t_value& target);
|
||||
//sections
|
||||
harray get_first_section(const std::string& pSectionName, hsection& h_child_section, hsection hparent_section);
|
||||
bool get_next_section(harray hSecArray, hsection& h_child_section);
|
||||
harray insert_first_section(const std::string& pSectionName, hsection& hinserted_childsection, hsection hparent_section);
|
||||
bool insert_next_section(harray hSecArray, hsection& hinserted_childsection);
|
||||
//------------------------------------------------------------------------
|
||||
//delete entry (section, value or array)
|
||||
bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr);
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool store_to_binary(binarybuffer& target);
|
||||
bool load_from_binary(const binarybuffer& target);
|
||||
template<class trace_policy>
|
||||
bool dump_as_xml(std::string& targetObj, const std::string& root_name = "");
|
||||
bool dump_as_json(std::string& targetObj, size_t indent = 0);
|
||||
bool load_from_json(const std::string& source);
|
||||
|
||||
private:
|
||||
section m_root;
|
||||
hsection get_root_section() {return &m_root;}
|
||||
storage_entry* find_storage_entry(const std::string& pentry_name, hsection psection);
|
||||
template<class entry_type>
|
||||
storage_entry* insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, const entry_type& entry);
|
||||
|
||||
hsection insert_new_section(const std::string& pentry_name, hsection psection);
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct storage_block_header
|
||||
{
|
||||
uint32_t m_signature_a;
|
||||
uint32_t m_signature_b;
|
||||
uint8_t m_ver;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
};
|
||||
inline
|
||||
bool portable_storage::dump_as_json(std::string& buff, size_t indent)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
std::stringstream ss;
|
||||
epee::serialization::dump_as_json(ss, m_root, indent);
|
||||
buff = ss.str();
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::dump_as_json", false)
|
||||
}
|
||||
inline
|
||||
bool portable_storage::load_from_json(const std::string& source)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
return json::load_from_json(source, *this);
|
||||
CATCH_ENTRY("portable_storage::load_from_json", false)
|
||||
}
|
||||
|
||||
template<class trace_policy>
|
||||
bool portable_storage::dump_as_xml(std::string& targetObj, const std::string& root_name)
|
||||
{
|
||||
return false;//TODO: don't think i ever again will use xml - ambiguous and "overtagged" format
|
||||
}
|
||||
|
||||
inline
|
||||
bool portable_storage::store_to_binary(binarybuffer& target)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
std::stringstream ss;
|
||||
storage_block_header sbh = AUTO_VAL_INIT(sbh);
|
||||
sbh.m_signature_a = PORTABLE_STORAGE_SIGNATUREA;
|
||||
sbh.m_signature_b = PORTABLE_STORAGE_SIGNATUREB;
|
||||
sbh.m_ver = PORTABLE_STORAGE_FORMAT_VER;
|
||||
ss.write((const char*)&sbh, sizeof(storage_block_header));
|
||||
pack_entry_to_buff(ss, m_root);
|
||||
target = ss.str();
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::store_to_binary", false)
|
||||
}
|
||||
inline
|
||||
bool portable_storage::load_from_binary(const binarybuffer& source)
|
||||
{
|
||||
m_root.m_entries.clear();
|
||||
if(source.size() < sizeof(storage_block_header))
|
||||
{
|
||||
LOG_ERROR("portable_storage: wrong binary format, packet size = " << source.size() << " less than expected sizeof(storage_block_header)=" << sizeof(storage_block_header));
|
||||
return false;
|
||||
}
|
||||
storage_block_header* pbuff = (storage_block_header*)source.data();
|
||||
if(pbuff->m_signature_a != PORTABLE_STORAGE_SIGNATUREA ||
|
||||
pbuff->m_signature_b != PORTABLE_STORAGE_SIGNATUREB
|
||||
)
|
||||
{
|
||||
LOG_ERROR("portable_storage: wrong binary format - signature missmatch");
|
||||
return false;
|
||||
}
|
||||
if(pbuff->m_ver != PORTABLE_STORAGE_FORMAT_VER)
|
||||
{
|
||||
LOG_ERROR("portable_storage: wrong binary format - unknown format ver = " << pbuff->m_ver);
|
||||
return false;
|
||||
}
|
||||
TRY_ENTRY();
|
||||
throwable_buffer_reader buf_reader(source.data()+sizeof(storage_block_header), source.size()-sizeof(storage_block_header));
|
||||
buf_reader.read(m_root);
|
||||
return true;//TODO:
|
||||
CATCH_ENTRY("portable_storage::load_from_binary", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
hparent_section = hparent_section ? hparent_section:&m_root;
|
||||
storage_entry* pentry = find_storage_entry(section_name, hparent_section);
|
||||
if(!pentry)
|
||||
{
|
||||
if(!create_if_notexist)
|
||||
return nullptr;
|
||||
return insert_new_section(section_name, hparent_section);
|
||||
}
|
||||
CHECK_AND_ASSERT(pentry , nullptr);
|
||||
//check that section_entry we find is real "CSSection"
|
||||
if(pentry->type() != typeid(section))
|
||||
{
|
||||
if(create_if_notexist)
|
||||
*pentry = storage_entry(section());//replace
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
return &boost::get<section>(*pentry);
|
||||
CATCH_ENTRY("portable_storage::open_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class to_type>
|
||||
struct get_value_visitor: boost::static_visitor<void>
|
||||
{
|
||||
to_type& m_target;
|
||||
get_value_visitor(to_type& target):m_target(target){}
|
||||
template<class from_type>
|
||||
void operator()(const from_type& v){convert_t(v, m_target);}
|
||||
};
|
||||
|
||||
template<class t_value>
|
||||
bool portable_storage::get_value(const std::string& value_name, t_value& val, hsection hparent_section)
|
||||
{
|
||||
BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> ));
|
||||
//TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
|
||||
if(!pentry)
|
||||
return false;
|
||||
|
||||
get_value_visitor<t_value> gvv(val);
|
||||
boost::apply_visitor(gvv, *pentry);
|
||||
return true;
|
||||
//CATCH_ENTRY("portable_storage::template<>get_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class t_value>
|
||||
bool portable_storage::set_value(const std::string& value_name, const t_value& v, hsection hparent_section)
|
||||
{
|
||||
BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> ));
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section)
|
||||
hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
|
||||
if(!pentry)
|
||||
{
|
||||
pentry = insert_new_entry_get_storage_entry(value_name, hparent_section, v);
|
||||
if(!pentry)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
*pentry = storage_entry(v);
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::template<>set_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(psection, nullptr);
|
||||
auto it = psection->m_entries.find(pentry_name);
|
||||
if(it == psection->m_entries.end())
|
||||
return nullptr;
|
||||
|
||||
return &it->second;
|
||||
CATCH_ENTRY("portable_storage::find_storage_entry", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class entry_type>
|
||||
storage_entry* portable_storage::insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, const entry_type& entry)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(psection, nullptr);
|
||||
auto ins_res = psection->m_entries.insert(std::pair<std::string, storage_entry>(pentry_name, entry));
|
||||
return &ins_res.first->second;
|
||||
CATCH_ENTRY("portable_storage::insert_new_entry_get_storage_entry", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
storage_entry* pse = insert_new_entry_get_storage_entry(pentry_name, psection, section());
|
||||
if(!pse) return nullptr;
|
||||
return &boost::get<section>(*pse);
|
||||
CATCH_ENTRY("portable_storage::insert_new_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class to_type>
|
||||
struct get_first_value_visitor: boost::static_visitor<bool>
|
||||
{
|
||||
to_type& m_target;
|
||||
get_first_value_visitor(to_type& target):m_target(target){}
|
||||
template<class from_type>
|
||||
bool operator()(const array_entry_t<from_type>& a)
|
||||
{
|
||||
const from_type* pv = a.get_first_val();
|
||||
if(!pv)
|
||||
return false;
|
||||
convert_t(*pv, m_target);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class t_value>
|
||||
harray portable_storage::get_first_value(const std::string& value_name, t_value& target, hsection hparent_section)
|
||||
{
|
||||
BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> ));
|
||||
//TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
|
||||
if(!pentry)
|
||||
return nullptr;
|
||||
if(pentry->type() != typeid(array_entry))
|
||||
return nullptr;
|
||||
array_entry& ar_entry = boost::get<array_entry>(*pentry);
|
||||
|
||||
get_first_value_visitor<t_value> gfv(target);
|
||||
if(!boost::apply_visitor(gfv, ar_entry))
|
||||
return nullptr;
|
||||
return &ar_entry;
|
||||
//CATCH_ENTRY("portable_storage::get_first_value", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class to_type>
|
||||
struct get_next_value_visitor: boost::static_visitor<bool>
|
||||
{
|
||||
to_type& m_target;
|
||||
get_next_value_visitor(to_type& target):m_target(target){}
|
||||
template<class from_type>
|
||||
bool operator()(const array_entry_t<from_type>& a)
|
||||
{
|
||||
//TODO: optimize code here: work without get_next_val function
|
||||
const from_type* pv = a.get_next_val();
|
||||
if(!pv)
|
||||
return false;
|
||||
convert_t(*pv, m_target);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class t_value>
|
||||
bool portable_storage::get_next_value(harray hval_array, t_value& target)
|
||||
{
|
||||
BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> ));
|
||||
//TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hval_array, false);
|
||||
array_entry& ar_entry = *hval_array;
|
||||
get_next_value_visitor<t_value> gnv(target);
|
||||
if(!boost::apply_visitor(gnv, ar_entry))
|
||||
return false;
|
||||
return true;
|
||||
//CATCH_ENTRY("portable_storage::get_next_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class t_value>
|
||||
harray portable_storage::insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
|
||||
if(!pentry)
|
||||
{
|
||||
pentry = insert_new_entry_get_storage_entry(value_name, hparent_section, array_entry(array_entry_t<t_value>()));
|
||||
if(!pentry)
|
||||
return nullptr;
|
||||
}
|
||||
if(pentry->type() != typeid(array_entry))
|
||||
*pentry = storage_entry(array_entry(array_entry_t<t_value>()));
|
||||
|
||||
array_entry& arr = boost::get<array_entry>(*pentry);
|
||||
if(arr.type() != typeid(array_entry_t<t_value>))
|
||||
arr = array_entry(array_entry_t<t_value>());
|
||||
|
||||
array_entry_t<t_value>& arr_typed = boost::get<array_entry_t<t_value> >(arr);
|
||||
arr_typed.insert_first_val(target);
|
||||
return &arr;
|
||||
CATCH_ENTRY("portable_storage::insert_first_value", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class t_value>
|
||||
bool portable_storage::insert_next_value(harray hval_array, const t_value& target)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hval_array, false);
|
||||
|
||||
CHECK_AND_ASSERT_MES(hval_array->type() == typeid(array_entry_t<t_value>),
|
||||
false, "unexpected type in insert_next_value: " << typeid(array_entry_t<t_value>).name());
|
||||
|
||||
array_entry_t<t_value>& arr_typed = boost::get<array_entry_t<t_value> >(*hval_array);
|
||||
arr_typed.insert_next_value(target);
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::insert_next_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
//sections
|
||||
inline
|
||||
harray portable_storage::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
|
||||
if(!pentry)
|
||||
return nullptr;
|
||||
if(pentry->type() != typeid(array_entry))
|
||||
return nullptr;
|
||||
array_entry& ar_entry = boost::get<array_entry>(*pentry);
|
||||
if(ar_entry.type() != typeid(array_entry_t<section>))
|
||||
return nullptr;
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
|
||||
section* psec = sec_array.get_first_val();
|
||||
if(!psec)
|
||||
return nullptr;
|
||||
h_child_section = psec;
|
||||
return &ar_entry;
|
||||
CATCH_ENTRY("portable_storage::get_first_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool portable_storage::get_next_section(harray hsec_array, hsection& h_child_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hsec_array, false);
|
||||
if(hsec_array->type() != typeid(array_entry_t<section>))
|
||||
return nullptr;
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
|
||||
h_child_section = sec_array.get_next_val();
|
||||
if(!h_child_section)
|
||||
return false;
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::get_next_section", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
|
||||
if(!pentry)
|
||||
{
|
||||
pentry = insert_new_entry_get_storage_entry(sec_name, hparent_section, array_entry(array_entry_t<section>()));
|
||||
if(!pentry)
|
||||
return nullptr;
|
||||
}
|
||||
if(pentry->type() != typeid(array_entry))
|
||||
*pentry = storage_entry(array_entry(array_entry_t<section>()));
|
||||
|
||||
array_entry& ar_entry = boost::get<array_entry>(*pentry);
|
||||
if(ar_entry.type() != typeid(array_entry_t<section>))
|
||||
ar_entry = array_entry(array_entry_t<section>());
|
||||
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
|
||||
hinserted_childsection = &sec_array.insert_first_val(section());
|
||||
return &ar_entry;
|
||||
CATCH_ENTRY("portable_storage::insert_first_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hsec_array, false);
|
||||
CHECK_AND_ASSERT_MES(hsec_array->type() == typeid(array_entry_t<section>),
|
||||
false, "unexpected type(not 'section') in insert_next_section, type: " << hsec_array->type().name());
|
||||
|
||||
array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
|
||||
hinserted_childsection = &sec_array.insert_next_value(section());
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::insert_next_section", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
160
contrib/epee/include/storages/portable_storage_base.h
Normal file
160
contrib/epee/include/storages/portable_storage_base.h
Normal file
|
@ -0,0 +1,160 @@
|
|||
// 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/variant.hpp>
|
||||
#include <boost/any.hpp>
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
#define PORTABLE_STORAGE_SIGNATUREA 0x01011101
|
||||
#define PORTABLE_STORAGE_SIGNATUREB 0x01020101 // bender's nightmare
|
||||
#define PORTABLE_STORAGE_FORMAT_VER 1
|
||||
|
||||
#define PORTABLE_RAW_SIZE_MARK_MASK 0x03
|
||||
#define PORTABLE_RAW_SIZE_MARK_BYTE 0
|
||||
#define PORTABLE_RAW_SIZE_MARK_WORD 1
|
||||
#define PORTABLE_RAW_SIZE_MARK_DWORD 2
|
||||
#define PORTABLE_RAW_SIZE_MARK_INT64 3
|
||||
|
||||
#ifndef MAX_STRING_LEN_POSSIBLE
|
||||
#define MAX_STRING_LEN_POSSIBLE 2000000000 //do not let string be so big
|
||||
#endif
|
||||
|
||||
//data types
|
||||
#define SERIALIZE_TYPE_INT64 1
|
||||
#define SERIALIZE_TYPE_INT32 2
|
||||
#define SERIALIZE_TYPE_INT16 3
|
||||
#define SERIALIZE_TYPE_INT8 4
|
||||
#define SERIALIZE_TYPE_UINT64 5
|
||||
#define SERIALIZE_TYPE_UINT32 6
|
||||
#define SERIALIZE_TYPE_UINT16 7
|
||||
#define SERIALIZE_TYPE_UINT8 8
|
||||
#define SERIALIZE_TYPE_DUOBLE 9
|
||||
#define SERIALIZE_TYPE_STRING 10
|
||||
#define SERIALIZE_TYPE_BOOL 11
|
||||
#define SERIALIZE_TYPE_OBJECT 12
|
||||
#define SERIALIZE_TYPE_ARRAY 13
|
||||
|
||||
#define SERIALIZE_FLAG_ARRAY 0x80
|
||||
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
struct section;
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
template<class t_entry_type>
|
||||
struct array_entry_t
|
||||
{
|
||||
array_entry_t():m_it(m_array.end()){}
|
||||
|
||||
const t_entry_type* get_first_val() const
|
||||
{
|
||||
m_it = m_array.begin();
|
||||
return get_next_val();
|
||||
}
|
||||
|
||||
t_entry_type* get_first_val()
|
||||
{
|
||||
m_it = m_array.begin();
|
||||
return get_next_val();
|
||||
}
|
||||
|
||||
|
||||
const t_entry_type* get_next_val() const
|
||||
{
|
||||
if(m_it == m_array.end())
|
||||
return nullptr;
|
||||
return &(*(m_it++));
|
||||
}
|
||||
|
||||
t_entry_type* get_next_val()
|
||||
{
|
||||
if(m_it == m_array.end())
|
||||
return nullptr;
|
||||
return (t_entry_type*)&(*(m_it++));//fuckoff
|
||||
}
|
||||
|
||||
t_entry_type& insert_first_val(const t_entry_type& v)
|
||||
{
|
||||
m_array.clear();
|
||||
m_it = m_array.end();
|
||||
return insert_next_value(v);
|
||||
}
|
||||
|
||||
t_entry_type& insert_next_value(const t_entry_type& v)
|
||||
{
|
||||
m_array.push_back(v);
|
||||
return m_array.back();
|
||||
}
|
||||
|
||||
std::list<t_entry_type> m_array;
|
||||
mutable typename std::list<t_entry_type>::const_iterator m_it;
|
||||
};
|
||||
|
||||
|
||||
typedef boost::make_recursive_variant<
|
||||
array_entry_t<section>,
|
||||
array_entry_t<uint64_t>,
|
||||
array_entry_t<uint32_t>,
|
||||
array_entry_t<uint16_t>,
|
||||
array_entry_t<uint8_t>,
|
||||
array_entry_t<int64_t>,
|
||||
array_entry_t<int32_t>,
|
||||
array_entry_t<int16_t>,
|
||||
array_entry_t<int8_t>,
|
||||
array_entry_t<double>,
|
||||
array_entry_t<bool>,
|
||||
array_entry_t<std::string>,
|
||||
array_entry_t<section>,
|
||||
array_entry_t<boost::recursive_variant_>
|
||||
>::type array_entry;
|
||||
|
||||
typedef boost::variant<uint64_t, uint32_t, uint16_t, uint8_t, int64_t, int32_t, int16_t, int8_t, double, bool, std::string, section, array_entry> storage_entry;
|
||||
|
||||
typedef std::string binarybuffer;//it's ok
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
struct section
|
||||
{
|
||||
std::map<std::string, storage_entry> m_entries;
|
||||
};
|
||||
|
||||
//handle-like aliases
|
||||
typedef section* hsection;
|
||||
typedef array_entry* harray;
|
||||
}
|
||||
}
|
281
contrib/epee/include/storages/portable_storage_from_bin.h
Normal file
281
contrib/epee/include/storages/portable_storage_from_bin.h
Normal file
|
@ -0,0 +1,281 @@
|
|||
// 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 "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
|
||||
#ifdef EPEE_PORTABLE_STORAGE_RECURSION_LIMIT
|
||||
#define EPEE_PORTABLE_STORAGE_RECURSION_LIMIT_INTERNAL EPEE_PORTABLE_STORAGE_RECURSION_LIMIT
|
||||
#else
|
||||
#define EPEE_PORTABLE_STORAGE_RECURSION_LIMIT_INTERNAL 100
|
||||
#endif
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
struct throwable_buffer_reader
|
||||
{
|
||||
throwable_buffer_reader(const void* ptr, size_t sz);
|
||||
void read(void* target, size_t count);
|
||||
void read_sec_name(std::string& sce_name);
|
||||
template<class t_pod_type>
|
||||
void read(t_pod_type& pod_val);
|
||||
template<class t_type>
|
||||
t_type read();
|
||||
template<class type_name>
|
||||
storage_entry read_ae();
|
||||
storage_entry load_storage_array_entry(uint8_t type);
|
||||
size_t read_varint();
|
||||
template<class t_type>
|
||||
storage_entry read_se();
|
||||
storage_entry load_storage_entry();
|
||||
void read(section& sec);
|
||||
void read(std::string& str);
|
||||
private:
|
||||
struct recursuion_limitation_guard
|
||||
{
|
||||
size_t& m_counter_ref;
|
||||
recursuion_limitation_guard(size_t& counter):m_counter_ref(counter)
|
||||
{
|
||||
++m_counter_ref;
|
||||
CHECK_AND_ASSERT_THROW_MES(m_counter_ref < EPEE_PORTABLE_STORAGE_RECURSION_LIMIT_INTERNAL, "Wrong blob data in portable storage: recursion limitation (" << EPEE_PORTABLE_STORAGE_RECURSION_LIMIT_INTERNAL << ") exceeded");
|
||||
}
|
||||
~recursuion_limitation_guard()
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(m_counter_ref != 0, "Internal error: m_counter_ref == 0 while ~recursuion_limitation_guard()");
|
||||
--m_counter_ref;
|
||||
}
|
||||
};
|
||||
#define RECURSION_LIMITATION() recursuion_limitation_guard rl(m_recursion_count)
|
||||
|
||||
const uint8_t* m_ptr;
|
||||
size_t m_count;
|
||||
size_t m_recursion_count;
|
||||
};
|
||||
|
||||
inline throwable_buffer_reader::throwable_buffer_reader(const void* ptr, size_t sz)
|
||||
{
|
||||
if(!ptr)
|
||||
throw std::runtime_error("throwable_buffer_reader: ptr==nullptr");
|
||||
if(!sz)
|
||||
throw std::runtime_error("throwable_buffer_reader: sz==0");
|
||||
m_ptr = (uint8_t*)ptr;
|
||||
m_count = sz;
|
||||
m_recursion_count = 0;
|
||||
}
|
||||
inline
|
||||
void throwable_buffer_reader::read(void* target, size_t count)
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
CHECK_AND_ASSERT_THROW_MES(m_count >= count, " attempt to read " << count << " bytes from buffer with " << m_count << " bytes remained");
|
||||
memcpy(target, m_ptr, count);
|
||||
m_ptr += count;
|
||||
m_count -= count;
|
||||
}
|
||||
inline
|
||||
void throwable_buffer_reader::read_sec_name(std::string& sce_name)
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
uint8_t name_len = 0;
|
||||
read(name_len);
|
||||
sce_name.resize(name_len);
|
||||
read((void*)sce_name.data(), name_len);
|
||||
}
|
||||
|
||||
template<class t_pod_type>
|
||||
void throwable_buffer_reader::read(t_pod_type& pod_val)
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
read(&pod_val, sizeof(pod_val));
|
||||
}
|
||||
|
||||
template<class t_type>
|
||||
t_type throwable_buffer_reader::read()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
t_type v;
|
||||
read(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
template<class type_name>
|
||||
storage_entry throwable_buffer_reader::read_ae()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
//for pod types
|
||||
array_entry_t<type_name> sa;
|
||||
size_t size = read_varint();
|
||||
//TODO: add some optimization here later
|
||||
while(size--)
|
||||
sa.m_array.push_back(read<type_name>());
|
||||
return storage_entry(array_entry(sa));
|
||||
}
|
||||
|
||||
inline
|
||||
storage_entry throwable_buffer_reader::load_storage_array_entry(uint8_t type)
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
type &= ~SERIALIZE_FLAG_ARRAY;
|
||||
switch(type)
|
||||
{
|
||||
case SERIALIZE_TYPE_INT64: return read_ae<int64_t>();
|
||||
case SERIALIZE_TYPE_INT32: return read_ae<int32_t>();
|
||||
case SERIALIZE_TYPE_INT16: return read_ae<int16_t>();
|
||||
case SERIALIZE_TYPE_INT8: return read_ae<int8_t>();
|
||||
case SERIALIZE_TYPE_UINT64: return read_ae<uint64_t>();
|
||||
case SERIALIZE_TYPE_UINT32: return read_ae<uint32_t>();
|
||||
case SERIALIZE_TYPE_UINT16: return read_ae<uint16_t>();
|
||||
case SERIALIZE_TYPE_UINT8: return read_ae<uint8_t>();
|
||||
case SERIALIZE_TYPE_DUOBLE: return read_ae<double>();
|
||||
case SERIALIZE_TYPE_BOOL: return read_ae<bool>();
|
||||
case SERIALIZE_TYPE_STRING: return read_ae<std::string>();
|
||||
case SERIALIZE_TYPE_OBJECT: return read_ae<section>();
|
||||
case SERIALIZE_TYPE_ARRAY: return read_ae<array_entry>();
|
||||
default:
|
||||
CHECK_AND_ASSERT_THROW_MES(false, "unknown entry_type code = " << type);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
size_t throwable_buffer_reader::read_varint()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
CHECK_AND_ASSERT_THROW_MES(m_count >= 1, "empty buff, expected place for varint");
|
||||
size_t v = 0;
|
||||
uint8_t size_mask = (*(uint8_t*)m_ptr) &PORTABLE_RAW_SIZE_MARK_MASK;
|
||||
switch (size_mask)
|
||||
{
|
||||
case PORTABLE_RAW_SIZE_MARK_BYTE: v = read<uint8_t>();break;
|
||||
case PORTABLE_RAW_SIZE_MARK_WORD: v = read<uint16_t>();break;
|
||||
case PORTABLE_RAW_SIZE_MARK_DWORD: v = read<uint32_t>();break;
|
||||
case PORTABLE_RAW_SIZE_MARK_INT64: v = read<uint64_t>();break;
|
||||
default:
|
||||
CHECK_AND_ASSERT_THROW_MES(false, "unknown varint size_mask = " << size_mask);
|
||||
}
|
||||
v >>= 2;
|
||||
return v;
|
||||
}
|
||||
|
||||
template<class t_type>
|
||||
storage_entry throwable_buffer_reader::read_se()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
t_type v;
|
||||
read(v);
|
||||
return storage_entry(v);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline storage_entry throwable_buffer_reader::read_se<std::string>()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
return storage_entry(read<std::string>());
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
inline storage_entry throwable_buffer_reader::read_se<section>()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
section s;//use extra variable due to vs bug, line "storage_entry se(section()); " can't be compiled in visual studio
|
||||
storage_entry se(s);
|
||||
section& section_entry = boost::get<section>(se);
|
||||
read(section_entry);
|
||||
return se;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline storage_entry throwable_buffer_reader::read_se<array_entry>()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
uint8_t ent_type = 0;
|
||||
read(ent_type);
|
||||
CHECK_AND_ASSERT_THROW_MES(ent_type&SERIALIZE_FLAG_ARRAY, "wrong type sequenses");
|
||||
return load_storage_array_entry(ent_type);
|
||||
}
|
||||
|
||||
inline
|
||||
storage_entry throwable_buffer_reader::load_storage_entry()
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
uint8_t ent_type = 0;
|
||||
read(ent_type);
|
||||
if(ent_type&SERIALIZE_FLAG_ARRAY)
|
||||
return load_storage_array_entry(ent_type);
|
||||
|
||||
switch(ent_type)
|
||||
{
|
||||
case SERIALIZE_TYPE_INT64: return read_se<int64_t>();
|
||||
case SERIALIZE_TYPE_INT32: return read_se<int32_t>();
|
||||
case SERIALIZE_TYPE_INT16: return read_se<int16_t>();
|
||||
case SERIALIZE_TYPE_INT8: return read_se<int8_t>();
|
||||
case SERIALIZE_TYPE_UINT64: return read_se<uint64_t>();
|
||||
case SERIALIZE_TYPE_UINT32: return read_se<uint32_t>();
|
||||
case SERIALIZE_TYPE_UINT16: return read_se<uint16_t>();
|
||||
case SERIALIZE_TYPE_UINT8: return read_se<uint8_t>();
|
||||
case SERIALIZE_TYPE_DUOBLE: return read_se<double>();
|
||||
case SERIALIZE_TYPE_BOOL: return read_se<bool>();
|
||||
case SERIALIZE_TYPE_STRING: return read_se<std::string>();
|
||||
case SERIALIZE_TYPE_OBJECT: return read_se<section>();
|
||||
case SERIALIZE_TYPE_ARRAY: return read_se<array_entry>();
|
||||
default:
|
||||
CHECK_AND_ASSERT_THROW_MES(false, "unknown entry_type code = " << ent_type);
|
||||
}
|
||||
}
|
||||
inline
|
||||
void throwable_buffer_reader::read(section& sec)
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
sec.m_entries.clear();
|
||||
size_t count = read_varint();
|
||||
while(count--)
|
||||
{
|
||||
//read section name string
|
||||
std::string sec_name;
|
||||
read_sec_name(sec_name);
|
||||
sec.m_entries.insert(std::make_pair(sec_name, load_storage_entry()));
|
||||
}
|
||||
}
|
||||
inline
|
||||
void throwable_buffer_reader::read(std::string& str)
|
||||
{
|
||||
RECURSION_LIMITATION();
|
||||
size_t len = read_varint();
|
||||
CHECK_AND_ASSERT_THROW_MES(len < MAX_STRING_LEN_POSSIBLE, "to big string len value in storage: " << len);
|
||||
CHECK_AND_ASSERT_THROW_MES(m_count >= len, "string len count value " << len << " goes out of remain storage len " << m_count);
|
||||
//do this manually to avoid double memory write in huge strings (first time at resize, second at read)
|
||||
str.assign((const char*)m_ptr, len);
|
||||
m_ptr+=len;
|
||||
m_count -= len;
|
||||
}
|
||||
}
|
||||
}
|
379
contrib/epee/include/storages/portable_storage_from_json.h
Normal file
379
contrib/epee/include/storages/portable_storage_from_json.h
Normal file
|
@ -0,0 +1,379 @@
|
|||
// 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 "parserse_base_utils.h"
|
||||
#include "file_io_utils.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
using namespace misc_utils::parse;
|
||||
namespace serialization
|
||||
{
|
||||
namespace json
|
||||
{
|
||||
#define CHECK_ISSPACE() if(!isspace(*it)){ ASSERT_MES_AND_THROW("Wrong JSON character at: " << std::string(it, buf_end));}
|
||||
|
||||
/*inline void parse_error()
|
||||
{
|
||||
ASSERT_MES_AND_THROW("json parse error");
|
||||
}*/
|
||||
template<class t_storage>
|
||||
inline void run_handler(typename t_storage::hsection current_section, std::string::const_iterator& sec_buf_begin, std::string::const_iterator buf_end, t_storage& stg)
|
||||
{
|
||||
|
||||
std::string::const_iterator sub_element_start;
|
||||
std::string name;
|
||||
typename t_storage::harray h_array = nullptr;
|
||||
enum match_state
|
||||
{
|
||||
match_state_lookup_for_section_start,
|
||||
match_state_lookup_for_name,
|
||||
match_state_waiting_separator,
|
||||
match_state_wonder_after_separator,
|
||||
match_state_wonder_after_value,
|
||||
match_state_wonder_array,
|
||||
match_state_array_after_value,
|
||||
match_state_array_waiting_value,
|
||||
match_state_error
|
||||
};
|
||||
|
||||
enum array_mode
|
||||
{
|
||||
array_mode_undifined = 0,
|
||||
array_mode_sections,
|
||||
array_mode_string,
|
||||
array_mode_numbers,
|
||||
array_mode_booleans
|
||||
};
|
||||
|
||||
match_state state = match_state_lookup_for_section_start;
|
||||
array_mode array_md = array_mode_undifined;
|
||||
std::string::const_iterator it = sec_buf_begin;
|
||||
for(;it != buf_end;it++)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case match_state_lookup_for_section_start:
|
||||
if(*it == '{')
|
||||
state = match_state_lookup_for_name;
|
||||
else CHECK_ISSPACE();
|
||||
break;
|
||||
case match_state_lookup_for_name:
|
||||
switch(*it)
|
||||
{
|
||||
case '"':
|
||||
match_string2(it, buf_end, name);
|
||||
state = match_state_waiting_separator;
|
||||
break;
|
||||
case '}':
|
||||
//this is it! section ends here.
|
||||
//seems that it is empty section
|
||||
sec_buf_begin = it;
|
||||
return;
|
||||
default:
|
||||
CHECK_ISSPACE();
|
||||
}
|
||||
break;
|
||||
case match_state_waiting_separator:
|
||||
if(*it == ':')
|
||||
state = match_state_wonder_after_separator;
|
||||
else CHECK_ISSPACE();
|
||||
break;
|
||||
case match_state_wonder_after_separator:
|
||||
if(*it == '"')
|
||||
{//just a named string value started
|
||||
std::string val;
|
||||
match_string2(it, buf_end, val);
|
||||
//insert text value
|
||||
stg.set_value(name, val, current_section);
|
||||
state = match_state_wonder_after_value;
|
||||
}else if (isdigit(*it) || *it == '-')
|
||||
{//just a named number value started
|
||||
std::string val;
|
||||
bool is_v_float = false;bool is_signed = false;
|
||||
match_number2(it, buf_end, val, is_v_float, is_signed);
|
||||
if(!is_v_float)
|
||||
{
|
||||
if(is_signed)
|
||||
{
|
||||
int64_t nval = boost::lexical_cast<int64_t>(val);
|
||||
stg.set_value(name, nval, current_section);
|
||||
}else
|
||||
{
|
||||
uint64_t nval = boost::lexical_cast<uint64_t >(val);
|
||||
stg.set_value(name, nval, current_section);
|
||||
}
|
||||
}else
|
||||
{
|
||||
double nval = boost::lexical_cast<double>(val);
|
||||
stg.set_value(name, nval, current_section);
|
||||
}
|
||||
state = match_state_wonder_after_value;
|
||||
}else if(isalpha(*it) )
|
||||
{// could be null, true or false
|
||||
std::string word;
|
||||
match_word2(it, buf_end, word);
|
||||
if(boost::iequals(word, "null"))
|
||||
{
|
||||
state = match_state_wonder_after_value;
|
||||
//just skip this,
|
||||
}else if(boost::iequals(word, "true"))
|
||||
{
|
||||
stg.set_value(name, true, current_section);
|
||||
state = match_state_wonder_after_value;
|
||||
}else if(boost::iequals(word, "false"))
|
||||
{
|
||||
stg.set_value(name, false, current_section);
|
||||
state = match_state_wonder_after_value;
|
||||
}else ASSERT_MES_AND_THROW("Unknown value keyword " << word);
|
||||
}else if(*it == '{')
|
||||
{
|
||||
//sub section here
|
||||
typename t_storage::hsection new_sec = stg.open_section(name, current_section, true);
|
||||
CHECK_AND_ASSERT_THROW_MES(new_sec, "Failed to insert new section in json: " << std::string(it, buf_end));
|
||||
run_handler(new_sec, it, buf_end, stg);
|
||||
state = match_state_wonder_after_value;
|
||||
}else if(*it == '[')
|
||||
{//array of something
|
||||
state = match_state_wonder_array;
|
||||
}else CHECK_ISSPACE();
|
||||
break;
|
||||
case match_state_wonder_after_value:
|
||||
if(*it == ',')
|
||||
state = match_state_lookup_for_name;
|
||||
else if(*it == '}')
|
||||
{
|
||||
//this is it! section ends here.
|
||||
sec_buf_begin = it;
|
||||
return;
|
||||
}else CHECK_ISSPACE();
|
||||
break;
|
||||
case match_state_wonder_array:
|
||||
if(*it == '[')
|
||||
{
|
||||
ASSERT_MES_AND_THROW("array of array not suppoerted yet :( sorry");
|
||||
//mean array of array
|
||||
}
|
||||
if(*it == '{')
|
||||
{
|
||||
//mean array of sections
|
||||
typename t_storage::hsection new_sec = nullptr;
|
||||
h_array = stg.insert_first_section(name, new_sec, current_section);
|
||||
CHECK_AND_ASSERT_THROW_MES(h_array&&new_sec, "failed to create new section");
|
||||
run_handler(new_sec, it, buf_end, stg);
|
||||
state = match_state_array_after_value;
|
||||
array_md = array_mode_sections;
|
||||
}else if(*it == '"')
|
||||
{
|
||||
//mean array of strings
|
||||
std::string val;
|
||||
match_string2(it, buf_end, val);
|
||||
h_array = stg.insert_first_value(name, val, current_section);
|
||||
CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values entry");
|
||||
state = match_state_array_after_value;
|
||||
array_md = array_mode_string;
|
||||
}else if (isdigit(*it) || *it == '-')
|
||||
{//array of numbers value started
|
||||
std::string val;
|
||||
bool is_v_float = false;bool is_signed_val = false;
|
||||
match_number2(it, buf_end, val, is_v_float, is_signed_val);
|
||||
if(!is_v_float)
|
||||
{
|
||||
int64_t nval = boost::lexical_cast<int64_t>(val);//bool res = string_tools::string_to_num_fast(val, nval);
|
||||
h_array = stg.insert_first_value(name, nval, current_section);
|
||||
CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values section entry");
|
||||
}else
|
||||
{
|
||||
double nval = boost::lexical_cast<double>(val);//bool res = string_tools::string_to_num_fast(val, nval);
|
||||
h_array = stg.insert_first_value(name, nval, current_section);
|
||||
CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values section entry");
|
||||
}
|
||||
|
||||
state = match_state_array_after_value;
|
||||
array_md = array_mode_numbers;
|
||||
}else if(*it == ']')//empty array
|
||||
{
|
||||
array_md = array_mode_undifined;
|
||||
state = match_state_wonder_after_value;
|
||||
}else if(isalpha(*it) )
|
||||
{// array of booleans
|
||||
std::string word;
|
||||
match_word2(it, buf_end, word);
|
||||
if(boost::iequals(word, "true"))
|
||||
{
|
||||
h_array = stg.insert_first_value(name, true, current_section);
|
||||
CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values section entry");
|
||||
state = match_state_array_after_value;
|
||||
array_md = array_mode_booleans;
|
||||
}else if(boost::iequals(word, "false"))
|
||||
{
|
||||
h_array = stg.insert_first_value(name, false, current_section);
|
||||
CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values section entry");
|
||||
state = match_state_array_after_value;
|
||||
array_md = array_mode_booleans;
|
||||
|
||||
}else ASSERT_MES_AND_THROW("Unknown value keyword " << word)
|
||||
}else CHECK_ISSPACE();
|
||||
break;
|
||||
case match_state_array_after_value:
|
||||
if(*it == ',')
|
||||
state = match_state_array_waiting_value;
|
||||
else if(*it == ']')
|
||||
{
|
||||
h_array = nullptr;
|
||||
array_md = array_mode_undifined;
|
||||
state = match_state_wonder_after_value;
|
||||
}else CHECK_ISSPACE();
|
||||
break;
|
||||
case match_state_array_waiting_value:
|
||||
switch(array_md)
|
||||
{
|
||||
case array_mode_sections:
|
||||
if(*it == '{')
|
||||
{
|
||||
typename t_storage::hsection new_sec = NULL;
|
||||
bool res = stg.insert_next_section(h_array, new_sec);
|
||||
CHECK_AND_ASSERT_THROW_MES(res&&new_sec, "failed to insert next section");
|
||||
run_handler(new_sec, it, buf_end, stg);
|
||||
state = match_state_array_after_value;
|
||||
}else CHECK_ISSPACE();
|
||||
break;
|
||||
case array_mode_string:
|
||||
if(*it == '"')
|
||||
{
|
||||
std::string val;
|
||||
match_string2(it, buf_end, val);
|
||||
bool res = stg.insert_next_value(h_array, val);
|
||||
CHECK_AND_ASSERT_THROW_MES(res, "failed to insert values");
|
||||
state = match_state_array_after_value;
|
||||
}else CHECK_ISSPACE();
|
||||
break;
|
||||
case array_mode_numbers:
|
||||
if (isdigit(*it) || *it == '-')
|
||||
{//array of numbers value started
|
||||
std::string val;
|
||||
bool is_v_float = false;bool is_signed_val = false;
|
||||
match_number2(it, buf_end, val, is_v_float, is_signed_val);
|
||||
bool insert_res = false;
|
||||
if(!is_v_float)
|
||||
{
|
||||
boost::int64_t nval = boost::lexical_cast<int64_t>(val); //bool res = string_tools::string_to_num_fast(val, nval);
|
||||
insert_res = stg.insert_next_value(h_array, nval);
|
||||
|
||||
}else
|
||||
{
|
||||
//TODO: optimize here if need
|
||||
double nval = boost::lexical_cast<double>(val); //string_tools::string_to_num_fast(val, nval);
|
||||
insert_res = stg.insert_next_value(h_array, nval);
|
||||
}
|
||||
CHECK_AND_ASSERT_THROW_MES(insert_res, "Failed to insert next value");
|
||||
state = match_state_array_after_value;
|
||||
array_md = array_mode_numbers;
|
||||
}else CHECK_ISSPACE();
|
||||
break;
|
||||
case array_mode_booleans:
|
||||
if(isalpha(*it) )
|
||||
{// array of booleans
|
||||
std::string word;
|
||||
match_word2(it, buf_end, word);
|
||||
if(boost::iequals(word, "true"))
|
||||
{
|
||||
bool r = stg.insert_next_value(h_array, true);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, " failed to insert values section entry");
|
||||
state = match_state_array_after_value;
|
||||
}else if(boost::iequals(word, "false"))
|
||||
{
|
||||
bool r = stg.insert_next_value(h_array, false);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, " failed to insert values section entry");
|
||||
state = match_state_array_after_value;
|
||||
}
|
||||
else ASSERT_MES_AND_THROW("Unknown value keyword " << word);
|
||||
}else CHECK_ISSPACE();
|
||||
break;
|
||||
case array_mode_undifined:
|
||||
default:
|
||||
ASSERT_MES_AND_THROW("Bad array state");
|
||||
}
|
||||
break;
|
||||
case match_state_error:
|
||||
default:
|
||||
ASSERT_MES_AND_THROW("WRONG JSON STATE");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
{
|
||||
"firstName": "John",
|
||||
"lastName": "Smith",
|
||||
"age": 25,
|
||||
"address": {
|
||||
"streetAddress": "21 2nd Street",
|
||||
"city": "New York",
|
||||
"state": "NY",
|
||||
"postalCode": -10021,
|
||||
"have_boobs": true,
|
||||
"have_balls": false
|
||||
},
|
||||
"phoneNumber": [
|
||||
{
|
||||
"type": "home",
|
||||
"number": "212 555-1234"
|
||||
},
|
||||
{
|
||||
"type": "fax",
|
||||
"number": "646 555-4567"
|
||||
}
|
||||
],
|
||||
"phoneNumbers": [
|
||||
"812 123-1234",
|
||||
"916 123-4567"
|
||||
]
|
||||
}
|
||||
*/
|
||||
template<class t_storage>
|
||||
inline bool load_from_json(const std::string& buff_json, t_storage& stg)
|
||||
{
|
||||
std::string::const_iterator sec_buf_begin = buff_json.begin();
|
||||
try
|
||||
{
|
||||
run_handler(nullptr, sec_buf_begin, buff_json.end(), stg);
|
||||
return true;
|
||||
}
|
||||
catch(const std::exception& ex)
|
||||
{
|
||||
LOG_PRINT_RED_L0("Failed to parse json, what: " << ex.what());
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
LOG_PRINT_RED_L0("Failed to parse json");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
120
contrib/epee/include/storages/portable_storage_template_helper.h
Normal file
120
contrib/epee/include/storages/portable_storage_template_helper.h
Normal file
|
@ -0,0 +1,120 @@
|
|||
// 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 "parserse_base_utils.h"
|
||||
#include "portable_storage.h"
|
||||
#include "file_io_utils.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool load_t_from_json(t_struct& out, const std::string& json_buff)
|
||||
{
|
||||
portable_storage ps;
|
||||
bool rs = ps.load_from_json(json_buff);
|
||||
if(!rs)
|
||||
return false;
|
||||
|
||||
return out.load(ps);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool load_t_from_json_file(t_struct& out, const std::string& json_file)
|
||||
{
|
||||
std::string f_buff;
|
||||
if(!file_io_utils::load_file_to_string(json_file, f_buff))
|
||||
return false;
|
||||
|
||||
return load_t_from_json(out, f_buff);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool store_t_to_json(t_struct& str_in, std::string& json_buff, size_t indent = 0)
|
||||
{
|
||||
portable_storage ps;
|
||||
str_in.store(ps);
|
||||
ps.dump_as_json(json_buff, indent);
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
std::string store_t_to_json(t_struct& str_in, size_t indent = 0)
|
||||
{
|
||||
std::string json_buff;
|
||||
store_t_to_json(str_in, json_buff, indent);
|
||||
return std::move(json_buff);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool store_t_to_json_file(t_struct& str_in, const std::string& fpath)
|
||||
{
|
||||
std::string json_buff;
|
||||
store_t_to_json(str_in, json_buff);
|
||||
return file_io_utils::save_string_to_file(fpath, json_buff);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool load_t_from_binary(t_struct& out, const std::string& binary_buff)
|
||||
{
|
||||
portable_storage ps;
|
||||
bool rs = ps.load_from_binary(binary_buff);
|
||||
if(!rs)
|
||||
return false;
|
||||
|
||||
return out.load(ps);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool load_t_from_binary_file(t_struct& out, const std::string& binary_file)
|
||||
{
|
||||
std::string f_buff;
|
||||
if(!file_io_utils::load_file_to_string(binary_file, f_buff))
|
||||
return false;
|
||||
|
||||
return load_t_from_binary(out, f_buff);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool store_t_to_binary(t_struct& str_in, std::string& binary_buff, size_t indent = 0)
|
||||
{
|
||||
portable_storage ps;
|
||||
str_in.store(ps);
|
||||
return ps.store_to_binary(binary_buff);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
std::string store_t_to_binary(t_struct& str_in, size_t indent = 0)
|
||||
{
|
||||
std::string binary_buff;
|
||||
store_t_to_binary(str_in, binary_buff, indent);
|
||||
return std::move(binary_buff);
|
||||
}
|
||||
}
|
||||
}
|
212
contrib/epee/include/storages/portable_storage_to_bin.h
Normal file
212
contrib/epee/include/storages/portable_storage_to_bin.h
Normal file
|
@ -0,0 +1,212 @@
|
|||
// 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 "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
|
||||
template<class pack_value, class t_stream>
|
||||
size_t pack_varint_t(t_stream& strm, uint8_t type_or, size_t& pv)
|
||||
{
|
||||
pack_value v = (*((pack_value*)&pv)) << 2;
|
||||
v |= type_or;
|
||||
strm.write((const char*)&v, sizeof(pack_value));
|
||||
return sizeof(pack_value);
|
||||
}
|
||||
|
||||
PRAGMA_WARNING_PUSH
|
||||
PRAGMA_GCC("GCC diagnostic ignored \"-Wstrict-aliasing\"")
|
||||
template<class t_stream>
|
||||
size_t pack_varint(t_stream& strm, size_t val)
|
||||
{ //the first two bits always reserved for size information
|
||||
|
||||
if(val <= 63)
|
||||
{//mean enough one byte
|
||||
return pack_varint_t<uint8_t>(strm, PORTABLE_RAW_SIZE_MARK_BYTE, val);
|
||||
}
|
||||
else if(val <= 16383)
|
||||
{//mean need word
|
||||
return pack_varint_t<uint16_t>(strm, PORTABLE_RAW_SIZE_MARK_WORD, val);
|
||||
}else if(val <= 1073741823)
|
||||
{//mean need dword
|
||||
return pack_varint_t<uint32_t>(strm, PORTABLE_RAW_SIZE_MARK_DWORD, val);
|
||||
}else
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(val <= 4611686018427387903, "failed to pack varint - too big amount = " << val);
|
||||
return pack_varint_t<uint64_t>(strm, PORTABLE_RAW_SIZE_MARK_INT64, val);
|
||||
}
|
||||
}
|
||||
PRAGMA_WARNING_POP
|
||||
|
||||
template<class t_stream>
|
||||
bool put_string(t_stream& strm, const std::string& v)
|
||||
{
|
||||
pack_varint(strm, v.size());
|
||||
if(v.size())
|
||||
strm.write((const char*)v.data(), v.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
struct array_entry_store_visitor: public boost::static_visitor<bool>
|
||||
{
|
||||
t_stream& m_strm;
|
||||
|
||||
template<class t_pod_type>
|
||||
bool pack_pod_array_type(uint8_t contained_type, const array_entry_t<t_pod_type>& arr_pod)
|
||||
{
|
||||
uint8_t type = contained_type|SERIALIZE_FLAG_ARRAY;
|
||||
m_strm.write((const char*)&type, 1);
|
||||
pack_varint(m_strm, arr_pod.m_array.size());
|
||||
for(const t_pod_type& x: arr_pod.m_array)
|
||||
m_strm.write((const char*)&x, sizeof(t_pod_type));
|
||||
return true;
|
||||
}
|
||||
|
||||
array_entry_store_visitor(t_stream& strm):m_strm(strm){}
|
||||
bool operator()(const array_entry_t<uint64_t>& v){ return pack_pod_array_type(SERIALIZE_TYPE_UINT64, v);}
|
||||
bool operator()(const array_entry_t<uint32_t>& v){ return pack_pod_array_type(SERIALIZE_TYPE_UINT32, v);}
|
||||
bool operator()(const array_entry_t<uint16_t>& v){ return pack_pod_array_type(SERIALIZE_TYPE_UINT16, v);}
|
||||
bool operator()(const array_entry_t<uint8_t>& v) { return pack_pod_array_type(SERIALIZE_TYPE_UINT8, v);}
|
||||
bool operator()(const array_entry_t<int64_t>& v) { return pack_pod_array_type(SERIALIZE_TYPE_INT64, v);}
|
||||
bool operator()(const array_entry_t<int32_t>& v) { return pack_pod_array_type(SERIALIZE_TYPE_INT32, v);}
|
||||
bool operator()(const array_entry_t<int16_t>& v) { return pack_pod_array_type(SERIALIZE_TYPE_INT16, v);}
|
||||
bool operator()(const array_entry_t<int8_t>& v) { return pack_pod_array_type(SERIALIZE_TYPE_INT8, v);}
|
||||
bool operator()(const array_entry_t<double>& v) { return pack_pod_array_type(SERIALIZE_TYPE_DUOBLE, v);}
|
||||
bool operator()(const array_entry_t<bool>& v) { return pack_pod_array_type(SERIALIZE_TYPE_BOOL, v);}
|
||||
bool operator()(const array_entry_t<std::string>& arr_str)
|
||||
{
|
||||
uint8_t type = SERIALIZE_TYPE_STRING|SERIALIZE_FLAG_ARRAY;
|
||||
m_strm.write((const char*)&type, 1);
|
||||
pack_varint(m_strm, arr_str.m_array.size());
|
||||
for(const std::string& s: arr_str.m_array)
|
||||
put_string(m_strm, s);
|
||||
return true;
|
||||
}
|
||||
bool operator()(const array_entry_t<section>& arr_sec)
|
||||
{
|
||||
uint8_t type = SERIALIZE_TYPE_OBJECT|SERIALIZE_FLAG_ARRAY;
|
||||
m_strm.write((const char*)&type, 1);
|
||||
pack_varint(m_strm, arr_sec.m_array.size());
|
||||
for(const section& s: arr_sec.m_array)
|
||||
pack_entry_to_buff(m_strm, s);
|
||||
return true;
|
||||
}
|
||||
bool operator()(const array_entry_t<array_entry>& arra_ar)
|
||||
{
|
||||
uint8_t type = SERIALIZE_TYPE_ARRAY|SERIALIZE_FLAG_ARRAY;
|
||||
m_strm.write((const char*)&type, 1);
|
||||
pack_varint(m_strm, arra_ar.m_array.size());
|
||||
for(const array_entry& s: arra_ar.m_array)
|
||||
pack_entry_to_buff(m_strm, s);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<class t_stream>
|
||||
struct storage_entry_store_visitor: public boost::static_visitor<bool>
|
||||
{
|
||||
t_stream& m_strm;
|
||||
storage_entry_store_visitor(t_stream& strm):m_strm(strm){}
|
||||
template<class pod_type>
|
||||
bool pack_pod_type(uint8_t type, const pod_type& v)
|
||||
{
|
||||
m_strm.write((const char*)&type, 1);
|
||||
m_strm.write((const char*)&v, sizeof(pod_type));
|
||||
return true;
|
||||
}
|
||||
//section, array_entry
|
||||
bool operator()(const uint64_t& v){ return pack_pod_type(SERIALIZE_TYPE_UINT64, v);}
|
||||
bool operator()(const uint32_t& v){ return pack_pod_type(SERIALIZE_TYPE_UINT32, v);}
|
||||
bool operator()(const uint16_t& v){ return pack_pod_type(SERIALIZE_TYPE_UINT16, v);}
|
||||
bool operator()(const uint8_t& v) { return pack_pod_type(SERIALIZE_TYPE_UINT8, v);}
|
||||
bool operator()(const int64_t& v) { return pack_pod_type(SERIALIZE_TYPE_INT64, v);}
|
||||
bool operator()(const int32_t& v) { return pack_pod_type(SERIALIZE_TYPE_INT32, v);}
|
||||
bool operator()(const int16_t& v) { return pack_pod_type(SERIALIZE_TYPE_INT16, v);}
|
||||
bool operator()(const int8_t& v) { return pack_pod_type(SERIALIZE_TYPE_INT8, v);}
|
||||
bool operator()(const double& v) { return pack_pod_type(SERIALIZE_TYPE_DUOBLE, v);}
|
||||
bool operator()(const bool& v) { return pack_pod_type(SERIALIZE_TYPE_BOOL, v);}
|
||||
bool operator()(const std::string& v)
|
||||
{
|
||||
uint8_t type = SERIALIZE_TYPE_STRING;
|
||||
m_strm.write((const char*)&type, 1);
|
||||
put_string(m_strm, v);
|
||||
return true;
|
||||
}
|
||||
bool operator()(const section& v)
|
||||
{
|
||||
uint8_t type = SERIALIZE_TYPE_OBJECT;
|
||||
m_strm.write((const char*)&type, 1);
|
||||
return pack_entry_to_buff(m_strm, v);
|
||||
}
|
||||
|
||||
bool operator()(const array_entry& v)
|
||||
{
|
||||
//uint8_t type = SERIALIZE_TYPE_ARRAY;
|
||||
//m_strm.write((const char*)&type, 1);
|
||||
return pack_entry_to_buff(m_strm, v);
|
||||
}
|
||||
};
|
||||
|
||||
template<class t_stream>
|
||||
bool pack_entry_to_buff(t_stream& strm, const array_entry& ae)
|
||||
{
|
||||
array_entry_store_visitor<t_stream> aesv(strm);
|
||||
return boost::apply_visitor(aesv, ae);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
bool pack_entry_to_buff(t_stream& strm, const storage_entry& se)
|
||||
{
|
||||
storage_entry_store_visitor<t_stream> sv(strm);
|
||||
return boost::apply_visitor(sv, se);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
bool pack_entry_to_buff(t_stream& strm, const section& sec)
|
||||
{
|
||||
typedef std::map<std::string, storage_entry>::value_type section_pair;
|
||||
pack_varint(strm, sec.m_entries.size());
|
||||
for(const section_pair& se: sec.m_entries)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(se.first.size() < std::numeric_limits<uint8_t>::max(), "storage_entry_name is too long: " << se.first.size() << ", val: " << se.first);
|
||||
uint8_t len = static_cast<uint8_t>(se.first.size());
|
||||
strm.write((const char*)&len, sizeof(len));
|
||||
strm.write(se.first.data(), size_t(len));
|
||||
pack_entry_to_buff(strm, se.second);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
172
contrib/epee/include/storages/portable_storage_to_json.h
Normal file
172
contrib/epee/include/storages/portable_storage_to_json.h
Normal file
|
@ -0,0 +1,172 @@
|
|||
// 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 "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const std::string& v, size_t indent);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const int8_t& v, size_t indent);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const bool& v, size_t indent);
|
||||
template<class t_stream, class t_type>
|
||||
void dump_as_json(t_stream& strm, const t_type& v, size_t indent);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const section& sec, size_t indent);
|
||||
|
||||
|
||||
inline std::string make_indent(size_t indent)
|
||||
{
|
||||
return std::string(indent*2, ' ');
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
struct array_entry_store_to_json_visitor: public boost::static_visitor<void>
|
||||
{
|
||||
t_stream& m_strm;
|
||||
size_t m_indent;
|
||||
array_entry_store_to_json_visitor(t_stream& strm, size_t indent):m_strm(strm), m_indent(indent){}
|
||||
|
||||
template<class t_type>
|
||||
void operator()(const array_entry_t<t_type>& a)
|
||||
{
|
||||
m_strm << "[";
|
||||
if(a.m_array.size())
|
||||
{
|
||||
auto last_it = --a.m_array.end();
|
||||
for(auto it = a.m_array.begin(); it != a.m_array.end(); it++)
|
||||
{
|
||||
dump_as_json(m_strm, *it, m_indent);
|
||||
if(it != last_it)
|
||||
m_strm << ",";
|
||||
}
|
||||
}
|
||||
m_strm << "]";
|
||||
}
|
||||
};
|
||||
|
||||
template<class t_stream>
|
||||
struct storage_entry_store_to_json_visitor: public boost::static_visitor<void>
|
||||
{
|
||||
t_stream& m_strm;
|
||||
size_t m_indent;
|
||||
storage_entry_store_to_json_visitor(t_stream& strm, size_t indent):m_strm(strm), m_indent(indent)
|
||||
{}
|
||||
//section, array_entry
|
||||
template<class visited_type>
|
||||
void operator()(const visited_type& v)
|
||||
{
|
||||
dump_as_json(m_strm, v, m_indent);
|
||||
}
|
||||
};
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent)
|
||||
{
|
||||
array_entry_store_to_json_visitor<t_stream> aesv(strm, indent);
|
||||
boost::apply_visitor(aesv, ae);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent)
|
||||
{
|
||||
storage_entry_store_to_json_visitor<t_stream> sv(strm, indent);
|
||||
boost::apply_visitor(sv, se);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const std::string& v, size_t indent)
|
||||
{
|
||||
strm << "\"" << misc_utils::parse::transform_to_escape_sequence(v) << "\"";
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const int8_t& v, size_t indent)
|
||||
{
|
||||
strm << static_cast<int32_t>(v);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent)
|
||||
{
|
||||
strm << static_cast<int32_t>(v);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const bool& v, size_t indent)
|
||||
{
|
||||
if(v)
|
||||
strm << "true";
|
||||
else
|
||||
strm << "false";
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class t_stream, class t_type>
|
||||
void dump_as_json(t_stream& strm, const t_type& v, size_t indent)
|
||||
{
|
||||
strm << v;
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const section& sec, size_t indent)
|
||||
{
|
||||
size_t local_indent = indent + 1;
|
||||
strm << "{\r\n";
|
||||
std::string indent_str = make_indent(local_indent);
|
||||
if(sec.m_entries.size())
|
||||
{
|
||||
auto it_last = --sec.m_entries.end();
|
||||
for(auto it = sec.m_entries.begin(); it!= sec.m_entries.end();it++)
|
||||
{
|
||||
strm << indent_str << "\"" << misc_utils::parse::transform_to_escape_sequence(it->first) << "\"" << ": ";
|
||||
dump_as_json(strm, it->second, local_indent);
|
||||
if(it_last != it)
|
||||
strm << ",";
|
||||
strm << "\r\n";
|
||||
}
|
||||
}
|
||||
strm << make_indent(indent) << "}";
|
||||
}
|
||||
}
|
||||
}
|
169
contrib/epee/include/storages/portable_storage_val_converters.h
Normal file
169
contrib/epee/include/storages/portable_storage_val_converters.h
Normal file
|
@ -0,0 +1,169 @@
|
|||
// 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 "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
#include "warnings.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
{
|
||||
#define ASSERT_AND_THROW_WRONG_CONVERSION() ASSERT_MES_AND_THROW("WRONG DATA CONVERSION: from type=" << typeid(from).name() << " to type " << typeid(to).name())
|
||||
|
||||
template<typename from_type, typename to_type>
|
||||
void convert_int_to_uint(const from_type& from, to_type& to)
|
||||
{
|
||||
PUSH_WARNINGS
|
||||
DISABLE_VS_WARNINGS(4018)
|
||||
CHECK_AND_ASSERT_THROW_MES(from >=0, "unexpected int value with signed storage value less than 0, and unsigned receiver value");
|
||||
DISABLE_GCC_AND_CLANG_WARNING(sign-compare)
|
||||
CHECK_AND_ASSERT_THROW_MES(from <= std::numeric_limits<to_type>::max(), "int value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with max possible value = " << std::numeric_limits<to_type>::max());
|
||||
to = static_cast<to_type>(from);
|
||||
POP_WARNINGS
|
||||
}
|
||||
template<typename from_type, typename to_type>
|
||||
void convert_int_to_int(const from_type& from, to_type& to)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(from >= boost::numeric::bounds<to_type>::lowest(), "int value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with lowest possible value = " << boost::numeric::bounds<to_type>::lowest());
|
||||
PUSH_WARNINGS
|
||||
DISABLE_CLANG_WARNING(tautological-constant-out-of-range-compare)
|
||||
CHECK_AND_ASSERT_THROW_MES(from <= std::numeric_limits<to_type>::max(), "int value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with max possible value = " << std::numeric_limits<to_type>::max());
|
||||
POP_WARNINGS
|
||||
to = static_cast<to_type>(from);
|
||||
}
|
||||
template<typename from_type, typename to_type>
|
||||
void convert_uint_to_any_int(const from_type& from, to_type& to)
|
||||
{
|
||||
PUSH_WARNINGS
|
||||
DISABLE_VS_WARNINGS(4018)
|
||||
DISABLE_CLANG_WARNING(tautological-constant-out-of-range-compare)
|
||||
CHECK_AND_ASSERT_THROW_MES(from <= std::numeric_limits<to_type>::max(), "uint value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with max possible value = " << std::numeric_limits<to_type>::max());
|
||||
to = static_cast<to_type>(from);
|
||||
POP_WARNINGS
|
||||
}
|
||||
|
||||
template<typename from_type, typename to_type, bool, bool> //is from signed, is from to signed
|
||||
struct convert_to_signed_unsigned;
|
||||
|
||||
template<typename from_type, typename to_type>
|
||||
struct convert_to_signed_unsigned<from_type, to_type, true, true>
|
||||
{
|
||||
static void convert(const from_type& from, to_type& to)
|
||||
{//from signed to signed
|
||||
convert_int_to_int(from, to);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename from_type, typename to_type>
|
||||
struct convert_to_signed_unsigned<from_type, to_type, true, false>
|
||||
{
|
||||
static void convert(const from_type& from, to_type& to)
|
||||
{//from signed to unsigned
|
||||
convert_int_to_uint(from, to);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename from_type, typename to_type>
|
||||
struct convert_to_signed_unsigned<from_type, to_type, false, true>
|
||||
{
|
||||
static void convert(const from_type& from, to_type& to)
|
||||
{//from unsigned to signed
|
||||
convert_uint_to_any_int(from, to);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename from_type, typename to_type>
|
||||
struct convert_to_signed_unsigned<from_type, to_type, false, false>
|
||||
{
|
||||
static void convert(const from_type& from, to_type& to)
|
||||
{
|
||||
//from unsigned to unsigned
|
||||
convert_uint_to_any_int(from, to);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename from_type, typename to_type, bool>
|
||||
struct convert_to_integral;
|
||||
|
||||
template<typename from_type, typename to_type>
|
||||
struct convert_to_integral<from_type, to_type, true>
|
||||
{
|
||||
static void convert(const from_type& from, to_type& to)
|
||||
{
|
||||
convert_to_signed_unsigned<from_type, to_type, std::is_signed<from_type>::value, std::is_signed<to_type>::value>::convert(from, to);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename from_type, typename to_type>
|
||||
struct convert_to_integral<from_type, to_type, false>
|
||||
{
|
||||
static void convert(const from_type& from, to_type& to)
|
||||
{
|
||||
ASSERT_AND_THROW_WRONG_CONVERSION();
|
||||
}
|
||||
};
|
||||
|
||||
template<class from_type, class to_type>
|
||||
struct is_convertable: std::integral_constant<bool,
|
||||
std::is_integral<to_type>::value &&
|
||||
std::is_integral<from_type>::value &&
|
||||
!std::is_same<from_type, bool>::value &&
|
||||
!std::is_same<to_type, bool>::value > {};
|
||||
|
||||
template<typename from_type, typename to_type, bool>
|
||||
struct convert_to_same;
|
||||
|
||||
template<typename from_type, typename to_type>
|
||||
struct convert_to_same<from_type, to_type, true>
|
||||
{
|
||||
static void convert(const from_type& from, to_type& to)
|
||||
{
|
||||
to = from;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename from_type, typename to_type>
|
||||
struct convert_to_same<from_type, to_type, false>
|
||||
{
|
||||
static void convert(const from_type& from, to_type& to)
|
||||
{
|
||||
convert_to_integral<from_type, to_type, is_convertable<from_type, to_type>::value>::convert(from, to);// ASSERT_AND_THROW_WRONG_CONVERSION();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class from_type, class to_type>
|
||||
void convert_t(const from_type& from, to_type& to)
|
||||
{
|
||||
convert_to_same<from_type, to_type, std::is_same<to_type, from_type>::value>::convert(from, to);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue