Monero
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 
29 #include "portable_storage_base.h"
31 #include "misc_log_ex.h"
32 #include "span.h"
33 
34 #include <boost/mpl/contains.hpp>
35 
36 namespace 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 
60  virtual ~portable_storage(){}
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);
89  bool store_to_binary(byte_stream& ss);
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)
113  {
117  };
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>
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: binary_utils.h:36
bool delete_entry(const std::string &pentry_name, hsection hparent_section=nullptr)
t_entry_type & insert_next_value(t_entry_type &&v)
Definition: portable_storage_base.h:128
harray get_first_value(const std::string &value_name, t_value &target, hsection hparent_section)
Definition: portable_storage.h:202
const CharType(& source)[N]
Definition: pointer.h:1147
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
array_entry * harray
Definition: portable_storage_base.h:175
hsection open_section(const std::string &section_name, hsection hparent_section, bool create_if_notexist=false)
Definition: portable_storage.cpp:117
to_type & m_target
Definition: portable_storage.h:224
bool operator()(const array_entry_t< from_type > &a)
Definition: portable_storage.h:227
bool get_value(const std::string &value_name, t_value &val, hsection hparent_section)
Definition: portable_storage.h:137
::std::string string
Definition: gtest-port.h:1097
storage_entry meta_entry
Definition: portable_storage.h:50
A partial drop-in replacement for std::ostream.
Definition: byte_stream.h:57
bool dump_as_xml(std::string &targetObj, const std::string &root_name="")
Definition: portable_storage.h:122
epee::serialization::hsection hsection
Definition: portable_storage.h:48
int type
Definition: superscalar.cpp:50
bool get_next_value(harray hval_array, t_value &target)
Definition: portable_storage.h:239
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
uint32_t m_signature_b
Definition: portable_storage.h:115
Non-owning sequence of data. Does not deep copy.
Definition: span.h:54
void convert_t(const from_type &from, to_type &to)
Definition: portable_storage_val_converters.h:203
uint32_t m_signature_a
Definition: portable_storage.h:114
Definition: portable_storage.h:45
unsigned char uint8_t
Definition: stdint.h:124
bool operator()(const array_entry_t< from_type > &a)
Definition: portable_storage.h:191
Definition: portable_storage_base.h:82
Definition: portable_storage.h:186
bool dump_as_json(std::string &targetObj, size_t indent=0, bool insert_newlines=true)
Definition: portable_storage.cpp:70
t_entry_type & insert_first_val(t_entry_type &&v)
Definition: portable_storage_base.h:121
bool get_next_section(harray hSecArray, hsection &h_child_section)
Definition: portable_storage.cpp:196
harray insert_first_section(const std::string &pSectionName, hsection &hinserted_childsection, hsection hparent_section)
Definition: portable_storage.cpp:210
bool insert_next_value(harray hval_array, t_value &&target)
Definition: portable_storage.h:280
unsigned int uint32_t
Definition: stdint.h:126
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
hsection insert_new_section(const std::string &pentry_name, hsection psection)
Definition: portable_storage.cpp:166
bool load_from_json(const std::string &source)
Definition: portable_storage.cpp:80
Definition: byte_slice.h:68
to_type & m_target
Definition: portable_storage.h:188
void operator()(const from_type &v)
Definition: portable_storage.h:133
harray insert_first_value(const std::string &value_name, t_value &&target, hsection hparent_section)
Definition: portable_storage.h:253
epee::serialization::harray harray
Definition: portable_storage.h:49
size_t n_strings
Definition: portable_storage.h:56
Definition: portable_storage_base.h:168
bool set_value(const std::string &value_name, t_value &&target, hsection hparent_section)
Definition: portable_storage.h:153
size_t n_objects
Definition: portable_storage.h:54
size_t n_fields
Definition: portable_storage.h:55
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
virtual ~portable_storage()
Definition: portable_storage.h:60
TODO: (mj-xmr) This will be reduced in an another PR.
Definition: byte_slice.h:39
hsection get_root_section()
Definition: portable_storage.h:103
to_type & m_target
Definition: portable_storage.h:130
get_first_value_visitor(to_type &target)
Definition: portable_storage.h:189
Definition: portable_storage.h:222
Definition: portable_storage.h:52
bool store_to_binary(byte_slice &target, std::size_t initial_buffer_size=8192)
Definition: portable_storage.cpp:46
get_next_value_visitor(to_type &target)
Definition: portable_storage.h:225
bool insert_next_section(harray hSecArray, hsection &hinserted_childsection)
Definition: portable_storage.cpp:234
bool load_from_binary(const std::string &target, const limits_t *limits=nullptr)
Definition: portable_storage.h:91
harray get_first_section(const std::string &pSectionName, hsection &h_child_section, hsection hparent_section)
Definition: portable_storage.cpp:175
portable_storage()
Definition: portable_storage.h:59
bool load_from_binary(const epee::span< const uint8_t > target, const limits_t *limits=nullptr)
Definition: portable_storage.cpp:87
std::map< std::string, storage_entry > m_entries
Definition: portable_storage_base.h:170
get_value_visitor(to_type &target)
Definition: portable_storage.h:131
Definition: portable_storage.h:128
storage_entry * insert_new_entry_get_storage_entry(const std::string &pentry_name, hsection psection, entry_type &&entry)
Definition: portable_storage.h:174
uint8_t m_ver
Definition: portable_storage.h:116
indent
Definition: transfer.py:36