forked from lthn/blockchain
more work on json/descriptions improvements
This commit is contained in:
parent
919790e808
commit
2283a77104
10 changed files with 280 additions and 265 deletions
|
|
@ -30,6 +30,7 @@
|
|||
#include "storages/portable_storage_template_helper.h"
|
||||
#include "http_base.h"
|
||||
#include "net/net_utils_base.h"
|
||||
#include "storages/portable_storage_extended_for_doc.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -47,15 +48,19 @@ bool auto_doc_t(const std::string& prefix_name, std::string& generate_reference)
|
|||
response_t res = get_documentation_json_struct<response_t>();
|
||||
|
||||
std::string req_str;
|
||||
epee::serialization::portable_storage ps;
|
||||
std::string req_str_descr;
|
||||
epee::serialization::portable_storage_extended_doc ps;
|
||||
req.store(ps, nullptr, true);
|
||||
ps.dump_as_json(req_str);
|
||||
ps.dump_as_decriptions(req_str_descr);
|
||||
|
||||
|
||||
std::string res_str;
|
||||
epee::serialization::portable_storage ps_res;
|
||||
std::string res_str_descr;
|
||||
epee::serialization::portable_storage_extended_doc ps_res;
|
||||
res.store(ps_res, nullptr, true);
|
||||
ps_res.dump_as_json(res_str);
|
||||
ps_res.dump_as_decriptions(res_str_descr);
|
||||
|
||||
|
||||
std::stringstream ss;
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ public: \
|
|||
#define KV_SERIALIZE_N(varialble, val_name) \
|
||||
epee::serialization::selector<is_store>::serialize(this_ref.varialble, stg, hparent_section, val_name);
|
||||
|
||||
#define KV_SERIALIZE_N_DOC(varialble, val_name, substitute) \
|
||||
epee::serialization::selector<is_store>::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, substitute);
|
||||
#define KV_SERIALIZE_N_DOC(varialble, val_name, substitute, description) \
|
||||
epee::serialization::selector<is_store>::serialize(this_ref.varialble, stg, hparent_section, val_name, auto_doc_mode, substitute, description);
|
||||
|
||||
#define KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, val_name) \
|
||||
epee::serialization::selector<is_store>::template serialize_custom<stored_type>(this_ref.varialble, stg, hparent_section, val_name, from_v_to_stored, from_stored_to_v);
|
||||
|
|
@ -98,7 +98,7 @@ public: \
|
|||
#define END_KV_SERIALIZE_MAP() return true;}
|
||||
|
||||
#define KV_SERIALIZE(varialble) KV_SERIALIZE_N(varialble, #varialble)
|
||||
#define KV_SERIALIZE_DOC(varialble, substitute) KV_SERIALIZE_N_DOC( varialble, #varialble, substitute)
|
||||
#define KV_SERIALIZE_DOC(varialble, substitute, description) KV_SERIALIZE_N_DOC( varialble, #varialble, substitute, description)
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble)
|
||||
#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check
|
||||
#define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble)
|
||||
|
|
|
|||
|
|
@ -317,6 +317,7 @@ namespace epee
|
|||
template<class t_type, class t_storage>
|
||||
static bool serialize(const t_type& d, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname, bool doc_mode = false, const t_type& doc_substitute = t_type(), const std::string& description = std::string())
|
||||
{
|
||||
stg.set_entry_description(hparent_section, pname, description);
|
||||
return kv_serialize( (doc_mode ? doc_substitute:d), stg, hparent_section, pname);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace epee
|
|||
{
|
||||
public:
|
||||
//typedef epee::serialization::hsection hsection;
|
||||
typedef t_section hasection;
|
||||
typedef t_section* hsection;
|
||||
typedef epee::serialization::harray harray;
|
||||
typedef storage_entry meta_entry;
|
||||
|
||||
|
|
@ -87,12 +87,13 @@ namespace epee
|
|||
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, end_of_line_t eol = eol_crlf);
|
||||
bool dump_as_json(std::string& targetObj, size_t indent = 0/*, end_of_line_t eol = eol_crlf*/);
|
||||
bool load_from_json(const std::string& source);
|
||||
void set_entry_description(hsection hparent_section, const std::string& name, const std::string& description) {}
|
||||
|
||||
template<typename cb_t>
|
||||
bool enum_entries(hsection hparent_section, cb_t cb);
|
||||
private:
|
||||
protected:
|
||||
section m_root;
|
||||
hsection get_root_section() {return &m_root;}
|
||||
storage_entry* find_storage_entry(const std::string& pentry_name, hsection psection);
|
||||
|
|
@ -111,32 +112,36 @@ namespace epee
|
|||
};
|
||||
#pragma pack(pop)
|
||||
};
|
||||
|
||||
|
||||
template<typename t_section>
|
||||
bool portable_storage_base<t_section>::dump_as_json(std::string& buff, size_t indent /* = 0 */, end_of_line_t eol /* = eol_crlf */)
|
||||
bool portable_storage_base<t_section>::dump_as_json(std::string& buff, size_t indent /* = 0 *//*, end_of_line_t eol *//* = eol_crlf */)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
std::stringstream ss;
|
||||
epee::serialization::dump_as_json(ss, m_root, indent, eol);
|
||||
epee::serialization::recursive_visitor<strategy_json>::dump_as_(ss, m_root, indent/*, eol*/);
|
||||
buff = ss.str();
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::dump_as_json", false)
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::dump_as_json", false)
|
||||
}
|
||||
inline
|
||||
bool portable_storage::load_from_json(const std::string& source)
|
||||
|
||||
template<typename t_section>
|
||||
bool portable_storage_base<t_section>::load_from_json(const std::string& source)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
return json::load_from_json(source, *this);
|
||||
CATCH_ENTRY("portable_storage::load_from_json", false)
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::load_from_json", false)
|
||||
}
|
||||
|
||||
template<typename t_section>
|
||||
template<class trace_policy>
|
||||
bool portable_storage::dump_as_xml(std::string& targetObj, const std::string& root_name)
|
||||
bool portable_storage_base<t_section>::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)
|
||||
template<typename t_section>
|
||||
bool portable_storage_base<t_section>::store_to_binary(binarybuffer& target)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
std::stringstream ss;
|
||||
|
|
@ -148,10 +153,10 @@ namespace epee
|
|||
pack_entry_to_buff(ss, m_root);
|
||||
target = ss.str();
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::store_to_binary", false)
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::store_to_binary", false)
|
||||
}
|
||||
inline
|
||||
bool portable_storage::load_from_binary(const binarybuffer& source)
|
||||
template<typename t_section>
|
||||
bool portable_storage_base<t_section>::load_from_binary(const binarybuffer& source)
|
||||
{
|
||||
m_root.m_entries.clear();
|
||||
if(source.size() < sizeof(storage_block_header))
|
||||
|
|
@ -176,11 +181,11 @@ namespace epee
|
|||
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);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::load_from_binary", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist)
|
||||
template<typename t_section>
|
||||
typename portable_storage_base<t_section>::hsection portable_storage_base<t_section>::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
hparent_section = hparent_section ? hparent_section:&m_root;
|
||||
|
|
@ -201,7 +206,7 @@ namespace epee
|
|||
return nullptr;
|
||||
}
|
||||
return &boost::get<section>(*pentry);
|
||||
CATCH_ENTRY("portable_storage::open_section", nullptr);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::open_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class to_type>
|
||||
|
|
@ -213,8 +218,9 @@ namespace epee
|
|||
void operator()(const from_type& v){convert_t(v, m_target);}
|
||||
};
|
||||
|
||||
template<typename t_section>
|
||||
template<class t_value>
|
||||
bool portable_storage::get_value(const std::string& value_name, t_value& val, hsection hparent_section)
|
||||
bool portable_storage_base<t_section>::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();
|
||||
|
|
@ -226,11 +232,11 @@ namespace epee
|
|||
get_value_visitor<t_value> gvv(val);
|
||||
boost::apply_visitor(gvv, *pentry);
|
||||
return true;
|
||||
//CATCH_ENTRY("portable_storage::template<>get_value", false);
|
||||
//CATCH_ENTRY("portable_storage_base<t_section>::template<>get_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool portable_storage::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section)
|
||||
template<typename t_section>
|
||||
bool portable_storage_base<t_section>::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section)
|
||||
{
|
||||
//TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
|
|
@ -240,11 +246,12 @@ namespace epee
|
|||
|
||||
val = *pentry;
|
||||
return true;
|
||||
//CATCH_ENTRY("portable_storage::template<>get_value", false);
|
||||
//CATCH_ENTRY("portable_storage_base<t_section>::template<>get_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<typename t_section>
|
||||
template<class t_value>
|
||||
bool portable_storage::set_value(const std::string& value_name, const t_value& v, hsection hparent_section)
|
||||
bool portable_storage_base<t_section>::set_value(const std::string& value_name, const t_value& v, hsection hparent_section)
|
||||
{
|
||||
BOOST_MPL_ASSERT(( boost::mpl::contains<boost::mpl::push_front<storage_entry::types, storage_entry>::type, t_value> ));
|
||||
TRY_ENTRY();
|
||||
|
|
@ -260,11 +267,11 @@ namespace epee
|
|||
}
|
||||
*pentry = storage_entry(v);
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::template<>set_value", false);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::template<>set_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection)
|
||||
template<typename t_section>
|
||||
storage_entry* portable_storage_base<t_section>::find_storage_entry(const std::string& pentry_name, hsection psection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(psection, nullptr);
|
||||
|
|
@ -273,27 +280,28 @@ namespace epee
|
|||
return nullptr;
|
||||
|
||||
return &it->second;
|
||||
CATCH_ENTRY("portable_storage::find_storage_entry", nullptr);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::find_storage_entry", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<typename t_section>
|
||||
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)
|
||||
storage_entry* portable_storage_base<t_section>::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);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::insert_new_entry_get_storage_entry", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection)
|
||||
template<typename t_section>
|
||||
typename portable_storage_base<t_section>::hsection portable_storage_base<t_section>::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);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::insert_new_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class to_type>
|
||||
|
|
@ -312,8 +320,9 @@ namespace epee
|
|||
}
|
||||
};
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<typename t_section>
|
||||
template<class t_value>
|
||||
harray portable_storage::get_first_value(const std::string& value_name, t_value& target, hsection hparent_section)
|
||||
harray portable_storage_base<t_section>::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();
|
||||
|
|
@ -329,7 +338,7 @@ namespace epee
|
|||
if(!boost::apply_visitor(gfv, ar_entry))
|
||||
return nullptr;
|
||||
return &ar_entry;
|
||||
//CATCH_ENTRY("portable_storage::get_first_value", nullptr);
|
||||
//CATCH_ENTRY("portable_storage_base<t_section>::get_first_value", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class to_type>
|
||||
|
|
@ -348,10 +357,10 @@ namespace epee
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<typename t_section>
|
||||
template<class t_value>
|
||||
bool portable_storage::get_next_value(harray hval_array, t_value& target)
|
||||
bool portable_storage_base<t_section>::get_next_value(harray hval_array, t_value& target)
|
||||
{
|
||||
BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> ));
|
||||
//TRY_ENTRY();
|
||||
|
|
@ -361,11 +370,12 @@ namespace epee
|
|||
if(!boost::apply_visitor(gnv, ar_entry))
|
||||
return false;
|
||||
return true;
|
||||
//CATCH_ENTRY("portable_storage::get_next_value", false);
|
||||
//CATCH_ENTRY("portable_storage_base<t_section>::get_next_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<typename t_section>
|
||||
template<class t_value>
|
||||
harray portable_storage::insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section)
|
||||
harray portable_storage_base<t_section>::insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
|
|
@ -386,11 +396,12 @@ namespace epee
|
|||
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);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::insert_first_value", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<typename t_section>
|
||||
template<typename cb_t>
|
||||
bool portable_storage::enum_entries(hsection hparent_section, cb_t cb)
|
||||
bool portable_storage_base<t_section>::enum_entries(hsection hparent_section, cb_t cb)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if (!hparent_section) hparent_section = &m_root;
|
||||
|
|
@ -400,11 +411,12 @@ namespace epee
|
|||
break;
|
||||
}
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::enum_entries", false);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::enum_entries", false);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<typename t_section>
|
||||
template<class t_value>
|
||||
bool portable_storage::insert_next_value(harray hval_array, const t_value& target)
|
||||
bool portable_storage_base<t_section>::insert_next_value(harray hval_array, const t_value& target)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hval_array, false);
|
||||
|
|
@ -415,12 +427,12 @@ namespace epee
|
|||
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);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::insert_next_value", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
//sections
|
||||
inline
|
||||
harray portable_storage::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section)
|
||||
template<typename t_section>
|
||||
harray portable_storage_base<t_section>::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
|
|
@ -438,11 +450,11 @@ namespace epee
|
|||
return nullptr;
|
||||
h_child_section = psec;
|
||||
return &ar_entry;
|
||||
CATCH_ENTRY("portable_storage::get_first_section", nullptr);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::get_first_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool portable_storage::get_next_section(harray hsec_array, hsection& h_child_section)
|
||||
template<typename t_section>
|
||||
bool portable_storage_base<t_section>::get_next_section(harray hsec_array, hsection& h_child_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hsec_array, false);
|
||||
|
|
@ -453,11 +465,11 @@ namespace epee
|
|||
if(!h_child_section)
|
||||
return false;
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::get_next_section", false);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::get_next_section", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section)
|
||||
template<typename t_section>
|
||||
harray portable_storage_base<t_section>::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if(!hparent_section) hparent_section = &m_root;
|
||||
|
|
@ -478,11 +490,11 @@ namespace epee
|
|||
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);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::insert_first_section", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
|
||||
template<typename t_section>
|
||||
bool portable_storage_base<t_section>::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
CHECK_AND_ASSERT(hsec_array, false);
|
||||
|
|
@ -492,8 +504,9 @@ namespace epee
|
|||
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);
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::insert_next_section", false);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
typedef portable_storage_base<section> portable_storage;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ namespace epee
|
|||
/************************************************************************/
|
||||
struct section
|
||||
{
|
||||
std::map<std::string, std::string> m_descriptions;
|
||||
std::map<std::string, storage_entry> m_entries;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,60 +37,28 @@ namespace epee
|
|||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
class portable_storage_extended: public portable_storage
|
||||
class portable_storage_extended_doc: public portable_storage
|
||||
{
|
||||
public:
|
||||
typedef epee::serialization::hsection hsection;
|
||||
typedef epee::serialization::harray harray;
|
||||
typedef storage_entry meta_entry;
|
||||
void set_entry_description(hsection hparent_section, const std::string& name, const std::string& description)
|
||||
{
|
||||
if (!hparent_section)
|
||||
hparent_section = &m_root;
|
||||
hparent_section->m_descriptions[name] = description;
|
||||
}
|
||||
|
||||
portable_storage_extended(){}
|
||||
virtual ~portable_storage_extended(){}
|
||||
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);
|
||||
bool get_value(const std::string& value_name, storage_entry& val, hsection hparent_section);
|
||||
template<class t_value>
|
||||
bool set_value(const std::string& value_name, const t_value& target, hsection hparent_section);
|
||||
bool dump_as_decriptions(std::string& buff, size_t indent = 0 , end_of_line_t eol = eol_crlf)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
std::stringstream ss;
|
||||
|
||||
//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, end_of_line_t eol = eol_crlf);
|
||||
bool load_from_json(const std::string& source);
|
||||
//epee::serialization::dump_as_descriptions(ss, m_root, indent, eol);
|
||||
buff = ss.str();
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage_base<t_section>::dump_as_json", false)
|
||||
}
|
||||
|
||||
template<typename cb_t>
|
||||
bool enum_entries(hsection hparent_section, cb_t cb);
|
||||
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);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@ namespace epee
|
|||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
template<class t_struct>
|
||||
bool store_t_to_json(const t_struct& str_in, std::string& json_buff, size_t indent = 0, end_of_line_t eol = eol_crlf)
|
||||
bool store_t_to_json(const t_struct& str_in, std::string& json_buff, size_t indent = 0/*, end_of_line_t eol = eol_crlf*/)
|
||||
{
|
||||
portable_storage ps;
|
||||
str_in.store(ps);
|
||||
ps.dump_as_json(json_buff, indent, eol);
|
||||
ps.dump_as_json(json_buff, indent/*, eol*/);
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -35,169 +35,196 @@ namespace epee
|
|||
{
|
||||
namespace serialization
|
||||
{
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent, end_of_line_t eol = eol_crlf);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent, end_of_line_t eol = eol_crlf);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const std::string& v, size_t indent, end_of_line_t eol = eol_crlf);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const int8_t& v, size_t indent, end_of_line_t eol = eol_crlf);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent, end_of_line_t eol = eol_crlf);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const bool& v, size_t indent, end_of_line_t eol = eol_crlf);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const double& v, size_t indent, end_of_line_t eol = eol_crlf);
|
||||
template<class t_stream, class t_type>
|
||||
void dump_as_json(t_stream& strm, const t_type& v, size_t indent, end_of_line_t eol = eol_crlf);
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const section& sec, size_t indent, end_of_line_t eol = eol_crlf);
|
||||
|
||||
inline const char* get_endline(end_of_line_t eol)
|
||||
{
|
||||
switch (eol)
|
||||
{
|
||||
case eol_lf: return "\n";
|
||||
case eol_cr: return "\r";
|
||||
case eol_space: return " ";
|
||||
default: return "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
inline std::string make_indent(size_t indent)
|
||||
{
|
||||
return std::string(indent*2, ' ');
|
||||
return std::string(indent * 2, ' ');
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
struct array_entry_store_to_json_visitor: public boost::static_visitor<void>
|
||||
class strategy_json
|
||||
{
|
||||
t_stream& m_strm;
|
||||
size_t m_indent;
|
||||
end_of_line_t m_eol;
|
||||
|
||||
array_entry_store_to_json_visitor(t_stream& strm, size_t indent, end_of_line_t eol)
|
||||
: m_strm(strm)
|
||||
, m_indent(indent)
|
||||
, m_eol(eol)
|
||||
{}
|
||||
|
||||
template<class t_type>
|
||||
void operator()(const array_entry_t<t_type>& a)
|
||||
public:
|
||||
inline static const char* eol = get_endline(eol_crlf);
|
||||
//static const end_of_line_t eol = eol_crlf;
|
||||
template<class t_stream>
|
||||
static void handle_value(t_stream& strm, const std::string& v, size_t indent)
|
||||
{
|
||||
m_strm << "[";
|
||||
if(a.m_array.size())
|
||||
strm << "\"" << misc_utils::parse::transform_to_json_escape_sequence(v) << "\"";
|
||||
}
|
||||
template<class t_stream>
|
||||
static void handle_value(t_stream& strm, const int8_t& v, size_t indent)
|
||||
{
|
||||
strm << static_cast<int32_t>(v);
|
||||
}
|
||||
template<class t_stream>
|
||||
static void handle_value(t_stream& strm, const uint8_t& v, size_t indent)
|
||||
{
|
||||
strm << static_cast<int32_t>(v);
|
||||
}
|
||||
template<class t_stream>
|
||||
static void handle_value(t_stream& strm, const bool& v, size_t indent)
|
||||
{
|
||||
if (v)
|
||||
strm << "true";
|
||||
else
|
||||
strm << "false";
|
||||
}
|
||||
template<class t_stream>
|
||||
static void handle_value(t_stream& strm, const double& v, size_t indent)
|
||||
{
|
||||
boost::io::ios_flags_saver ifs(strm);
|
||||
strm.precision(8);
|
||||
strm << std::fixed << v;
|
||||
}
|
||||
template<class t_stream, class t_type>
|
||||
static void handle_value(t_stream& strm, const t_type& v, size_t indent)
|
||||
{
|
||||
strm << v;
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
static void handle_array_start(t_stream& strm, size_t indent)
|
||||
{
|
||||
strm << "[";
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
static void handle_array_end(t_stream& strm, size_t indent)
|
||||
{
|
||||
strm << "]";
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
static void handle_obj_begin(t_stream& strm, size_t indent)
|
||||
{
|
||||
strm << "{";
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
static void handle_obj_end(t_stream& strm, size_t indent)
|
||||
{
|
||||
strm << "}";
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
static void handle_print_key(t_stream& strm, const std::string& key, size_t indent)
|
||||
{
|
||||
const std::string indent_str = make_indent(indent);
|
||||
strm << indent_str << "\"" << misc_utils::parse::transform_to_json_escape_sequence(key) << "\"" << ": ";
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename t_strategy_layout_strategy>
|
||||
class recursive_visitor
|
||||
{
|
||||
public:
|
||||
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)
|
||||
{
|
||||
auto last_it = --a.m_array.end();
|
||||
for(auto it = a.m_array.begin(); it != a.m_array.end(); it++)
|
||||
|
||||
t_strategy_layout_strategy::handle_array_start(m_strm, m_indent);
|
||||
if (a.m_array.size())
|
||||
{
|
||||
dump_as_json(m_strm, *it, m_indent, m_eol);
|
||||
if(it != last_it)
|
||||
m_strm << ",";
|
||||
auto last_it = --a.m_array.end();
|
||||
for (auto it = a.m_array.begin(); it != a.m_array.end(); it++)
|
||||
{
|
||||
dump_as_(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;
|
||||
end_of_line_t m_eol;
|
||||
|
||||
storage_entry_store_to_json_visitor(t_stream& strm, size_t indent, end_of_line_t eol)
|
||||
: m_strm(strm)
|
||||
, m_indent(indent)
|
||||
, m_eol(eol)
|
||||
{}
|
||||
|
||||
//section, array_entry
|
||||
template<class visited_type>
|
||||
void operator()(const visited_type& v)
|
||||
{
|
||||
dump_as_json(m_strm, v, m_indent, m_eol);
|
||||
}
|
||||
};
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent, end_of_line_t eol)
|
||||
{
|
||||
array_entry_store_to_json_visitor<t_stream> aesv(strm, indent, eol);
|
||||
boost::apply_visitor(aesv, ae);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent, end_of_line_t eol)
|
||||
{
|
||||
storage_entry_store_to_json_visitor<t_stream> sv(strm, indent, eol);
|
||||
boost::apply_visitor(sv, se);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const std::string& v, size_t indent, end_of_line_t eol)
|
||||
{
|
||||
strm << "\"" << misc_utils::parse::transform_to_json_escape_sequence(v) << "\"";
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const int8_t& v, size_t indent, end_of_line_t eol)
|
||||
{
|
||||
strm << static_cast<int32_t>(v);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent, end_of_line_t eol)
|
||||
{
|
||||
strm << static_cast<int32_t>(v);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const bool& v, size_t indent, end_of_line_t eol)
|
||||
{
|
||||
if(v)
|
||||
strm << "true";
|
||||
else
|
||||
strm << "false";
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const double& v, size_t indent, end_of_line_t eol)
|
||||
{
|
||||
boost::io::ios_flags_saver ifs(strm);
|
||||
strm.precision(8);
|
||||
strm << std::fixed << v;
|
||||
}
|
||||
|
||||
template<class t_stream, class t_type>
|
||||
void dump_as_json(t_stream& strm, const t_type& v, size_t indent, end_of_line_t eol)
|
||||
{
|
||||
strm << v;
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void dump_as_json(t_stream& strm, const section& sec, size_t indent, end_of_line_t eol)
|
||||
{
|
||||
auto put_eol = [&]() {
|
||||
switch (eol)
|
||||
{
|
||||
case eol_lf: strm << "\n"; break;
|
||||
case eol_cr: strm << "\r"; break;
|
||||
case eol_space: strm << " "; break;
|
||||
default: strm << "\r\n"; break;
|
||||
t_strategy_layout_strategy::handle_array_end(m_strm, m_indent);
|
||||
}
|
||||
};
|
||||
|
||||
size_t local_indent = indent + 1;
|
||||
strm << "{";
|
||||
put_eol();
|
||||
std::string indent_str = make_indent(local_indent);
|
||||
if(sec.m_entries.size())
|
||||
template<class t_stream>
|
||||
struct storage_entry_store_to_json_visitor : public boost::static_visitor<void>
|
||||
{
|
||||
auto it_last = --sec.m_entries.end();
|
||||
for(auto it = sec.m_entries.begin(); it!= sec.m_entries.end();it++)
|
||||
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)
|
||||
{
|
||||
strm << indent_str << "\"" << misc_utils::parse::transform_to_json_escape_sequence(it->first) << "\"" << ": ";
|
||||
dump_as_json(strm, it->second, local_indent, eol);
|
||||
if(it_last != it)
|
||||
strm << ",";
|
||||
put_eol();
|
||||
dump_as_(m_strm, v, m_indent);
|
||||
}
|
||||
};
|
||||
|
||||
template<class t_stream>
|
||||
void static dump_as_(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);
|
||||
}
|
||||
strm << make_indent(indent) << "}";
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void static dump_as_(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, class t_type>
|
||||
void static dump_as_(t_stream& strm, const t_type& v, size_t indent)
|
||||
{
|
||||
t_strategy_layout_strategy::handle_value(strm, v, indent);
|
||||
}
|
||||
|
||||
template<class t_stream>
|
||||
void static dump_as_(t_stream& strm, const section& sec, size_t indent)
|
||||
{
|
||||
|
||||
|
||||
size_t local_indent = indent + 1;
|
||||
t_strategy_layout_strategy::handle_obj_begin(strm, indent);
|
||||
put_eol();
|
||||
|
||||
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++)
|
||||
{
|
||||
t_strategy_layout_strategy::handle_print_key(strm, it->first, local_indent);
|
||||
dump_as_(strm, it->second, local_indent/*, eol*/);
|
||||
if (it_last != it)
|
||||
strm << ",";
|
||||
put_eol();
|
||||
}
|
||||
}
|
||||
t_strategy_layout_strategy::handle_obj_end(strm, indent);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ namespace currency
|
|||
std::stringstream ss;
|
||||
ss << "\"blocks\":{" << ENDL << print_complete_block_entry_list(v.blocks) << ENDL << "}, " << ENDL;
|
||||
ss << "\"missed_ids\":" << ENDL;
|
||||
::epee::serialization::dump_as_json(ss, v.missed_ids, 2);
|
||||
::epee::serialization::recursive_visitor<::epee::serialization::strategy_json>::dump_as_(ss, v.missed_ids, 2);
|
||||
ss << ENDL << "\"current_blockchain_height\":" << v.current_blockchain_height;
|
||||
return ss.str();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,8 +149,8 @@ namespace currency
|
|||
std::string status;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_DOC(height, uint64_t(11111))
|
||||
KV_SERIALIZE_DOC(status, std::string("OK"))
|
||||
KV_SERIALIZE_DOC(height, uint64_t(11111), "Some height of the block")
|
||||
KV_SERIALIZE_DOC(status, std::string("OK"), "Status of the operation")
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue