Monero
Loading...
Searching...
No Matches
serialization.h
Go to the documentation of this file.
1// Copyright (c) 2014-2022, 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
57template <class T>
58struct is_blob_type { typedef boost::false_type type; };
59
64template <class T>
65struct has_free_serializer { typedef boost::true_type type; };
66
71template <class T>
72struct is_basic_type { typedef boost::false_type type; };
73
74template<typename F, typename S>
75struct is_basic_type<std::pair<F,S>> { typedef boost::true_type type; };
76template<>
77struct is_basic_type<std::string> { typedef boost::true_type type; };
78
92template <class Archive, class T>
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
123template <class Archive, class T>
124inline bool do_serialize(Archive &ar, T &v)
125{
126 return ::serializer<Archive, T>::serialize(ar, v);
127}
128template <class Archive>
129inline bool do_serialize(Archive &ar, bool &v)
130{
131 ar.serialize_blob(&v, sizeof(v));
132 return true;
133}
134
135/* the following add a trait to a set and define the serialization DSL*/
136
141#define BLOB_SERIALIZER(T) \
142 template<> \
143 struct is_blob_type<T> { \
144 typedef boost::true_type type; \
145 }
146
151#define FREE_SERIALIZER(T) \
152 template<> \
153 struct has_free_serializer<T> { \
154 typedef boost::true_type type; \
155 }
156
161#define VARIANT_TAG(Archive, Type, Tag) \
162 template <bool W> \
163 struct variant_serialization_traits<Archive<W>, Type> { \
164 static inline typename Archive<W>::variant_tag_type get_tag() { \
165 return Tag; \
166 } \
167 }
168
175#define BEGIN_SERIALIZE() \
176 template <bool W, template <bool> class Archive> \
177 bool do_serialize(Archive<W> &ar) {
178
184#define BEGIN_SERIALIZE_OBJECT() \
185 template <bool W, template <bool> class Archive> \
186 bool do_serialize(Archive<W> &ar) { \
187 ar.begin_object(); \
188 bool r = do_serialize_object(ar); \
189 ar.end_object(); \
190 return r; \
191 } \
192 template <bool W, template <bool> class Archive> \
193 bool do_serialize_object(Archive<W> &ar){
194
197#define PREPARE_CUSTOM_VECTOR_SERIALIZATION(size, vec) \
198 ::serialization::detail::prepare_custom_vector_serialization(size, vec, typename Archive<W>::is_saving())
199
202#define PREPARE_CUSTOM_DEQUE_SERIALIZATION(size, vec) \
203 ::serialization::detail::prepare_custom_deque_serialization(size, vec, typename Archive<W>::is_saving())
204
208#define END_SERIALIZE() \
209 return ar.good(); \
210 }
211
215#define VALUE(f) \
216 do { \
217 ar.tag(#f); \
218 bool r = ::do_serialize(ar, f); \
219 if (!r || !ar.good()) return false; \
220 } while(0);
221
226#define FIELD_N(t, f) \
227 do { \
228 ar.tag(t); \
229 bool r = ::do_serialize(ar, f); \
230 if (!r || !ar.good()) return false; \
231 } while(0);
232
237#define FIELD(f) \
238 do { \
239 ar.tag(#f); \
240 bool r = ::do_serialize(ar, f); \
241 if (!r || !ar.good()) return false; \
242 } while(0);
243
248#define FIELDS(f) \
249 do { \
250 bool r = ::do_serialize(ar, f); \
251 if (!r || !ar.good()) return false; \
252 } while(0);
253
257#define VARINT_FIELD(f) \
258 do { \
259 ar.tag(#f); \
260 ar.serialize_varint(f); \
261 if (!ar.good()) return false; \
262 } while(0);
263
268#define VARINT_FIELD_N(t, f) \
269 do { \
270 ar.tag(t); \
271 ar.serialize_varint(f); \
272 if (!ar.good()) return false; \
273 } while(0);
274
277#define MAGIC_FIELD(m) \
278 std::string magic = m; \
279 do { \
280 ar.tag("magic"); \
281 ar.serialize_blob((void*)magic.data(), magic.size()); \
282 if (!ar.good()) return false; \
283 if (magic != m) return false; \
284 } while(0);
285
288#define VERSION_FIELD(v) \
289 uint32_t version = v; \
290 do { \
291 ar.tag("version"); \
292 ar.serialize_varint(version); \
293 if (!ar.good()) return false; \
294 } while(0);
295
296
297namespace serialization {
303 namespace detail
304 {
309 template <typename T>
310 void prepare_custom_vector_serialization(size_t size, std::vector<T>& vec, const boost::mpl::bool_<true>& /*is_saving*/)
311 {
312 }
313
314 template <typename T>
315 void prepare_custom_vector_serialization(size_t size, std::vector<T>& vec, const boost::mpl::bool_<false>& /*is_saving*/)
316 {
317 vec.resize(size);
318 }
319
320 template <typename T>
321 void prepare_custom_deque_serialization(size_t size, std::deque<T>& vec, const boost::mpl::bool_<true>& /*is_saving*/)
322 {
323 }
324
325 template <typename T>
326 void prepare_custom_deque_serialization(size_t size, std::deque<T>& vec, const boost::mpl::bool_<false>& /*is_saving*/)
327 {
328 vec.resize(size);
329 }
330
335 template<class Archive>
336 bool do_check_stream_state(Archive& ar, boost::mpl::bool_<true>, bool noeof)
337 {
338 return ar.good();
339 }
346 template<class Archive>
347 bool do_check_stream_state(Archive& ar, boost::mpl::bool_<false>, bool noeof)
348 {
349 bool result = false;
350 if (ar.good())
351 {
352 result = noeof || ar.eof();
353 }
354 return result;
355 }
356 }
357
362 template<class Archive>
363 bool check_stream_state(Archive& ar, bool noeof = false)
364 {
365 return detail::do_check_stream_state(ar, typename Archive::is_saving(), noeof);
366 }
367
372 template <class Archive, class T>
373 inline bool serialize(Archive &ar, T &v)
374 {
375 bool r = do_serialize(ar, v);
376 return r && check_stream_state(ar, false);
377 }
378
383 template <class Archive, class T>
384 inline bool serialize_noeof(Archive &ar, T &v)
385 {
386 bool r = do_serialize(ar, v);
387 return r && check_stream_state(ar, true);
388 }
389}
binary_archive< false > ar
Definition: cold-outputs.cpp:54
bool do_serialize(Archive< false > &ar, std::vector< T > &v)
Definition: containers.h:109
declaration and default definition for the functions used the API
Definition: expect.cpp:34
bool do_check_stream_state(Archive &ar, boost::mpl::bool_< true >, bool noeof)
Definition: serialization.h:336
void prepare_custom_deque_serialization(size_t size, std::deque< T > &vec, const boost::mpl::bool_< true > &)
Definition: serialization.h:321
void prepare_custom_vector_serialization(size_t size, std::vector< T > &vec, const boost::mpl::bool_< true > &)
Definition: serialization.h:310
Definition: binary_utils.h:36
bool serialize_noeof(Archive &ar, T &v)
Definition: serialization.h:384
bool check_stream_state(Archive &ar, bool noeof=false)
Definition: serialization.h:363
bool serialize(Archive &ar, T &v)
Definition: serialization.h:373
Definition: enums.h:68
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
bool do_serialize(Archive &ar, T &v)
just calls the serialize function defined for ar and v...
Definition: serialization.h:124
tools::wallet2::message_signature_result_t result
Definition: signature.cpp:62
bool good() const noexcept
Definition: binary_archive.h:99
bool eof() const noexcept
If implementing as std::istream, reset stream error state after peek() call.
Definition: binary_archive.h:103
void serialize_blob(void *buf, size_t len, const char *delimiter="")
Definition: binary_archive.h:130
void serialize_int(T &v)
Definition: binary_archive.h:107
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
#define T(x)