diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 93fac55e..50ab3e30 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -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(); 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; diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index 033b12ca..e510f30a 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -68,8 +68,8 @@ public: \ #define KV_SERIALIZE_N(varialble, val_name) \ epee::serialization::selector::serialize(this_ref.varialble, stg, hparent_section, val_name); -#define KV_SERIALIZE_N_DOC(varialble, val_name, substitute) \ - epee::serialization::selector::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::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::template serialize_custom(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) diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index 42397206..9123fe6f 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -317,6 +317,7 @@ namespace epee template 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); } diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h index 2b41cdfc..0eed742b 100644 --- a/contrib/epee/include/storages/portable_storage.h +++ b/contrib/epee/include/storages/portable_storage.h @@ -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 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 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 - bool portable_storage_base::dump_as_json(std::string& buff, size_t indent /* = 0 */, end_of_line_t eol /* = eol_crlf */) + bool portable_storage_base::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::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::dump_as_json", false) } - inline - bool portable_storage::load_from_json(const std::string& source) + + template + bool portable_storage_base::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::load_from_json", false) } + template template - bool portable_storage::dump_as_xml(std::string& targetObj, const std::string& root_name) + bool portable_storage_base::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 + bool portable_storage_base::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::store_to_binary", false) } - inline - bool portable_storage::load_from_binary(const binarybuffer& source) + template + bool portable_storage_base::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::load_from_binary", false); } //--------------------------------------------------------------------------------------------------------------- - inline - hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist) + template + typename portable_storage_base::hsection portable_storage_base::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
(*pentry); - CATCH_ENTRY("portable_storage::open_section", nullptr); + CATCH_ENTRY("portable_storage_base::open_section", nullptr); } //--------------------------------------------------------------------------------------------------------------- template @@ -213,8 +218,9 @@ namespace epee void operator()(const from_type& v){convert_t(v, m_target);} }; + template template - bool portable_storage::get_value(const std::string& value_name, t_value& val, hsection hparent_section) + bool portable_storage_base::get_value(const std::string& value_name, t_value& val, hsection hparent_section) { BOOST_MPL_ASSERT(( boost::mpl::contains )); //TRY_ENTRY(); @@ -226,11 +232,11 @@ namespace epee get_value_visitor gvv(val); boost::apply_visitor(gvv, *pentry); return true; - //CATCH_ENTRY("portable_storage::template<>get_value", false); + //CATCH_ENTRY("portable_storage_base::template<>get_value", false); } //--------------------------------------------------------------------------------------------------------------- - inline - bool portable_storage::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section) + template + bool portable_storage_base::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::template<>get_value", false); } //--------------------------------------------------------------------------------------------------------------- + template template - bool portable_storage::set_value(const std::string& value_name, const t_value& v, hsection hparent_section) + bool portable_storage_base::set_value(const std::string& value_name, const t_value& v, hsection hparent_section) { BOOST_MPL_ASSERT(( boost::mpl::contains::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::template<>set_value", false); } //--------------------------------------------------------------------------------------------------------------- - inline - storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection) + template + storage_entry* portable_storage_base::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::find_storage_entry", nullptr); } //--------------------------------------------------------------------------------------------------------------- + template template - 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::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(pentry_name, entry)); return &ins_res.first->second; - CATCH_ENTRY("portable_storage::insert_new_entry_get_storage_entry", nullptr); + CATCH_ENTRY("portable_storage_base::insert_new_entry_get_storage_entry", nullptr); } //--------------------------------------------------------------------------------------------------------------- - inline - hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection) + template + typename portable_storage_base::hsection portable_storage_base::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
(*pse); - CATCH_ENTRY("portable_storage::insert_new_section", nullptr); + CATCH_ENTRY("portable_storage_base::insert_new_section", nullptr); } //--------------------------------------------------------------------------------------------------------------- template @@ -312,8 +320,9 @@ namespace epee } }; //--------------------------------------------------------------------------------------------------------------- + template template - harray portable_storage::get_first_value(const std::string& value_name, t_value& target, hsection hparent_section) + harray portable_storage_base::get_first_value(const std::string& value_name, t_value& target, hsection hparent_section) { BOOST_MPL_ASSERT(( boost::mpl::contains )); //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::get_first_value", nullptr); } //--------------------------------------------------------------------------------------------------------------- template @@ -348,10 +357,10 @@ namespace epee return true; } }; - - + //--------------------------------------------------------------------------------------------------------------- + template template - bool portable_storage::get_next_value(harray hval_array, t_value& target) + bool portable_storage_base::get_next_value(harray hval_array, t_value& target) { BOOST_MPL_ASSERT(( boost::mpl::contains )); //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::get_next_value", false); } //--------------------------------------------------------------------------------------------------------------- + template template - harray portable_storage::insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section) + harray portable_storage_base::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& arr_typed = boost::get >(arr); arr_typed.insert_first_val(target); return &arr; - CATCH_ENTRY("portable_storage::insert_first_value", nullptr); + CATCH_ENTRY("portable_storage_base::insert_first_value", nullptr); } //--------------------------------------------------------------------------------------------------------------- + template template - bool portable_storage::enum_entries(hsection hparent_section, cb_t cb) + bool portable_storage_base::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::enum_entries", false); } - + //--------------------------------------------------------------------------------------------------------------- + template template - bool portable_storage::insert_next_value(harray hval_array, const t_value& target) + bool portable_storage_base::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& arr_typed = boost::get >(*hval_array); arr_typed.insert_next_value(target); return true; - CATCH_ENTRY("portable_storage::insert_next_value", false); + CATCH_ENTRY("portable_storage_base::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 + harray portable_storage_base::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::get_first_section", nullptr); } //--------------------------------------------------------------------------------------------------------------- - inline - bool portable_storage::get_next_section(harray hsec_array, hsection& h_child_section) + template + bool portable_storage_base::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::get_next_section", false); } //--------------------------------------------------------------------------------------------------------------- - inline - harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section) + template + harray portable_storage_base::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
& sec_array = boost::get>(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::insert_first_section", nullptr); } //--------------------------------------------------------------------------------------------------------------- - inline - bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection) + template + bool portable_storage_base::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
& sec_array = boost::get>(*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::insert_next_section", false); } - //--------------------------------------------------------------------------------------------------------------- + //--------------------------------------------------------------------------------------------------------------- + typedef portable_storage_base
portable_storage; } } diff --git a/contrib/epee/include/storages/portable_storage_base.h b/contrib/epee/include/storages/portable_storage_base.h index 99c792e5..2f2ed5d1 100644 --- a/contrib/epee/include/storages/portable_storage_base.h +++ b/contrib/epee/include/storages/portable_storage_base.h @@ -153,6 +153,7 @@ namespace epee /************************************************************************/ struct section { + std::map m_descriptions; std::map m_entries; }; diff --git a/contrib/epee/include/storages/portable_storage_extended_for_doc.h b/contrib/epee/include/storages/portable_storage_extended_for_doc.h index 35de4c65..81e70ed9 100644 --- a/contrib/epee/include/storages/portable_storage_extended_for_doc.h +++ b/contrib/epee/include/storages/portable_storage_extended_for_doc.h @@ -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 - 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 - 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 - harray get_first_value(const std::string& value_name, t_value& target, hsection hparent_section); - template - bool get_next_value(harray hval_array, t_value& target); - template - harray insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section); - template - 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 - 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::dump_as_json", false) + } - template - 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 - 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); }; - //--------------------------------------------------------------------------------------------------------------- } } diff --git a/contrib/epee/include/storages/portable_storage_template_helper.h b/contrib/epee/include/storages/portable_storage_template_helper.h index 896f9eb2..841a094a 100644 --- a/contrib/epee/include/storages/portable_storage_template_helper.h +++ b/contrib/epee/include/storages/portable_storage_template_helper.h @@ -56,11 +56,11 @@ namespace epee } //----------------------------------------------------------------------------------------------------------- template - 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; } //----------------------------------------------------------------------------------------------------------- diff --git a/contrib/epee/include/storages/portable_storage_to_json.h b/contrib/epee/include/storages/portable_storage_to_json.h index 1e2d5d97..a118e755 100644 --- a/contrib/epee/include/storages/portable_storage_to_json.h +++ b/contrib/epee/include/storages/portable_storage_to_json.h @@ -35,169 +35,196 @@ namespace epee { namespace serialization { - - template - void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const std::string& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const int8_t& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const bool& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const double& v, size_t indent, end_of_line_t eol = eol_crlf); - template - void dump_as_json(t_stream& strm, const t_type& v, size_t indent, end_of_line_t eol = eol_crlf); - template - 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 - struct array_entry_store_to_json_visitor: public boost::static_visitor + 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 - void operator()(const array_entry_t& a) + public: + inline static const char* eol = get_endline(eol_crlf); + //static const end_of_line_t eol = eol_crlf; + template + 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 + static void handle_value(t_stream& strm, const int8_t& v, size_t indent) + { + strm << static_cast(v); + } + template + static void handle_value(t_stream& strm, const uint8_t& v, size_t indent) + { + strm << static_cast(v); + } + template + static void handle_value(t_stream& strm, const bool& v, size_t indent) + { + if (v) + strm << "true"; + else + strm << "false"; + } + template + 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 + static void handle_value(t_stream& strm, const t_type& v, size_t indent) + { + strm << v; + } + + template + static void handle_array_start(t_stream& strm, size_t indent) + { + strm << "["; + } + + template + static void handle_array_end(t_stream& strm, size_t indent) + { + strm << "]"; + } + + template + static void handle_obj_begin(t_stream& strm, size_t indent) + { + strm << "{"; + } + + template + static void handle_obj_end(t_stream& strm, size_t indent) + { + strm << "}"; + } + + template + 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 + class recursive_visitor + { + public: + template + struct array_entry_store_to_json_visitor : public boost::static_visitor + { + 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 + void operator()(const array_entry_t& 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 - struct storage_entry_store_to_json_visitor: public boost::static_visitor - { - 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 - void operator()(const visited_type& v) - { - dump_as_json(m_strm, v, m_indent, m_eol); - } - }; - - template - 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 aesv(strm, indent, eol); - boost::apply_visitor(aesv, ae); - } - - template - 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 sv(strm, indent, eol); - boost::apply_visitor(sv, se); - } - - template - 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 - void dump_as_json(t_stream& strm, const int8_t& v, size_t indent, end_of_line_t eol) - { - strm << static_cast(v); - } - - template - void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent, end_of_line_t eol) - { - strm << static_cast(v); - } - - template - 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 - 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 - void dump_as_json(t_stream& strm, const t_type& v, size_t indent, end_of_line_t eol) - { - strm << v; - } - - template - 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 + struct storage_entry_store_to_json_visitor : public boost::static_visitor { - 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 + 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 + void static dump_as_(t_stream& strm, const array_entry& ae, size_t indent) + { + array_entry_store_to_json_visitor aesv(strm, indent); + boost::apply_visitor(aesv, ae); } - strm << make_indent(indent) << "}"; - } + + template + void static dump_as_(t_stream& strm, const storage_entry& se, size_t indent) + { + storage_entry_store_to_json_visitor sv(strm, indent); + boost::apply_visitor(sv, se); + } + + template + void static dump_as_(t_stream& strm, const t_type& v, size_t indent) + { + t_strategy_layout_strategy::handle_value(strm, v, indent); + } + + template + 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); + } + }; + } } diff --git a/src/currency_protocol/currency_protocol_defs_print.h b/src/currency_protocol/currency_protocol_defs_print.h index 68f6fa4b..023ed305 100644 --- a/src/currency_protocol/currency_protocol_defs_print.h +++ b/src/currency_protocol/currency_protocol_defs_print.h @@ -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(); } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 056b3bfe..abf3e02e 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -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() }; };