1
0
Fork 0
forked from lthn/blockchain

more work on json/descriptions improvements

This commit is contained in:
cryptozoidberg 2024-03-21 22:57:55 +01:00
parent 919790e808
commit 2283a77104
No known key found for this signature in database
GPG key ID: 2E10CC61CAC8F36D
10 changed files with 280 additions and 265 deletions

View file

@ -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;

View file

@ -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)

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -153,6 +153,7 @@ namespace epee
/************************************************************************/
struct section
{
std::map<std::string, std::string> m_descriptions;
std::map<std::string, storage_entry> m_entries;
};

View file

@ -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);
};
//---------------------------------------------------------------------------------------------------------------
}
}

View file

@ -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;
}
//-----------------------------------------------------------------------------------------------------------

View file

@ -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);
}
};
}
}

View file

@ -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();
}

View file

@ -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()
};
};