Electroneum
Loading...
Searching...
No Matches
serialization.h
Go to the documentation of this file.
1// Copyright (c) 2014-2019, 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
41
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
56template <class T>
57struct is_blob_type { typedef boost::false_type type; };
58
63template <class T>
64struct has_free_serializer { typedef boost::true_type type; };
65
70template <class T>
71struct is_basic_type { typedef boost::false_type type; };
72
73template<typename F, typename S>
74struct is_basic_type<std::pair<F,S>> { typedef boost::true_type type; };
75template<>
76struct is_basic_type<std::string> { typedef boost::true_type type; };
77
91template <class Archive, class T>
93 static bool serialize(Archive &ar, T &v) {
94 return serialize(ar, v, typename boost::is_integral<T>::type(), typename is_blob_type<T>::type(), typename is_basic_type<T>::type());
95 }
96 template<typename A>
97 static bool serialize(Archive &ar, T &v, boost::false_type, boost::true_type, A a) {
98 ar.serialize_blob(&v, sizeof(v));
99 return true;
100 }
101 template<typename A>
102 static bool serialize(Archive &ar, T &v, boost::true_type, boost::false_type, A a) {
103 ar.serialize_int(v);
104 return true;
105 }
106 static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::false_type) {
107 //serialize_custom(ar, v, typename has_free_serializer<T>::type());
108 return v.do_serialize(ar);
109 }
110 static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::true_type) {
111 //serialize_custom(ar, v, typename has_free_serializer<T>::type());
112 return do_serialize(ar, v);
113 }
114 static void serialize_custom(Archive &ar, T &v, boost::true_type) {
115 }
116};
117
122template <class Archive, class T>
123inline bool do_serialize(Archive &ar, T &v)
124{
125 return ::serializer<Archive, T>::serialize(ar, v);
126}
127template <class Archive>
128inline bool do_serialize(Archive &ar, bool &v)
129{
130 ar.serialize_blob(&v, sizeof(v));
131 return true;
132}
133
134// Never used in the code base
135// #ifndef __GNUC__
136// #ifndef constexpr
137// #define constexpr
138// #endif
139// #endif
140
141/* the following add a trait to a set and define the serialization DSL*/
142
147#define BLOB_SERIALIZER(T) \
148 template<> \
149 struct is_blob_type<T> { \
150 typedef boost::true_type type; \
151 }
152
157#define FREE_SERIALIZER(T) \
158 template<> \
159 struct has_free_serializer<T> { \
160 typedef boost::true_type type; \
161 }
162
167#define VARIANT_TAG(Archive, Type, Tag) \
168 template <bool W> \
169 struct variant_serialization_traits<Archive<W>, Type> { \
170 static inline typename Archive<W>::variant_tag_type get_tag() { \
171 return Tag; \
172 } \
173 }
174
181#define BEGIN_SERIALIZE() \
182 template <bool W, template <bool> class Archive> \
183 bool do_serialize(Archive<W> &ar) {
184
190#define BEGIN_SERIALIZE_OBJECT() \
191 template <bool W, template <bool> class Archive> \
192 bool do_serialize(Archive<W> &ar) { \
193 ar.begin_object(); \
194 bool r = do_serialize_object(ar); \
195 ar.end_object(); \
196 return r; \
197 } \
198 template <bool W, template <bool> class Archive> \
199 bool do_serialize_object(Archive<W> &ar){
200
203#define PREPARE_CUSTOM_VECTOR_SERIALIZATION(size, vec) \
204 ::serialization::detail::prepare_custom_vector_serialization(size, vec, typename Archive<W>::is_saving())
205
208#define PREPARE_CUSTOM_DEQUE_SERIALIZATION(size, vec) \
209 ::serialization::detail::prepare_custom_deque_serialization(size, vec, typename Archive<W>::is_saving())
210
214#define END_SERIALIZE() \
215 return ar.stream().good(); \
216 }
217
221#define VALUE(f) \
222 do { \
223 ar.tag(#f); \
224 bool r = ::do_serialize(ar, f); \
225 if (!r || !ar.stream().good()) return false; \
226 } while(0);
227
232#define FIELD_N(t, f) \
233 do { \
234 ar.tag(t); \
235 bool r = ::do_serialize(ar, f); \
236 if (!r || !ar.stream().good()) return false; \
237 } while(0);
238
243#define FIELD(f) \
244 do { \
245 ar.tag(#f); \
246 bool r = ::do_serialize(ar, f); \
247 if (!r || !ar.stream().good()) return false; \
248 } while(0);
249
254#define FIELDS(f) \
255 do { \
256 bool r = ::do_serialize(ar, f); \
257 if (!r || !ar.stream().good()) return false; \
258 } while(0);
259
263#define VARINT_FIELD(f) \
264 do { \
265 ar.tag(#f); \
266 ar.serialize_varint(f); \
267 if (!ar.stream().good()) return false; \
268 } while(0);
269
274#define VARINT_FIELD_N(t, f) \
275 do { \
276 ar.tag(t); \
277 ar.serialize_varint(f); \
278 if (!ar.stream().good()) return false; \
279 } while(0);
280
281
282namespace serialization {
288 namespace detail
289 {
294 template <typename T>
295 void prepare_custom_vector_serialization(size_t size, std::vector<T>& vec, const boost::mpl::bool_<true>& /*is_saving*/)
296 {
297 }
298
299 template <typename T>
300 void prepare_custom_vector_serialization(size_t size, std::vector<T>& vec, const boost::mpl::bool_<false>& /*is_saving*/)
301 {
302 vec.resize(size);
303 }
304
305 template <typename T>
306 void prepare_custom_deque_serialization(size_t size, std::deque<T>& vec, const boost::mpl::bool_<true>& /*is_saving*/)
307 {
308 }
309
310 template <typename T>
311 void prepare_custom_deque_serialization(size_t size, std::deque<T>& vec, const boost::mpl::bool_<false>& /*is_saving*/)
312 {
313 vec.resize(size);
314 }
315
320 template<class Stream>
321 bool do_check_stream_state(Stream& s, boost::mpl::bool_<true>, bool noeof)
322 {
323 return s.good();
324 }
325
331 template<class Stream>
332 bool do_check_stream_state(Stream& s, boost::mpl::bool_<false>, bool noeof)
333 {
334 bool result = false;
335 if (s.good())
336 {
337 std::ios_base::iostate state = s.rdstate();
338 result = noeof || EOF == s.peek();
339 s.clear(state);
340 }
341 return result;
342 }
343 }
344
349 template<class Archive>
350 bool check_stream_state(Archive& ar, bool noeof = false)
351 {
352 return detail::do_check_stream_state(ar.stream(), typename Archive::is_saving(), noeof);
353 }
354
359 template <class Archive, class T>
360 inline bool serialize(Archive &ar, T &v)
361 {
362 bool r = do_serialize(ar, v);
363 return r && check_stream_state(ar, false);
364 }
365
370 template <class Archive, class T>
371 inline bool serialize_noeof(Archive &ar, T &v)
372 {
373 bool r = do_serialize(ar, v);
374 return r && check_stream_state(ar, true);
375 }
376}
Concept for reading and writing characters.
void prepare_custom_deque_serialization(size_t size, std::deque< T > &vec, const boost::mpl::bool_< true > &)
void prepare_custom_vector_serialization(size_t size, std::vector< T > &vec, const boost::mpl::bool_< true > &)
bool do_check_stream_state(Stream &s, boost::mpl::bool_< true >, bool noeof)
bool serialize_noeof(Archive &ar, T &v)
bool check_stream_state(Archive &ar, bool noeof=false)
bool serialize(Archive &ar, T &v)
STL namespace.
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
bool do_serialize(Archive< false > &ar, std::vector< crypto::signature > &v)
Definition crypto.h:44
bool do_serialize(Archive &ar, T &v)
just calls the serialize function defined for ar and v...
a descriptor for dispatching serialize
boost::true_type type
a descriptor for dispatching serialize
boost::false_type type
a descriptor for dispatching serialize
boost::false_type type
... wouldn't a class be better?
static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::false_type)
static void serialize_custom(Archive &ar, T &v, boost::true_type)
static bool serialize(Archive &ar, T &v, boost::false_type, boost::true_type, A a)
static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::true_type)
static bool serialize(Archive &ar, T &v)
static bool serialize(Archive &ar, T &v, boost::true_type, boost::false_type, A a)
#define T(x)