Monero
serialization.h
Go to the documentation of this file.
1 // Copyright (c) 2014-2020, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30 
42 #pragma once
43 #include <vector>
44 #include <deque>
45 #include <list>
46 #include <set>
47 #include <unordered_set>
48 #include <string>
49 #include <boost/type_traits/is_integral.hpp>
50 #include <boost/type_traits/integral_constant.hpp>
51 #include <boost/mpl/bool.hpp>
52 
57 template <class T>
58 struct is_blob_type { typedef boost::false_type type; };
59 
64 template <class T>
66 
71 template <class T>
72 struct is_basic_type { typedef boost::false_type type; };
73 
74 template<typename F, typename S>
75 struct is_basic_type<std::pair<F,S>> { typedef boost::true_type type; };
76 template<>
77 struct is_basic_type<std::string> { typedef boost::true_type type; };
78 
92 template <class Archive, class T>
93 struct serializer{
94  static bool serialize(Archive &ar, T &v) {
95  return serialize(ar, v, typename boost::is_integral<T>::type(), typename is_blob_type<T>::type(), typename is_basic_type<T>::type());
96  }
97  template<typename A>
98  static bool serialize(Archive &ar, T &v, boost::false_type, boost::true_type, A a) {
99  ar.serialize_blob(&v, sizeof(v));
100  return true;
101  }
102  template<typename A>
103  static bool serialize(Archive &ar, T &v, boost::true_type, boost::false_type, A a) {
104  ar.serialize_int(v);
105  return true;
106  }
107  static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::false_type) {
108  //serialize_custom(ar, v, typename has_free_serializer<T>::type());
109  return v.do_serialize(ar);
110  }
111  static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::true_type) {
112  //serialize_custom(ar, v, typename has_free_serializer<T>::type());
113  return do_serialize(ar, v);
114  }
115  static void serialize_custom(Archive &ar, T &v, boost::true_type) {
116  }
117 };
118 
123 template <class Archive, class T>
124 inline bool do_serialize(Archive &ar, T &v)
125 {
127 }
128 template <class Archive>
129 inline bool do_serialize(Archive &ar, bool &v)
130 {
131  ar.serialize_blob(&v, sizeof(v));
132  return true;
133 }
134 
135 // Never used in the code base
136 // #ifndef __GNUC__
137 // #ifndef constexpr
138 // #define constexpr
139 // #endif
140 // #endif
141 
142 /* the following add a trait to a set and define the serialization DSL*/
143 
148 #define BLOB_SERIALIZER(T) \
149  template<> \
150  struct is_blob_type<T> { \
151  typedef boost::true_type type; \
152  }
153 
158 #define FREE_SERIALIZER(T) \
159  template<> \
160  struct has_free_serializer<T> { \
161  typedef boost::true_type type; \
162  }
163 
168 #define VARIANT_TAG(Archive, Type, Tag) \
169  template <bool W> \
170  struct variant_serialization_traits<Archive<W>, Type> { \
171  static inline typename Archive<W>::variant_tag_type get_tag() { \
172  return Tag; \
173  } \
174  }
175 
182 #define BEGIN_SERIALIZE() \
183  template <bool W, template <bool> class Archive> \
184  bool do_serialize(Archive<W> &ar) {
185 
191 #define BEGIN_SERIALIZE_OBJECT() \
192  template <bool W, template <bool> class Archive> \
193  bool do_serialize(Archive<W> &ar) { \
194  ar.begin_object(); \
195  bool r = do_serialize_object(ar); \
196  ar.end_object(); \
197  return r; \
198  } \
199  template <bool W, template <bool> class Archive> \
200  bool do_serialize_object(Archive<W> &ar){
201 
204 #define PREPARE_CUSTOM_VECTOR_SERIALIZATION(size, vec) \
205  ::serialization::detail::prepare_custom_vector_serialization(size, vec, typename Archive<W>::is_saving())
206 
209 #define PREPARE_CUSTOM_DEQUE_SERIALIZATION(size, vec) \
210  ::serialization::detail::prepare_custom_deque_serialization(size, vec, typename Archive<W>::is_saving())
211 
215 #define END_SERIALIZE() \
216  return ar.stream().good(); \
217  }
218 
222 #define VALUE(f) \
223  do { \
224  ar.tag(#f); \
225  bool r = ::do_serialize(ar, f); \
226  if (!r || !ar.stream().good()) return false; \
227  } while(0);
228 
233 #define FIELD_N(t, f) \
234  do { \
235  ar.tag(t); \
236  bool r = ::do_serialize(ar, f); \
237  if (!r || !ar.stream().good()) return false; \
238  } while(0);
239 
244 #define FIELD(f) \
245  do { \
246  ar.tag(#f); \
247  bool r = ::do_serialize(ar, f); \
248  if (!r || !ar.stream().good()) return false; \
249  } while(0);
250 
255 #define FIELDS(f) \
256  do { \
257  bool r = ::do_serialize(ar, f); \
258  if (!r || !ar.stream().good()) return false; \
259  } while(0);
260 
264 #define VARINT_FIELD(f) \
265  do { \
266  ar.tag(#f); \
267  ar.serialize_varint(f); \
268  if (!ar.stream().good()) return false; \
269  } while(0);
270 
275 #define VARINT_FIELD_N(t, f) \
276  do { \
277  ar.tag(t); \
278  ar.serialize_varint(f); \
279  if (!ar.stream().good()) return false; \
280  } while(0);
281 
284 #define MAGIC_FIELD(m) \
285  std::string magic = m; \
286  do { \
287  ar.tag("magic"); \
288  ar.serialize_blob((void*)magic.data(), magic.size()); \
289  if (!ar.stream().good()) return false; \
290  if (magic != m) return false; \
291  } while(0);
292 
295 #define VERSION_FIELD(v) \
296  uint32_t version = v; \
297  do { \
298  ar.tag("version"); \
299  ar.serialize_varint(version); \
300  if (!ar.stream().good()) return false; \
301  } while(0);
302 
303 
304 namespace serialization {
310  namespace detail
311  {
316  template <typename T>
317  void prepare_custom_vector_serialization(size_t size, std::vector<T>& vec, const boost::mpl::bool_<true>& /*is_saving*/)
318  {
319  }
320 
321  template <typename T>
322  void prepare_custom_vector_serialization(size_t size, std::vector<T>& vec, const boost::mpl::bool_<false>& /*is_saving*/)
323  {
324  vec.resize(size);
325  }
326 
327  template <typename T>
328  void prepare_custom_deque_serialization(size_t size, std::deque<T>& vec, const boost::mpl::bool_<true>& /*is_saving*/)
329  {
330  }
331 
332  template <typename T>
333  void prepare_custom_deque_serialization(size_t size, std::deque<T>& vec, const boost::mpl::bool_<false>& /*is_saving*/)
334  {
335  vec.resize(size);
336  }
337 
342  template<class Stream>
343  bool do_check_stream_state(Stream& s, boost::mpl::bool_<true>, bool noeof)
344  {
345  return s.good();
346  }
353  template<class Stream>
354  bool do_check_stream_state(Stream& s, boost::mpl::bool_<false>, bool noeof)
355  {
356  bool result = false;
357  if (s.good())
358  {
359  std::ios_base::iostate state = s.rdstate();
360  result = noeof || EOF == s.peek();
361  s.clear(state);
362  }
363  return result;
364  }
365  }
366 
371  template<class Archive>
372  bool check_stream_state(Archive& ar, bool noeof = false)
373  {
374  return detail::do_check_stream_state(ar.stream(), typename Archive::is_saving(), noeof);
375  }
376 
381  template <class Archive, class T>
382  inline bool serialize(Archive &ar, T &v)
383  {
384  bool r = do_serialize(ar, v);
385  return r && check_stream_state(ar, false);
386  }
387 
392  template <class Archive, class T>
393  inline bool serialize_noeof(Archive &ar, T &v)
394  {
395  bool r = do_serialize(ar, v);
396  return r && check_stream_state(ar, true);
397  }
398 }
#define s(x, c)
Definition: aesb.c:47
const uint32_t T[512]
Definition: groestl_tables.h:36
string a
Definition: MakeCryptoOps.py:15
declaration and default definition for the functions used the API
Definition: expect.cpp:34
void prepare_custom_deque_serialization(size_t size, std::deque< T > &vec, const boost::mpl::bool_< true > &)
Definition: serialization.h:328
void prepare_custom_vector_serialization(size_t size, std::vector< T > &vec, const boost::mpl::bool_< true > &)
Definition: serialization.h:317
bool do_check_stream_state(Stream &s, boost::mpl::bool_< true >, bool noeof)
Definition: serialization.h:343
Definition: binary_utils.h:36
bool serialize_noeof(Archive &ar, T &v)
Definition: serialization.h:393
bool check_stream_state(Archive &ar, bool noeof=false)
Definition: serialization.h:372
bool serialize(Archive &ar, T &v)
Definition: serialization.h:382
char true_type
Definition: sfinae_helpers.h:39
Definition: blockchain_ancestry.cpp:72
bool do_serialize(Archive &ar, T &v)
just calls the serialize function defined for ar and v...
Definition: serialization.h:124
a descriptor for dispatching serialize
Definition: serialization.h:65
boost::true_type type
Definition: serialization.h:65
boost::true_type type
Definition: serialization.h:75
boost::true_type type
Definition: serialization.h:77
a descriptor for dispatching serialize
Definition: serialization.h:72
boost::false_type type
Definition: serialization.h:72
a descriptor for dispatching serialize
Definition: serialization.h:58
boost::false_type type
Definition: serialization.h:58
... wouldn't a class be better?
Definition: serialization.h:93
static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::false_type)
Definition: serialization.h:107
static void serialize_custom(Archive &ar, T &v, boost::true_type)
Definition: serialization.h:115
static bool serialize(Archive &ar, T &v, boost::false_type, boost::true_type, A a)
Definition: serialization.h:98
static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::true_type)
Definition: serialization.h:111
static bool serialize(Archive &ar, T &v)
Definition: serialization.h:94
static bool serialize(Archive &ar, T &v, boost::true_type, boost::false_type, A a)
Definition: serialization.h:103
Definition: blake256.h:36