Monero
Loading...
Searching...
No Matches
portable_storage.h
Go to the documentation of this file.
1// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution.
11// * Neither the name of the Andrey N. Sabelnikov nor the
12// names of its contributors may be used to endorse or promote products
13// derived from this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26
27#pragma once
28
31#include "misc_log_ex.h"
32#include "span.h"
33
34#include <boost/mpl/contains.hpp>
35
36namespace epee
37{
38 class byte_slice;
39 class byte_stream;
40 namespace serialization
41 {
42 /************************************************************************/
43 /* */
44 /************************************************************************/
46 {
47 public:
51
52 struct limits_t
53 {
54 size_t n_objects;
55 size_t n_fields;
56 size_t n_strings; // not counting field names
57 };
58
61 hsection open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist = false);
62 template<class t_value>
63 bool get_value(const std::string& value_name, t_value& val, hsection hparent_section);
64 bool get_value(const std::string& value_name, storage_entry& val, hsection hparent_section);
65 template<class t_value>
66 bool set_value(const std::string& value_name, t_value&& target, hsection hparent_section);
67
68 //serial access for arrays of values --------------------------------------
69 //values
70 template<class t_value>
71 harray get_first_value(const std::string& value_name, t_value& target, hsection hparent_section);
72 template<class t_value>
73 bool get_next_value(harray hval_array, t_value& target);
74 template<class t_value>
75 harray insert_first_value(const std::string& value_name, t_value&& target, hsection hparent_section);
76 template<class t_value>
77 bool insert_next_value(harray hval_array, t_value&& target);
78 //sections
79 harray get_first_section(const std::string& pSectionName, hsection& h_child_section, hsection hparent_section);
80 bool get_next_section(harray hSecArray, hsection& h_child_section);
81 harray insert_first_section(const std::string& pSectionName, hsection& hinserted_childsection, hsection hparent_section);
82 bool insert_next_section(harray hSecArray, hsection& hinserted_childsection);
83 //------------------------------------------------------------------------
84 //delete entry (section, value or array)
85 bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr);
86
87 //-------------------------------------------------------------------------------
88 bool store_to_binary(byte_slice& target, std::size_t initial_buffer_size = 8192);
90 bool load_from_binary(const epee::span<const uint8_t> target, const limits_t *limits = nullptr);
91 bool load_from_binary(const std::string& target, const limits_t *limits = nullptr)
92 {
93 return load_from_binary(epee::strspan<uint8_t>(target), limits);
94 }
95
96 template<class trace_policy>
97 bool dump_as_xml(std::string& targetObj, const std::string& root_name = "");
98 bool dump_as_json(std::string& targetObj, size_t indent = 0, bool insert_newlines = true);
99 bool load_from_json(const std::string& source);
100
101 private:
104 storage_entry* find_storage_entry(const std::string& pentry_name, hsection psection);
105 template<class entry_type>
106 storage_entry* insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, entry_type&& entry);
107
108 hsection insert_new_section(const std::string& pentry_name, hsection psection);
109
110#pragma pack(push)
111#pragma pack(1)
118#pragma pack(pop)
119 };
120
121 template<class trace_policy>
122 bool portable_storage::dump_as_xml(std::string& targetObj, const std::string& root_name)
123 {
124 return false;//TODO: don't think i ever again will use xml - ambiguous and "overtagged" format
125 }
126
127 template<class to_type>
128 struct get_value_visitor: boost::static_visitor<void>
129 {
130 to_type& m_target;
131 get_value_visitor(to_type& target):m_target(target){}
132 template<class from_type>
133 void operator()(const from_type& v){convert_t(v, m_target);}
134 };
135
136 template<class t_value>
137 bool portable_storage::get_value(const std::string& value_name, t_value& val, hsection hparent_section)
138 {
139 BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> ));
140 //TRY_ENTRY();
141 if(!hparent_section) hparent_section = &m_root;
142 storage_entry* pentry = find_storage_entry(value_name, hparent_section);
143 if(!pentry)
144 return false;
145
147 boost::apply_visitor(gvv, *pentry);
148 return true;
149 //CATCH_ENTRY("portable_storage::template<>get_value", false);
150 }
151 //---------------------------------------------------------------------------------------------------------------
152 template<class t_value>
153 bool portable_storage::set_value(const std::string& value_name, t_value&& v, hsection hparent_section)
154 {
155 using t_real_value = typename std::decay<t_value>::type;
156 BOOST_MPL_ASSERT(( boost::mpl::contains<boost::mpl::push_front<storage_entry::types, storage_entry>::type, t_real_value> ));
157 TRY_ENTRY();
158 if(!hparent_section)
159 hparent_section = &m_root;
160 storage_entry* pentry = find_storage_entry(value_name, hparent_section);
161 if(!pentry)
162 {
163 pentry = insert_new_entry_get_storage_entry(value_name, hparent_section, std::forward<t_value>(v));
164 if(!pentry)
165 return false;
166 return true;
167 }
168 *pentry = std::forward<t_value>(v);
169 return true;
170 CATCH_ENTRY("portable_storage::template<>set_value", false);
171 }
172 //---------------------------------------------------------------------------------------------------------------
173 template<class entry_type>
174 storage_entry* portable_storage::insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, entry_type&& entry)
175 {
176 static_assert(std::is_rvalue_reference<entry_type&&>(), "unexpected copy of value");
177 TRY_ENTRY();
178 CHECK_AND_ASSERT(psection, nullptr);
179 CHECK_AND_ASSERT(!pentry_name.empty(), nullptr);
180 auto ins_res = psection->m_entries.emplace(pentry_name, std::forward<entry_type>(entry));
181 return &ins_res.first->second;
182 CATCH_ENTRY("portable_storage::insert_new_entry_get_storage_entry", nullptr);
183 }
184 //---------------------------------------------------------------------------------------------------------------
185 template<class to_type>
186 struct get_first_value_visitor: boost::static_visitor<bool>
187 {
188 to_type& m_target;
189 get_first_value_visitor(to_type& target):m_target(target){}
190 template<class from_type>
192 {
193 const from_type* pv = a.get_first_val();
194 if(!pv)
195 return false;
196 convert_t(*pv, m_target);
197 return true;
198 }
199 };
200 //---------------------------------------------------------------------------------------------------------------
201 template<class t_value>
202 harray portable_storage::get_first_value(const std::string& value_name, t_value& target, hsection hparent_section)
203 {
204 BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> ));
205 //TRY_ENTRY();
206 if(!hparent_section) hparent_section = &m_root;
207 storage_entry* pentry = find_storage_entry(value_name, hparent_section);
208 if(!pentry)
209 return nullptr;
210 if(pentry->type() != typeid(array_entry))
211 return nullptr;
212 array_entry& ar_entry = boost::get<array_entry>(*pentry);
213
215 if(!boost::apply_visitor(gfv, ar_entry))
216 return nullptr;
217 return &ar_entry;
218 //CATCH_ENTRY("portable_storage::get_first_value", nullptr);
219 }
220 //---------------------------------------------------------------------------------------------------------------
221 template<class to_type>
222 struct get_next_value_visitor: boost::static_visitor<bool>
223 {
224 to_type& m_target;
225 get_next_value_visitor(to_type& target):m_target(target){}
226 template<class from_type>
228 {
229 //TODO: optimize code here: work without get_next_val function
230 const from_type* pv = a.get_next_val();
231 if(!pv)
232 return false;
233 convert_t(*pv, m_target);
234 return true;
235 }
236 };
237
238 template<class t_value>
239 bool portable_storage::get_next_value(harray hval_array, t_value& target)
240 {
241 BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> ));
242 //TRY_ENTRY();
243 CHECK_AND_ASSERT(hval_array, false);
244 array_entry& ar_entry = *hval_array;
246 if(!boost::apply_visitor(gnv, ar_entry))
247 return false;
248 return true;
249 //CATCH_ENTRY("portable_storage::get_next_value", false);
250 }
251 //---------------------------------------------------------------------------------------------------------------
252 template<class t_value>
253 harray portable_storage::insert_first_value(const std::string& value_name, t_value&& target, hsection hparent_section)
254 {
255 using t_real_value = typename std::decay<t_value>::type;
256 static_assert(std::is_rvalue_reference<t_value&&>(), "unexpected copy of value");
257 TRY_ENTRY();
258 if(!hparent_section) hparent_section = &m_root;
259 storage_entry* pentry = find_storage_entry(value_name, hparent_section);
260 if(!pentry)
261 {
262 pentry = insert_new_entry_get_storage_entry(value_name, hparent_section, array_entry(array_entry_t<t_real_value>()));
263 if(!pentry)
264 return nullptr;
265 }
266 if(pentry->type() != typeid(array_entry))
268
269 array_entry& arr = boost::get<array_entry>(*pentry);
270 if(arr.type() != typeid(array_entry_t<t_real_value>))
272
273 array_entry_t<t_real_value>& arr_typed = boost::get<array_entry_t<t_real_value> >(arr);
274 arr_typed.insert_first_val(std::forward<t_value>(target));
275 return &arr;
276 CATCH_ENTRY("portable_storage::insert_first_value", nullptr);
277 }
278 //---------------------------------------------------------------------------------------------------------------
279 template<class t_value>
280 bool portable_storage::insert_next_value(harray hval_array, t_value&& target)
281 {
282 using t_real_value = typename std::decay<t_value>::type;
283 static_assert(std::is_rvalue_reference<t_value&&>(), "unexpected copy of value");
284 TRY_ENTRY();
285 CHECK_AND_ASSERT(hval_array, false);
286
287 CHECK_AND_ASSERT_MES(hval_array->type() == typeid(array_entry_t<t_real_value>),
288 false, "unexpected type in insert_next_value: " << typeid(array_entry_t<t_real_value>).name());
289
290 array_entry_t<t_real_value>& arr_typed = boost::get<array_entry_t<t_real_value> >(*hval_array);
291 arr_typed.insert_next_value(std::forward<t_value>(target));
292 return true;
293 CATCH_ENTRY("portable_storage::insert_next_value", false);
294 }
295 }
296}
Definition byte_slice.h:69
A partial drop-in replacement for std::ostream.
Definition byte_stream.h:58
bool load_from_binary(const epee::span< const uint8_t > target, const limits_t *limits=nullptr)
Definition portable_storage.cpp:87
storage_entry * insert_new_entry_get_storage_entry(const std::string &pentry_name, hsection psection, entry_type &&entry)
Definition portable_storage.h:174
bool get_value(const std::string &value_name, t_value &val, hsection hparent_section)
Definition portable_storage.h:137
epee::serialization::hsection hsection
Definition portable_storage.h:48
bool delete_entry(const std::string &pentry_name, hsection hparent_section=nullptr)
bool store_to_binary(byte_slice &target, std::size_t initial_buffer_size=8192)
Definition portable_storage.cpp:46
harray get_first_value(const std::string &value_name, t_value &target, hsection hparent_section)
Definition portable_storage.h:202
storage_entry meta_entry
Definition portable_storage.h:50
bool set_value(const std::string &value_name, t_value &&target, hsection hparent_section)
Definition portable_storage.h:153
harray insert_first_section(const std::string &pSectionName, hsection &hinserted_childsection, hsection hparent_section)
Definition portable_storage.cpp:210
harray get_first_section(const std::string &pSectionName, hsection &h_child_section, hsection hparent_section)
Definition portable_storage.cpp:175
bool insert_next_section(harray hSecArray, hsection &hinserted_childsection)
Definition portable_storage.cpp:234
bool insert_next_value(harray hval_array, t_value &&target)
Definition portable_storage.h:280
virtual ~portable_storage()
Definition portable_storage.h:60
bool dump_as_xml(std::string &targetObj, const std::string &root_name="")
Definition portable_storage.h:122
bool load_from_binary(const std::string &target, const limits_t *limits=nullptr)
Definition portable_storage.h:91
hsection open_section(const std::string &section_name, hsection hparent_section, bool create_if_notexist=false)
Definition portable_storage.cpp:117
harray insert_first_value(const std::string &value_name, t_value &&target, hsection hparent_section)
Definition portable_storage.h:253
portable_storage()
Definition portable_storage.h:59
bool get_next_value(harray hval_array, t_value &target)
Definition portable_storage.h:239
bool dump_as_json(std::string &targetObj, size_t indent=0, bool insert_newlines=true)
Definition portable_storage.cpp:70
epee::serialization::harray harray
Definition portable_storage.h:49
storage_entry * find_storage_entry(const std::string &pentry_name, hsection psection)
Definition portable_storage.cpp:154
section m_root
Definition portable_storage.h:102
bool load_from_json(const std::string &source)
Definition portable_storage.cpp:80
hsection insert_new_section(const std::string &pentry_name, hsection psection)
Definition portable_storage.cpp:166
hsection get_root_section()
Definition portable_storage.h:103
bool get_next_section(harray hSecArray, hsection &h_child_section)
Definition portable_storage.cpp:196
Non-owning sequence of data. Does not deep copy.
Definition span.h:55
Definition keyvalue_serialization_overloads.h:49
section * hsection
Definition portable_storage_base.h:174
void convert_t(const from_type &from, to_type &to)
Definition portable_storage_val_converters.h:203
boost::variant< uint64_t, uint32_t, uint16_t, uint8_t, int64_t, int32_t, int16_t, int8_t, double, bool, std::string, section, array_entry > storage_entry
Definition portable_storage_base.h:161
boost::make_recursive_variant< array_entry_t< section >, array_entry_t< uint64_t >, array_entry_t< uint32_t >, array_entry_t< uint16_t >, array_entry_t< uint8_t >, array_entry_t< int64_t >, array_entry_t< int32_t >, array_entry_t< int16_t >, array_entry_t< int8_t >, array_entry_t< double >, array_entry_t< bool >, array_entry_t< std::string >, array_entry_t< section >, array_entry_t< boost::recursive_variant_ > >::type array_entry
Definition portable_storage_base.h:159
array_entry * harray
Definition portable_storage_base.h:175
TODO: (mj-xmr) This will be reduced in an another PR.
Definition byte_slice.h:40
span< const T > strspan(const U &s) noexcept
make a span from a std::string
Definition span.h:183
const CharType(& source)[N]
Definition pointer.h:1147
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
unsigned int uint32_t
Definition stdint.h:126
unsigned char uint8_t
Definition stdint.h:124
Definition portable_storage_base.h:83
t_entry_type & insert_first_val(t_entry_type &&v)
Definition portable_storage_base.h:121
t_entry_type & insert_next_value(t_entry_type &&v)
Definition portable_storage_base.h:128
Definition portable_storage.h:187
to_type & m_target
Definition portable_storage.h:188
get_first_value_visitor(to_type &target)
Definition portable_storage.h:189
bool operator()(const array_entry_t< from_type > &a)
Definition portable_storage.h:191
Definition portable_storage.h:223
bool operator()(const array_entry_t< from_type > &a)
Definition portable_storage.h:227
get_next_value_visitor(to_type &target)
Definition portable_storage.h:225
to_type & m_target
Definition portable_storage.h:224
Definition portable_storage.h:129
void operator()(const from_type &v)
Definition portable_storage.h:133
get_value_visitor(to_type &target)
Definition portable_storage.h:131
to_type & m_target
Definition portable_storage.h:130
Definition portable_storage.h:53
size_t n_objects
Definition portable_storage.h:54
size_t n_fields
Definition portable_storage.h:55
size_t n_strings
Definition portable_storage.h:56
uint32_t m_signature_b
Definition portable_storage.h:115
uint8_t m_ver
Definition portable_storage.h:116
uint32_t m_signature_a
Definition portable_storage.h:114
Definition portable_storage_base.h:169
std::map< std::string, storage_entry > m_entries
Definition portable_storage_base.h:170