Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin developers
3 : // Copyright (c) 2015-2021 The PIVX Core developers
4 : // Distributed under the MIT software license, see the accompanying
5 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 :
7 : #ifndef PIVX_SERIALIZE_H
8 : #define PIVX_SERIALIZE_H
9 :
10 : #include <algorithm>
11 : #include <array>
12 : #include <assert.h>
13 : #include <cstring>
14 : #include <cstdint>
15 : #include <ios>
16 : #include <limits>
17 : #include <list>
18 : #include <map>
19 : #include <memory>
20 : #include <set>
21 : #include <string.h>
22 : #include <string>
23 : #include <utility>
24 : #include <vector>
25 :
26 : #include "compat/endian.h"
27 : #include "libzerocoin/Denominations.h"
28 : #include "libzerocoin/SpendType.h"
29 : #include "optional.h"
30 : #include "prevector.h"
31 : #include "span.h"
32 : #include "sporkid.h"
33 :
34 : class CScript;
35 :
36 : /**
37 : * The maximum size of a serialized object in bytes or number of elements
38 : * (for eg vectors) when the size is encoded as CompactSize.
39 : */
40 : static constexpr uint64_t MAX_SIZE = 0x02000000;
41 :
42 : /** Maximum amount of memory (in bytes) to allocate at once when deserializing vectors. */
43 : static const unsigned int MAX_VECTOR_ALLOCATE = 5000000;
44 :
45 : /**
46 : * Dummy data type to identify deserializing constructors.
47 : *
48 : * By convention, a constructor of a type T with signature
49 : *
50 : * template <typename Stream> T::T(deserialize_type, Stream& s)
51 : *
52 : * is a deserializing constructor, which builds the type by
53 : * deserializing it from s. If T contains const fields, this
54 : * is likely the only way to do so.
55 : */
56 : struct deserialize_type {};
57 : constexpr deserialize_type deserialize {};
58 :
59 : /**
60 : * Used to bypass the rule against non-const reference to temporary
61 : * where it makes sense with wrappers such as CFlatData or CTxDB
62 : */
63 :
64 : template <typename T>
65 0 : inline T& REF(const T& val)
66 : {
67 : return const_cast<T&>(val);
68 : }
69 :
70 : //! Safely convert odd char pointer types to standard ones.
71 : inline char* CharCast(char* c) { return c; }
72 8744347 : inline char* CharCast(unsigned char* c) { return (char*)c; }
73 : inline const char* CharCast(const char* c) { return c; }
74 419705 : inline const char* CharCast(const unsigned char* c) { return (const char*)c; }
75 :
76 : /*
77 : * Lowest-level serialization and conversion.
78 : * @note Sizes of these types are verified in the tests
79 : */
80 30478900 : template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
81 : {
82 640669794 : s.write((char*)&obj, 1);
83 0 : }
84 15339534 : template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
85 : {
86 7950211 : obj = htole16(obj);
87 15212325 : s.write((char*)&obj, 2);
88 0 : }
89 : template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj)
90 : {
91 : obj = htobe16(obj);
92 : s.write((char*)&obj, 2);
93 : }
94 139924554 : template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
95 : {
96 137704771 : obj = htole32(obj);
97 123797368 : s.write((char*)&obj, 4);
98 0 : }
99 67383271 : template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
100 : {
101 67374745 : obj = htole64(obj);
102 65586504 : s.write((char*)&obj, 8);
103 0 : }
104 86515791 : template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
105 : {
106 : uint8_t obj;
107 70822094 : s.read((char*)&obj, 1);
108 86515336 : return obj;
109 : }
110 1937973 : template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
111 : {
112 : uint16_t obj;
113 400446 : s.read((char*)&obj, 2);
114 1894773 : return le16toh(obj);
115 : }
116 : template<typename Stream> inline uint16_t ser_readdata16be(Stream &s)
117 : {
118 : uint16_t obj;
119 : s.read((char*)&obj, 2);
120 : return be16toh(obj);
121 : }
122 5433073 : template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
123 : {
124 : uint32_t obj;
125 39233 : s.read((char*)&obj, 4);
126 3254833 : return le32toh(obj);
127 : }
128 2149795 : template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
129 : {
130 : uint64_t obj;
131 4252 : s.read((char*)&obj, 8);
132 3163153 : return le64toh(obj);
133 : }
134 738996 : inline uint64_t ser_double_to_uint64(double x)
135 : {
136 738996 : uint64_t tmp;
137 737994 : std::memcpy(&tmp, &x, sizeof(x));
138 738996 : static_assert(sizeof(tmp) == sizeof(x), "double and uint64_t assumed to have the same size");
139 738994 : return tmp;
140 : }
141 1008 : inline uint32_t ser_float_to_uint32(float x)
142 : {
143 1008 : uint32_t tmp;
144 6 : std::memcpy(&tmp, &x, sizeof(x));
145 1008 : static_assert(sizeof(tmp) == sizeof(x), "float and uint32_t assumed to have the same size");
146 1006 : return tmp;
147 : }
148 175138 : inline double ser_uint64_to_double(uint64_t y)
149 : {
150 175138 : double tmp;
151 174138 : std::memcpy(&tmp, &y, sizeof(y));
152 175138 : static_assert(sizeof(tmp) == sizeof(y), "double and uint64_t assumed to have the same size");
153 1090 : return tmp;
154 : }
155 1006 : inline float ser_uint32_to_float(uint32_t y)
156 : {
157 1006 : float tmp;
158 6 : std::memcpy(&tmp, &y, sizeof(y));
159 1006 : static_assert(sizeof(tmp) == sizeof(y), "float and uint32_t assumed to have the same size");
160 1006 : return tmp;
161 : }
162 :
163 :
164 : /////////////////////////////////////////////////////////////////
165 : //
166 : // Templates for serializing to anything that looks like a stream,
167 : // i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)
168 : //
169 :
170 : class CSizeComputer;
171 :
172 : enum {
173 : // primary actions
174 : SER_NETWORK = (1 << 0),
175 : SER_DISK = (1 << 1),
176 : SER_GETHASH = (1 << 2),
177 : };
178 :
179 : //! Convert the reference base type to X, without changing constness or reference type.
180 5286753 : template<typename X> X& ReadWriteAsHelper(X& x) { return x; }
181 103447180 : template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
182 :
183 : #define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
184 : #define READWRITEAS(type, obj) (::SerReadWriteMany(s, ser_action, ReadWriteAsHelper<type>(obj)))
185 : #define SER_READ(obj, code) ::SerRead(s, ser_action, obj, [&](Stream& s, typename std::remove_const<Type>::type& obj) { code; })
186 : #define SER_WRITE(obj, code) ::SerWrite(s, ser_action, obj, [&](Stream& s, const Type& obj) { code; })
187 :
188 : /**
189 : * Implement the Ser and Unser methods needed for implementing a formatter (see Using below).
190 : *
191 : * Both Ser and Unser are delegated to a single static method SerializationOps, which is polymorphic
192 : * in the serialized/deserialized type (allowing it to be const when serializing, and non-const when
193 : * deserializing).
194 : *
195 : * Example use:
196 : * struct FooFormatter {
197 : * FORMATTER_METHODS(Class, obj) { READWRITE(obj.val1, VARINT(obj.val2)); }
198 : * }
199 : * would define a class FooFormatter that defines a serialization of Class objects consisting
200 : * of serializing its val1 member using the default serialization, and its val2 member using
201 : * VARINT serialization. That FooFormatter can then be used in statements like
202 : * READWRITE(Using<FooFormatter>(obj.bla)).
203 : */
204 : #define FORMATTER_METHODS(cls, obj) \
205 : template<typename Stream> \
206 : static void Ser(Stream& s, const cls& obj) { SerializationOps(obj, s, CSerActionSerialize()); } \
207 : template<typename Stream> \
208 : static void Unser(Stream& s, cls& obj) { SerializationOps(obj, s, CSerActionUnserialize()); } \
209 : template<typename Stream, typename Type, typename Operation> \
210 : static inline void SerializationOps(Type& obj, Stream& s, Operation ser_action) \
211 :
212 : /**
213 : * Implement the Serialize and Unserialize methods by delegating to a single templated
214 : * static method that takes the to-be-(de)serialized object as a parameter. This approach
215 : * has the advantage that the constness of the object becomes a template parameter, and
216 : * thus allows a single implementation that sees the object as const for serializing
217 : * and non-const for deserializing, without casts.
218 : */
219 : #define SERIALIZE_METHODS(cls, obj) \
220 : template<typename Stream> \
221 : void Serialize(Stream& s) const \
222 : { \
223 : static_assert(std::is_same<const cls&, decltype(*this)>::value, "Serialize type mismatch"); \
224 : Ser(s, *this); \
225 : } \
226 : template<typename Stream> \
227 : void Unserialize(Stream& s) \
228 : { \
229 : static_assert(std::is_same<cls&, decltype(*this)>::value, "Unserialize type mismatch"); \
230 : Unser(s, *this); \
231 : } \
232 : FORMATTER_METHODS(cls, obj)
233 :
234 : /*
235 : * Basic Types
236 : */
237 370128 : template<typename Stream> inline void Serialize(Stream& s, char a ) { ser_writedata8(s, a); } // TODO Get rid of bare char
238 2 : template<typename Stream> inline void Serialize(Stream& s, int8_t a ) { ser_writedata8(s, a); }
239 937833041 : template<typename Stream> inline void Serialize(Stream& s, uint8_t a ) { ser_writedata8(s, a); }
240 7918335 : template<typename Stream> inline void Serialize(Stream& s, int16_t a ) { ser_writedata16(s, a); }
241 16880 : template<typename Stream> inline void Serialize(Stream& s, uint16_t a) { ser_writedata16(s, a); }
242 20253265 : template<typename Stream> inline void Serialize(Stream& s, int32_t a ) { ser_writedata32(s, a); }
243 43025895 : template<typename Stream> inline void Serialize(Stream& s, uint32_t a) { ser_writedata32(s, a); }
244 78267278 : template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_writedata64(s, a); }
245 727965 : template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
246 1000 : template<typename Stream> inline void Serialize(Stream& s, float a ) { ser_writedata32(s, ser_float_to_uint32(a)); }
247 1356 : template<typename Stream> inline void Serialize(Stream& s, double a ) { ser_writedata64(s, ser_double_to_uint64(a)); }
248 658938 : template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(a, N); }
249 451717 : template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(CharCast(a), N); }
250 66123 : template<typename Stream> inline void Serialize(Stream& s, const Span<const unsigned char>& span) { s.write(CharCast(span.data()), span.size()); }
251 1574535 : template<typename Stream> inline void Serialize(Stream& s, const Span<unsigned char>& span) { s.write(CharCast(span.data()), span.size()); }
252 :
253 22825 : template<typename Stream> inline void Unserialize(Stream& s, char& a ) { a = ser_readdata8(s); } // TODO Get rid of bare char
254 : template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
255 8732248 : template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); }
256 1853058 : template<typename Stream> inline void Unserialize(Stream& s, int16_t& a ) { a = ser_readdata16(s); }
257 71482 : template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a) { a = ser_readdata16(s); }
258 692696 : template<typename Stream> inline void Unserialize(Stream& s, int32_t& a ) { a = ser_readdata32(s); }
259 2378943 : template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); }
260 147425 : template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); }
261 14700 : template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
262 1000 : template<typename Stream> inline void Unserialize(Stream& s, float& a ) { a = ser_uint32_to_float(ser_readdata32(s)); }
263 175132 : template<typename Stream> inline void Unserialize(Stream& s, double& a ) { a = ser_uint64_to_double(ser_readdata64(s)); }
264 758315 : template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(a, N); }
265 16363 : template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(CharCast(a), N); }
266 7167592 : template<typename Stream> inline void Unserialize(Stream& s, Span<unsigned char>& span) { s.read(CharCast(span.data()), span.size()); }
267 :
268 34997 : template<typename Stream> inline void Serialize(Stream& s, bool a) { char f=a; ser_writedata8(s, f); }
269 10594 : template<typename Stream> inline void Unserialize(Stream& s, bool& a) { char f=ser_readdata8(s); a=f; }
270 :
271 : // Serializatin for libzerocoin::CoinDenomination
272 : template <typename Stream>
273 699 : inline void Serialize(Stream& s, libzerocoin::CoinDenomination a)
274 : {
275 699 : int f = libzerocoin::ZerocoinDenominationToInt(a);
276 699 : ser_writedata32(s, f);
277 699 : }
278 :
279 : template <typename Stream>
280 320 : inline void Unserialize(Stream& s, libzerocoin::CoinDenomination& a)
281 : {
282 320 : int f = ser_readdata32(s);
283 320 : a = libzerocoin::IntToZerocoinDenomination(f);
284 320 : }
285 :
286 : // Serialization for libzerocoin::SpendType
287 : template <typename Stream>
288 0 : inline void Serialize(Stream& s, libzerocoin::SpendType a)
289 : {
290 0 : uint8_t f = static_cast<uint8_t>(a);
291 0 : ser_writedata8(s, f);
292 : }
293 :
294 : template <typename Stream>
295 0 : inline void Unserialize(Stream& s, libzerocoin::SpendType & a)
296 : {
297 0 : uint8_t f = ser_readdata8(s);
298 0 : a = static_cast<libzerocoin::SpendType>(f);
299 : }
300 :
301 : // Serialization for SporkId
302 : template <typename Stream>
303 8164 : inline void Serialize(Stream& s, SporkId sporkID)
304 : {
305 8164 : int32_t f = static_cast<int32_t>(sporkID);
306 6386 : ser_writedata32(s, f);
307 : }
308 :
309 : template <typename Stream>
310 2173 : inline void Unserialize(Stream& s, SporkId& sporkID)
311 : {
312 2173 : int32_t f = ser_readdata32(s);
313 2173 : sporkID = (SporkId) f;
314 : }
315 :
316 :
317 : /**
318 : * Compact Size
319 : * size < 253 -- 1 byte
320 : * size <= USHRT_MAX -- 3 bytes (253 + 2 bytes)
321 : * size <= UINT_MAX -- 5 bytes (254 + 4 bytes)
322 : * size > UINT_MAX -- 9 bytes (255 + 8 bytes)
323 : */
324 23228847 : inline unsigned int GetSizeOfCompactSize(uint64_t nSize)
325 : {
326 22628869 : if (nSize < 253) return sizeof(unsigned char);
327 18937 : else if (nSize <= std::numeric_limits<uint16_t>::max()) return sizeof(unsigned char) + sizeof(uint16_t);
328 91 : else if (nSize <= std::numeric_limits<unsigned int>::max()) return sizeof(unsigned char) + sizeof(unsigned int);
329 0 : else return sizeof(unsigned char) + sizeof(uint64_t);
330 : }
331 :
332 : inline void WriteCompactSize(CSizeComputer& os, uint64_t nSize);
333 :
334 : template <typename Stream>
335 107330682 : void WriteCompactSize(Stream& os, uint64_t nSize)
336 : {
337 107330682 : if (nSize < 253) {
338 107301648 : ser_writedata8(os, nSize);
339 29105 : } else if (nSize <= std::numeric_limits<uint16_t>::max()) {
340 29008 : ser_writedata8(os, 253);
341 29008 : ser_writedata16(os, nSize);
342 97 : } else if (nSize <= std::numeric_limits<unsigned int>::max()) {
343 97 : ser_writedata8(os, 254);
344 97 : ser_writedata32(os, nSize);
345 : } else {
346 0 : ser_writedata8(os, 255);
347 0 : ser_writedata64(os, nSize);
348 : }
349 107330681 : return;
350 : }
351 :
352 : /**
353 : * Decode a CompactSize-encoded variable-length integer.
354 : *
355 : * As these are primarily used to encode the size of vector-like serializations, by default a range
356 : * check is performed. When used as a generic number encoding, range_check should be set to false.
357 : */
358 : template<typename Stream>
359 8010172 : uint64_t ReadCompactSize(Stream& is, bool range_check = true)
360 : {
361 8010167 : uint8_t chSize = ser_readdata8(is);
362 8010167 : uint64_t nSizeRet = 0;
363 8010167 : if (chSize < 253) {
364 7999933 : nSizeRet = chSize;
365 10236 : } else if (chSize == 253) {
366 10173 : nSizeRet = ser_readdata16(is);
367 10173 : if (nSizeRet < 253)
368 2 : throw std::ios_base::failure("non-canonical ReadCompactSize()");
369 63 : } else if (chSize == 254) {
370 61 : nSizeRet = ser_readdata32(is);
371 61 : if (nSizeRet < 0x10000u)
372 2 : throw std::ios_base::failure("non-canonical ReadCompactSize()");
373 : } else {
374 2 : nSizeRet = ser_readdata64(is);
375 2 : if (nSizeRet < 0x100000000ULL)
376 2 : throw std::ios_base::failure("non-canonical ReadCompactSize()");
377 : }
378 8010161 : if (range_check && nSizeRet > MAX_SIZE) {
379 0 : throw std::ios_base::failure("ReadCompactSize(): size too large");
380 : }
381 8010161 : return nSizeRet;
382 : }
383 :
384 : /**
385 : * Variable-length integers: bytes are a MSB base-128 encoding of the number.
386 : * The high bit in each byte signifies whether another digit follows. To make
387 : * sure the encoding is one-to-one, one is subtracted from all but the last digit.
388 : * Thus, the byte sequence a[] with length len, where all but the last byte
389 : * has bit 128 set, encodes the number:
390 : *
391 : * (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1))
392 : *
393 : * Properties:
394 : * * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)
395 : * * Every integer has exactly one encoding
396 : * * Encoding does not depend on size of original integer type
397 : * * No redundancy: every (infinite) byte sequence corresponds to a list
398 : * of encoded integers.
399 : *
400 : * 0: [0x00] 256: [0x81 0x00]
401 : * 1: [0x01] 16383: [0xFE 0x7F]
402 : * 127: [0x7F] 16384: [0xFF 0x00]
403 : * 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F]
404 : * 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F]
405 : * 2^32: [0x8E 0xFE 0xFE 0xFF 0x00]
406 : */
407 :
408 : /**
409 : * Mode for encoding VarInts.
410 : *
411 : * Currently there is no support for signed encodings. The default mode will not
412 : * compile with signed values, and the legacy "nonnegative signed" mode will
413 : * accept signed values, but improperly encode and decode them if they are
414 : * negative. In the future, the DEFAULT mode could be extended to support
415 : * negative numbers in a backwards compatible way, and additional modes could be
416 : * added to support different varint formats (e.g. zigzag encoding).
417 : */
418 : enum class VarIntMode { DEFAULT, NONNEGATIVE_SIGNED };
419 :
420 : template <VarIntMode Mode, typename I>
421 : struct CheckVarIntMode {
422 46759636 : constexpr CheckVarIntMode()
423 : {
424 : static_assert(Mode != VarIntMode::DEFAULT || std::is_unsigned<I>::value, "Unsigned type required with mode DEFAULT.");
425 : static_assert(Mode != VarIntMode::NONNEGATIVE_SIGNED || std::is_signed<I>::value, "Signed type required with mode NONNEGATIVE_SIGNED.");
426 : }
427 : };
428 :
429 : template<VarIntMode Mode, typename I>
430 : inline unsigned int GetSizeOfVarInt(I n)
431 : {
432 : CheckVarIntMode<Mode, I>();
433 : int nRet = 0;
434 : while (true) {
435 : nRet++;
436 : if (n <= 0x7F)
437 : break;
438 : n = (n >> 7) - 1;
439 : }
440 : return nRet;
441 : }
442 :
443 : template<typename I>
444 : inline void WriteVarInt(CSizeComputer& os, I n);
445 :
446 : template<typename Stream, VarIntMode Mode, typename I>
447 17727432 : void WriteVarInt(Stream& os, I n)
448 : {
449 : CheckVarIntMode<Mode, I>();
450 : unsigned char tmp[(sizeof(n)*8+6)/7];
451 17727432 : int len=0;
452 24190115 : while(true) {
453 39855410 : tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
454 41917518 : if (n <= 0x7F)
455 : break;
456 24190115 : n = (n >> 7) - 1;
457 24190115 : len++;
458 : }
459 41917519 : do {
460 41917519 : ser_writedata8(os, tmp[len]);
461 : } while (len--);
462 17727432 : }
463 :
464 : template<typename Stream, VarIntMode Mode, typename I>
465 29032186 : I ReadVarInt(Stream& is)
466 : {
467 : CheckVarIntMode<Mode, I>();
468 29032186 : I n = 0;
469 36264946 : while (true) {
470 65297084 : unsigned char chData = ser_readdata8(is);
471 65297084 : if (n > (std::numeric_limits<I>::max() >> 7)) {
472 0 : throw std::ios_base::failure("ReadVarInt(): size too large");
473 : }
474 65297084 : n = (n << 7) | (chData & 0x7F);
475 65297084 : if (chData & 0x80) {
476 36264946 : if (n == std::numeric_limits<I>::max()) {
477 0 : throw std::ios_base::failure("ReadVarInt(): size too large");
478 : }
479 36264946 : n++;
480 : } else {
481 29032186 : return n;
482 : }
483 : }
484 : }
485 :
486 : /** Simple wrapper class to serialize objects using a formatter; used by Using(). */
487 : template<typename Formatter, typename T>
488 : class Wrapper
489 : {
490 : static_assert(std::is_lvalue_reference<T>::value, "Wrapper needs an lvalue reference type T");
491 : protected:
492 : T m_object;
493 : public:
494 86327974 : explicit Wrapper(T obj) : m_object(obj) {}
495 68597785 : template<typename Stream> void Serialize(Stream &s) const { Formatter().Ser(s, m_object); }
496 9649268 : template<typename Stream> void Unserialize(Stream &s) { Formatter().Unser(s, m_object); }
497 : };
498 :
499 : /** Cause serialization/deserialization of an object to be done using a specified formatter class.
500 : *
501 : * To use this, you need a class Formatter that has public functions Ser(stream, const object&) for
502 : * serialization, and Unser(stream, object&) for deserialization. Serialization routines (inside
503 : * READWRITE, or directly with << and >> operators), can then use Using<Formatter>(object).
504 : *
505 : * This works by constructing a Wrapper<Formatter, T>-wrapped version of object, where T is
506 : * const during serialization, and non-const during deserialization, which maintains const
507 : * correctness.
508 : */
509 : template<typename Formatter, typename T>
510 47101155 : static inline Wrapper<Formatter, T&> Using(T&& t) { return Wrapper<Formatter, T&>(t); }
511 :
512 : #define VARINT_MODE(obj, mode) Using<VarIntFormatter<mode>>(obj)
513 : #define VARINT(obj) Using<VarIntFormatter<VarIntMode::DEFAULT>>(obj)
514 : #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj)
515 : #define LIMITED_STRING(obj,n) Using<LimitedStringFormatter<n>>(obj)
516 :
517 : /** Serialization wrapper class for integers in VarInt format. */
518 : template<VarIntMode Mode>
519 : struct VarIntFormatter
520 : {
521 17727436 : template<typename Stream, typename I> void Ser(Stream &s, I v)
522 : {
523 17727436 : WriteVarInt<Stream,Mode,typename std::remove_cv<I>::type>(s, v);
524 : }
525 :
526 29032159 : template<typename Stream, typename I> void Unser(Stream& s, I& v)
527 : {
528 57534105 : v = ReadVarInt<Stream,Mode,typename std::remove_cv<I>::type>(s);
529 : }
530 : };
531 :
532 : #define FIXEDBITSET(obj, size) Using<BitSetFormatter<size>>(obj)
533 : #define DYNBITSET(obj) Using<BitSetFormatter<0>>(obj)
534 : #define FIXEDVARINTSBITSET(obj, size) REF(CFixedVarIntsBitSet(REF(obj), (size)))
535 : #define AUTOBITSET(obj, size) REF(CAutoBitSet(REF(obj), (size)))
536 :
537 : /* Formatter for fixed (size N), or dynamic (size 0) bitsets */
538 :
539 : template<size_t N>
540 : struct BitSetFormatter
541 : {
542 : template<typename Stream>
543 3897 : void Ser(Stream& s, const std::vector<bool>& vec)
544 : {
545 3897 : size_t size = (N == 0 ? vec.size() : N);
546 : if (N == 0) {
547 4493 : WriteCompactSize(s, size);
548 : }
549 3897 : std::vector<unsigned char> vBytes((size + 7) / 8);
550 3897 : size_t ms = std::min(size, vec.size());
551 15706 : for (size_t p = 0; p < ms; p++)
552 11809 : vBytes[p / 8] |= vec[p] << (p % 8);
553 5714 : s.write((char*)vBytes.data(), vBytes.size());
554 3897 : }
555 :
556 : template<typename Stream>
557 21472 : void Unser(Stream& s, std::vector<bool>& vec)
558 : {
559 21472 : size_t size = (N == 0 ? ReadCompactSize(s) : N);
560 21472 : vec.resize(size);
561 21472 : std::vector<unsigned char> vBytes((size + 7) / 8);
562 21472 : s.read((char*)vBytes.data(), vBytes.size());
563 86006 : for (size_t p = 0; p < size; p++)
564 129068 : vec[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0;
565 21472 : if (vBytes.size() * 8 != size) {
566 21472 : size_t rem = vBytes.size() * 8 - size;
567 21472 : uint8_t m = ~(uint8_t)(0xff >> rem);
568 21472 : if (vBytes[vBytes.size() - 1] & m) {
569 0 : throw std::ios_base::failure("Out-of-range bits set");
570 : }
571 : }
572 21472 : }
573 : };
574 :
575 : /**
576 : * Stores a fixed size bitset as a series of VarInts. Each VarInt is an offset from the last entry and the sum of the
577 : * last entry and the offset gives an index into the bitset for a set bit. The series of VarInts ends with a 0.
578 : */
579 :
580 : class CFixedVarIntsBitSet
581 : {
582 : protected:
583 : std::vector<bool>& vec;
584 : size_t size;
585 :
586 : public:
587 0 : CFixedVarIntsBitSet(std::vector<bool>& vecIn, size_t sizeIn) : vec(vecIn), size(sizeIn) {}
588 :
589 : template <typename Stream>
590 0 : void Serialize(Stream& s) const
591 : {
592 0 : int32_t last = -1;
593 0 : for (int32_t i = 0; i < (int32_t)vec.size(); i++) {
594 0 : if (vec[i]) {
595 0 : WriteVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s, (uint32_t)(i - last));
596 0 : last = i;
597 : }
598 : }
599 0 : WriteVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s, 0); // stopper
600 0 : }
601 :
602 : template <typename Stream>
603 0 : void Unserialize(Stream& s)
604 : {
605 0 : vec.assign(size, false);
606 :
607 : int32_t last = -1;
608 0 : while (true) {
609 0 : uint32_t offset = ReadVarInt<Stream, VarIntMode::DEFAULT, uint32_t>(s);
610 0 : if (offset == 0) {
611 : break;
612 : }
613 0 : int32_t idx = last + offset;
614 0 : if (idx >= size) {
615 0 : throw std::ios_base::failure("out of bounds index");
616 : }
617 0 : if (last != -1 && idx <= last) {
618 0 : throw std::ios_base::failure("offset overflow");
619 : }
620 0 : vec[idx] = true;
621 0 : last = idx;
622 : }
623 0 : }
624 : };
625 :
626 : /**
627 : * Serializes either as a or CFixedVarIntsBitSet
628 : */
629 :
630 : class CAutoBitSet
631 : {
632 : protected:
633 : std::vector<bool>& vec;
634 : size_t size;
635 :
636 : public:
637 0 : explicit CAutoBitSet(std::vector<bool>& vecIn, size_t sizeIn) : vec(vecIn), size(sizeIn) {}
638 :
639 : template <typename Stream>
640 0 : void Serialize(Stream& s) const
641 : {
642 0 : assert(vec.size() == size);
643 :
644 0 : ser_writedata8(s, 0);
645 0 : s << FIXEDVARINTSBITSET(vec, vec.size());
646 0 : }
647 :
648 : template <typename Stream>
649 0 : void Unserialize(Stream& s)
650 : {
651 0 : uint8_t isVarInts = ser_readdata8(s);
652 0 : if (isVarInts != 0) {
653 0 : throw std::ios_base::failure("invalid value for isVarInts byte");
654 : }
655 0 : s >> FIXEDVARINTSBITSET(vec, size);
656 0 : }
657 : };
658 :
659 : /** Serialization wrapper class for custom integers and enums.
660 : *
661 : * It permits specifying the serialized size (1 to 8 bytes) and endianness.
662 : *
663 : * Use the big endian mode for values that are stored in memory in native
664 : * byte order, but serialized in big endian notation. This is only intended
665 : * to implement serializers that are compatible with existing formats, and
666 : * its use is not recommended for new data structures.
667 : */
668 : template<int Bytes, bool BigEndian = false>
669 : struct CustomUintFormatter
670 : {
671 : static_assert(Bytes > 0 && Bytes <= 8, "CustomUintFormatter Bytes out of range");
672 : static constexpr uint64_t MAX = 0xffffffffffffffff >> (8 * (8 - Bytes));
673 :
674 74573 : template <typename Stream, typename I> void Ser(Stream& s, I v)
675 : {
676 : if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range");
677 : if (BigEndian) {
678 19545 : uint64_t raw = htobe64(v);
679 70754 : s.write(((const char*)&raw) + 8 - Bytes, Bytes);
680 : } else {
681 2937 : uint64_t raw = htole64(v);
682 2937 : s.write((const char*)&raw, Bytes);
683 : }
684 11 : }
685 :
686 16040 : template <typename Stream, typename I> void Unser(Stream& s, I& v)
687 : {
688 : using U = typename std::conditional<std::is_enum<I>::value, std::underlying_type<I>, std::common_type<I>>::type::type;
689 : static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small");
690 16040 : uint64_t raw = 0;
691 : if (BigEndian) {
692 16945 : s.read(((char*)&raw) + 8 - Bytes, Bytes);
693 10747 : v = static_cast<I>(be64toh(raw));
694 : } else {
695 5293 : s.read((char*)&raw, Bytes);
696 5293 : v = static_cast<I>(le64toh(raw));
697 : }
698 : }
699 : };
700 :
701 : template<int Bytes> using BigEndianFormatter = CustomUintFormatter<Bytes, true>;
702 :
703 : /** Formatter for integers in CompactSize format. */
704 : template<bool RangeCheck>
705 : struct CompactSizeFormatter
706 : {
707 : template<typename Stream, typename I>
708 6536 : void Unser(Stream& s, I& v)
709 : {
710 13072 : uint64_t n = ReadCompactSize<Stream>(s, RangeCheck);
711 : if (n < std::numeric_limits<I>::min() || n > std::numeric_limits<I>::max()) {
712 : throw std::ios_base::failure("CompactSize exceeds limit of type");
713 : }
714 5499 : v = n;
715 : }
716 :
717 : template<typename Stream, typename I>
718 17983 : void Ser(Stream& s, I v)
719 : {
720 : static_assert(std::is_unsigned<I>::value, "CompactSize only supported for unsigned integers");
721 : static_assert(std::numeric_limits<I>::max() <= std::numeric_limits<uint64_t>::max(), "CompactSize only supports 64-bit integers and below");
722 :
723 17983 : WriteCompactSize<Stream>(s, v);
724 : }
725 : };
726 :
727 : template<size_t Limit>
728 : struct LimitedStringFormatter
729 : {
730 : template<typename Stream>
731 1711 : void Unser(Stream& s, std::string& v)
732 : {
733 1711 : size_t size = ReadCompactSize(s);
734 1710 : if (size > Limit) {
735 0 : throw std::ios_base::failure("String length limit exceeded");
736 : }
737 1710 : v.resize(size);
738 1710 : if (size != 0) s.read((char*)v.data(), size);
739 1710 : }
740 :
741 : template<typename Stream>
742 597 : void Ser(Stream& s, const std::string& v)
743 : {
744 597 : s << v;
745 : }
746 : };
747 :
748 : /** Formatter to serialize/deserialize vector elements using another formatter
749 : *
750 : * Example:
751 : * struct X {
752 : * std::vector<uint64_t> v;
753 : * SERIALIZE_METHODS(X, obj) { READWRITE(Using<VectorFormatter<VarInt>>(obj.v)); }
754 : * };
755 : * will define a struct that contains a vector of uint64_t, which is serialized
756 : * as a vector of VarInt-encoded integers.
757 : *
758 : * V is not required to be an std::vector type. It works for any class that
759 : * exposes a value_type, size, reserve, emplace_back, back, and const iterators.
760 : */
761 : template<class Formatter>
762 : struct VectorFormatter
763 : {
764 : template<typename Stream, typename V>
765 17703502 : void Ser(Stream& s, const V& v)
766 : {
767 : Formatter formatter;
768 25422283 : WriteCompactSize(s, v.size());
769 100419826 : for (const typename V::value_type& elem : v) {
770 82277052 : formatter.Ser(s, elem);
771 : }
772 17703502 : }
773 :
774 : template<typename Stream, typename V>
775 2794340 : void Unser(Stream& s, V& v)
776 : {
777 : Formatter formatter;
778 2794340 : v.clear();
779 2794340 : size_t size = ReadCompactSize(s);
780 2794336 : size_t allocated = 0;
781 5521772 : while (allocated < size) {
782 : // For DoS prevention, do not blindly allocate as much as the stream claims to contain.
783 : // Instead, allocate in 5MiB batches, so that an attacker actually needs to provide
784 : // X MiB of data to make us allocate X+5 Mib.
785 : static_assert(sizeof(typename V::value_type) <= MAX_VECTOR_ALLOCATE, "Vector element size too large");
786 2727447 : allocated = std::min(size, allocated + MAX_VECTOR_ALLOCATE / sizeof(typename V::value_type));
787 2727447 : v.reserve(allocated);
788 9406666 : while (v.size() < allocated) {
789 6679221 : v.emplace_back();
790 11302096 : formatter.Unser(s, v.back());
791 : }
792 : }
793 2794334 : };
794 : };
795 :
796 : /**
797 : * Forward declarations
798 : */
799 :
800 : /**
801 : * std::string
802 : */
803 : template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str);
804 : template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str);
805 :
806 : /**
807 : * prevector
808 : * prevectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
809 : */
810 : template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&);
811 : template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&);
812 : template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v);
813 : template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&);
814 : template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&);
815 : template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v);
816 :
817 : /**
818 : * vector
819 : * vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
820 : */
821 : template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&);
822 : template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const bool&);
823 : template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&);
824 : template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v);
825 : template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&);
826 : template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&);
827 : template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v);
828 :
829 : /**
830 : * array
831 : */
832 : template<typename T, std::size_t N> unsigned int GetSerializeSize(const std::array<T, N> &item);
833 : template<typename Stream, typename T, std::size_t N> void Serialize(Stream& os, const std::array<T, N>& item);
834 : template<typename Stream, typename T, std::size_t N> void Unserialize(Stream& is, std::array<T, N>& item);
835 :
836 : /**
837 : * optional
838 : */
839 : template<typename T> unsigned int GetSerializeSize(const Optional<T> &item);
840 : template<typename Stream, typename T> void Serialize(Stream& os, const Optional<T>& item);
841 : template<typename Stream, typename T> void Unserialize(Stream& is, Optional<T>& item);
842 :
843 : /**
844 : * array
845 : */
846 : template<typename T, std::size_t N>
847 : unsigned int GetSerializeSize(const std::array<T, N> &item)
848 : {
849 : unsigned int size = 0;
850 : for (size_t i = 0; i < N; i++) {
851 : size += GetSerializeSize(item[0]);
852 : }
853 : return size;
854 : }
855 :
856 : template<typename Stream, typename T>
857 183534 : void Serialize(Stream& os, const Optional<T>& item)
858 : {
859 : // If the value is there, put 0x01 and then serialize the value.
860 : // If it's not, put 0x00.
861 183534 : if (item) {
862 176370 : unsigned char discriminant = 0x01;
863 176370 : Serialize(os, discriminant);
864 355390 : Serialize(os, *item);
865 : } else {
866 7164 : unsigned char discriminant = 0x00;
867 73182 : Serialize(os, discriminant);
868 : }
869 183534 : }
870 :
871 : template<typename Stream, typename T>
872 26468 : void Unserialize(Stream& is, Optional<T>& item)
873 : {
874 26468 : unsigned char discriminant = 0x00;
875 26468 : Unserialize(is, discriminant);
876 :
877 26468 : if (discriminant == 0x00) {
878 417 : item = boost::none;
879 : } else {
880 11635 : T object;
881 26051 : Unserialize(is, object);
882 26051 : item = object;
883 : }
884 26468 : }
885 :
886 :
887 : template<typename Stream, typename T, std::size_t N>
888 1905496 : void Serialize(Stream& os, const std::array<T, N>& item)
889 : {
890 510456022 : for (size_t i = 0; i < N; i++) {
891 508550039 : Serialize(os, item[i]);
892 : }
893 1905496 : }
894 :
895 : template<typename Stream, typename T, std::size_t N>
896 47517 : void Unserialize(Stream& is, std::array<T, N>& item)
897 : {
898 6726465 : for (size_t i = 0; i < N; i++) {
899 6678950 : Unserialize(is, item[i]);
900 : }
901 47517 : }
902 :
903 :
904 : /**
905 : * pair
906 : */
907 : template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item);
908 : template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item);
909 :
910 : /**
911 : * tuple
912 : */
913 : template<typename Stream, typename... Elements> void Serialize(Stream& os, const std::tuple<Elements...>& item);
914 : template<typename Stream, typename... Elements> void Unserialize(Stream& is, std::tuple<Elements...>& item);
915 :
916 : /**
917 : * map
918 : */
919 : template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m);
920 : template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m);
921 :
922 : /**
923 : * set
924 : */
925 : template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m);
926 : template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m);
927 :
928 : /**
929 : * shared_ptr
930 : */
931 : template<typename Stream, typename T> void Serialize(Stream& os, const std::shared_ptr<const T>& p);
932 : template<typename Stream, typename T> void Unserialize(Stream& os, std::shared_ptr<const T>& p);
933 :
934 : template<typename Stream, typename T> void Serialize(Stream& os, const std::shared_ptr<T>& p);
935 : template<typename Stream, typename T> void Unserialize(Stream& os, std::shared_ptr<T>& p);
936 :
937 : /**
938 : * unique_ptr
939 : */
940 : template<typename Stream, typename T> void Serialize(Stream& os, const std::unique_ptr<const T>& p);
941 : template<typename Stream, typename T> void Unserialize(Stream& os, std::unique_ptr<const T>& p);
942 :
943 :
944 :
945 : /**
946 : * If none of the specialized versions above matched, default to calling member function.
947 : */
948 : template <typename Stream, typename T>
949 53097167 : inline void Serialize(Stream& os, const T& a)
950 : {
951 137142942 : a.Serialize(os);
952 8701653 : }
953 :
954 : template<typename Stream, typename T>
955 29547249 : inline void Unserialize(Stream& is, T&& a)
956 : {
957 36197594 : a.Unserialize(is);
958 14492 : }
959 :
960 : /** Default formatter. Serializes objects as themselves.
961 : *
962 : * The vector/prevector serialization code passes this to VectorFormatter
963 : * to enable reusing that logic. It shouldn't be needed elsewhere.
964 : */
965 : struct DefaultFormatter
966 : {
967 : template<typename Stream, typename T>
968 80394537 : static void Ser(Stream& s, const T& t) { Serialize(s, t); }
969 :
970 : template<typename Stream, typename T>
971 8868972 : static void Unser(Stream& s, T& t) { Unserialize(s, t); }
972 : };
973 :
974 :
975 : /**
976 : * string
977 : */
978 : template <typename Stream, typename C>
979 2779372 : void Serialize(Stream& os, const std::basic_string<C>& str)
980 : {
981 2779374 : WriteCompactSize(os, str.size());
982 2779371 : if (!str.empty())
983 2439107 : os.write((char*)str.data(), str.size() * sizeof(C));
984 2779371 : }
985 :
986 : template <typename Stream, typename C>
987 88049 : void Unserialize(Stream& is, std::basic_string<C>& str)
988 : {
989 88049 : unsigned int nSize = ReadCompactSize(is);
990 88049 : str.resize(nSize);
991 88049 : if (nSize != 0)
992 81062 : is.read((char*)str.data(), nSize * sizeof(C));
993 88047 : }
994 :
995 : /**
996 : * list
997 : */
998 : template<typename T, typename A> unsigned int GetSerializeSize(const std::list<T, A>& m);
999 : template<typename Stream, typename T, typename A> void Serialize(Stream& os, const std::list<T, A>& m);
1000 : template<typename Stream, typename T, typename A> void Unserialize(Stream& is, std::list<T, A>& m);
1001 :
1002 : template<typename T, typename A>
1003 : unsigned int GetSerializeSize(const std::list<T, A>& l)
1004 : {
1005 : unsigned int nSize = GetSizeOfCompactSize(l.size());
1006 : for (typename std::list<T, A>::const_iterator it = l.begin(); it != l.end(); ++it)
1007 : nSize += GetSerializeSize((*it));
1008 : return nSize;
1009 : }
1010 :
1011 : template<typename Stream, typename T, typename A>
1012 2255 : void Serialize(Stream& os, const std::list<T, A>& l)
1013 : {
1014 2255 : WriteCompactSize(os, l.size());
1015 3091 : for (typename std::list<T, A>::const_iterator it = l.begin(); it != l.end(); ++it)
1016 836 : Serialize(os, (*it));
1017 2255 : }
1018 :
1019 : template<typename Stream, typename T, typename A>
1020 23 : void Unserialize(Stream& is, std::list<T, A>& l)
1021 : {
1022 23 : l.clear();
1023 23 : unsigned int nSize = ReadCompactSize(is);
1024 24 : for (unsigned int i = 0; i < nSize; i++)
1025 : {
1026 1 : T item;
1027 1 : Unserialize(is, item);
1028 1 : l.push_back(item);
1029 : }
1030 23 : }
1031 :
1032 :
1033 : /**
1034 : * prevector
1035 : */
1036 : template<typename Stream, unsigned int N, typename T>
1037 102819728 : void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
1038 : {
1039 118187335 : WriteCompactSize(os, v.size());
1040 102819728 : if (!v.empty())
1041 161035154 : os.write((char*)v.data(), v.size() * sizeof(T));
1042 102819728 : }
1043 :
1044 : template<typename Stream, unsigned int N, typename T, typename V>
1045 219648 : void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&)
1046 : {
1047 219648 : Serialize(os, Using<VectorFormatter<DefaultFormatter>>(v));
1048 219648 : }
1049 :
1050 : template<typename Stream, unsigned int N, typename T>
1051 103039377 : inline void Serialize(Stream& os, const prevector<N, T>& v)
1052 : {
1053 199340077 : Serialize_impl(os, v, T());
1054 : }
1055 :
1056 :
1057 : template<typename Stream, unsigned int N, typename T>
1058 4932033 : void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&)
1059 : {
1060 : // Limit size per read so bogus size value won't cause out of memory
1061 4932033 : v.clear();
1062 4932033 : unsigned int nSize = ReadCompactSize(is);
1063 4932033 : unsigned int i = 0;
1064 9510353 : while (i < nSize)
1065 : {
1066 4578321 : unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
1067 4578321 : v.resize_uninitialized(i + blk);
1068 4578321 : is.read((char*)&v[i], blk * sizeof(T));
1069 4578321 : i += blk;
1070 : }
1071 4932032 : }
1072 :
1073 : template<typename Stream, unsigned int N, typename T, typename V>
1074 : void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&)
1075 : {
1076 : Unserialize(is, Using<VectorFormatter<DefaultFormatter>>(v));
1077 : }
1078 :
1079 : template<typename Stream, unsigned int N, typename T>
1080 4932030 : inline void Unserialize(Stream& is, prevector<N, T>& v)
1081 : {
1082 9864059 : Unserialize_impl(is, v, T());
1083 : }
1084 :
1085 :
1086 :
1087 : /**
1088 : * vector
1089 : */
1090 : template <typename Stream, typename T, typename A>
1091 239261 : void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&)
1092 : {
1093 289962 : WriteCompactSize(os, v.size());
1094 239261 : if (!v.empty())
1095 237489 : os.write((char*)v.data(), v.size() * sizeof(T));
1096 239261 : }
1097 :
1098 : template <typename Stream, typename T, typename A>
1099 22 : void Serialize_impl(Stream& os, const std::vector<T, A>& v, const bool&)
1100 : {
1101 : // A special case for std::vector<bool>, as dereferencing
1102 : // std::vector<bool>::const_iterator does not result in a const bool&
1103 : // due to std::vector's special casing for bool arguments.
1104 22 : WriteCompactSize(os, v.size());
1105 10514 : for (bool elem : v) {
1106 9939 : ::Serialize(os, elem);
1107 : }
1108 22 : }
1109 :
1110 : template <typename Stream, typename T, typename A, typename V>
1111 16448158 : void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&)
1112 : {
1113 16448158 : Serialize(os, Using<VectorFormatter<DefaultFormatter>>(v));
1114 16448158 : }
1115 :
1116 : template <typename Stream, typename T, typename A>
1117 16619992 : inline void Serialize(Stream& os, const std::vector<T, A>& v)
1118 : {
1119 16218339 : Serialize_impl(os, v, T());
1120 15340785 : }
1121 :
1122 :
1123 : template <typename Stream, typename T, typename A>
1124 131208 : void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&)
1125 : {
1126 : // Limit size per read so bogus size value won't cause out of memory
1127 131208 : v.clear();
1128 131208 : unsigned int nSize = ReadCompactSize(is);
1129 131208 : unsigned int i = 0;
1130 208930 : while (i < nSize) {
1131 77722 : unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
1132 77722 : v.resize(i + blk);
1133 77722 : is.read((char*)&v[i], blk * sizeof(T));
1134 77722 : i += blk;
1135 : }
1136 131208 : }
1137 :
1138 : template <typename Stream, typename T, typename A, typename V>
1139 2664350 : void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&)
1140 : {
1141 2664350 : Unserialize(is, Using<VectorFormatter<DefaultFormatter>>(v));
1142 2664344 : }
1143 :
1144 : template <typename Stream, typename T, typename A>
1145 2737235 : inline void Unserialize(Stream& is, std::vector<T, A>& v)
1146 : {
1147 2779478 : Unserialize_impl(is, v, T());
1148 2416836 : }
1149 :
1150 :
1151 :
1152 : /**
1153 : * pair
1154 : */
1155 : template <typename Stream, typename K, typename T>
1156 2018558 : void Serialize(Stream& os, const std::pair<K, T>& item)
1157 : {
1158 2018558 : Serialize(os, item.first);
1159 2018558 : Serialize(os, item.second);
1160 2018558 : }
1161 :
1162 : template <typename Stream, typename K, typename T>
1163 55928 : void Unserialize(Stream& is, std::pair<K, T>& item)
1164 : {
1165 55928 : Unserialize(is, item.first);
1166 55931 : Unserialize(is, item.second);
1167 55632 : }
1168 :
1169 : /**
1170 : * tuple
1171 : */
1172 : template<typename Stream, int index, typename... Ts>
1173 : struct SerializeTuple {
1174 120395 : void operator() (Stream&s, std::tuple<Ts...>& t) {
1175 120395 : SerializeTuple<Stream, index - 1, Ts...>{}(s, t);
1176 120395 : s << std::get<index>(t);
1177 120395 : }
1178 : };
1179 :
1180 : template<typename Stream, typename... Ts>
1181 : struct SerializeTuple<Stream, 0, Ts...> {
1182 63355 : void operator() (Stream&s, std::tuple<Ts...>& t) {
1183 63355 : s << std::get<0>(t);
1184 : }
1185 : };
1186 :
1187 : template<typename Stream, int index, typename... Ts>
1188 : struct DeserializeTuple {
1189 35970 : void operator() (Stream&s, std::tuple<Ts...>& t) {
1190 35970 : DeserializeTuple<Stream, index - 1, Ts...>{}(s, t);
1191 35970 : s >> std::get<index>(t);
1192 35044 : }
1193 : };
1194 :
1195 : template<typename Stream, typename... Ts>
1196 : struct DeserializeTuple<Stream, 0, Ts...> {
1197 17522 : void operator() (Stream&s, std::tuple<Ts...>& t) {
1198 17522 : s >> std::get<0>(t);
1199 : }
1200 : };
1201 :
1202 :
1203 : template<typename Stream, typename... Elements>
1204 63355 : void Serialize(Stream& os, const std::tuple<Elements...>& item)
1205 : {
1206 63355 : const auto size = std::tuple_size<std::tuple<Elements...>>::value;
1207 63355 : SerializeTuple<Stream, size - 1, Elements...>{}(os, const_cast<std::tuple<Elements...>&>(item));
1208 63355 : }
1209 :
1210 : template<typename Stream, typename... Elements>
1211 17522 : void Unserialize(Stream& is, std::tuple<Elements...>& item)
1212 : {
1213 17522 : const auto size = std::tuple_size<std::tuple<Elements...>>::value;
1214 17377 : DeserializeTuple<Stream, size - 1, Elements...>{}(is, item);
1215 17377 : }
1216 :
1217 :
1218 : /**
1219 : * map
1220 : */
1221 : template <typename Stream, typename K, typename T, typename Pred, typename A>
1222 348531 : void Serialize(Stream& os, const std::map<K, T, Pred, A>& m)
1223 : {
1224 348531 : WriteCompactSize(os, m.size());
1225 1365655 : for (const auto& entry : m)
1226 1017130 : Serialize(os, entry);
1227 348531 : }
1228 :
1229 : template <typename Stream, typename K, typename T, typename Pred, typename A>
1230 8475 : void Unserialize(Stream& is, std::map<K, T, Pred, A>& m)
1231 : {
1232 8475 : m.clear();
1233 8475 : unsigned int nSize = ReadCompactSize(is);
1234 8475 : typename std::map<K, T, Pred, A>::iterator mi = m.begin();
1235 28921 : for (unsigned int i = 0; i < nSize; i++) {
1236 40786 : std::pair<K, T> item;
1237 20446 : Unserialize(is, item);
1238 20446 : mi = m.insert(mi, item);
1239 : }
1240 8475 : }
1241 :
1242 :
1243 : /**
1244 : * set
1245 : */
1246 : template <typename Stream, typename K, typename Pred, typename A>
1247 : void Serialize(Stream& os, const std::set<K, Pred, A>& m)
1248 : {
1249 : WriteCompactSize(os, m.size());
1250 : for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
1251 : Serialize(os, (*it));
1252 : }
1253 :
1254 : template <typename Stream, typename K, typename Pred, typename A>
1255 : void Unserialize(Stream& is, std::set<K, Pred, A>& m)
1256 : {
1257 : m.clear();
1258 : unsigned int nSize = ReadCompactSize(is);
1259 : typename std::set<K, Pred, A>::iterator it = m.begin();
1260 : for (unsigned int i = 0; i < nSize; i++) {
1261 : K key;
1262 : Unserialize(is, key);
1263 : it = m.insert(it, key);
1264 : }
1265 : }
1266 :
1267 :
1268 :
1269 : /**
1270 : * unique_ptr
1271 : */
1272 : template<typename Stream, typename T> void
1273 : Serialize(Stream& os, const std::unique_ptr<const T>& p)
1274 : {
1275 : Serialize(os, *p);
1276 : }
1277 :
1278 : template<typename Stream, typename T>
1279 : void Unserialize(Stream& is, std::unique_ptr<const T>& p)
1280 : {
1281 : p.reset(new T(deserialize, is));
1282 : }
1283 :
1284 :
1285 :
1286 : /**
1287 : * shared_ptr
1288 : */
1289 : template<typename Stream, typename T> void
1290 2558677 : Serialize(Stream& os, const std::shared_ptr<const T>& p)
1291 : {
1292 2558677 : Serialize(os, *p);
1293 2558677 : }
1294 :
1295 : template<typename Stream, typename T>
1296 900602 : void Unserialize(Stream& is, std::shared_ptr<const T>& p)
1297 : {
1298 907366 : p = std::make_shared<const T>(deserialize, is);
1299 900602 : }
1300 :
1301 : template<typename Stream, typename T> void
1302 34 : Serialize(Stream& os, const std::shared_ptr<T>& p)
1303 : {
1304 34 : Serialize(os, *p);
1305 34 : }
1306 :
1307 : template<typename Stream, typename T>
1308 0 : void Unserialize(Stream& is, std::shared_ptr<T>& p)
1309 : {
1310 0 : p = std::make_shared<T>(deserialize, is);
1311 0 : }
1312 :
1313 : /**
1314 : * Support for SERIALIZE_METHODS and READWRITE macro.
1315 : */
1316 : struct CSerActionSerialize {
1317 : constexpr bool ForRead() const { return false; }
1318 : };
1319 : struct CSerActionUnserialize {
1320 : constexpr bool ForRead() const { return true; }
1321 : };
1322 :
1323 :
1324 : /* ::GetSerializeSize implementations
1325 : *
1326 : * Computing the serialized size of objects is done through a special stream
1327 : * object of type CSizeComputer, which only records the number of bytes written
1328 : * to it.
1329 : *
1330 : * If your Serialize or SerializationOp method has non-trivial overhead for
1331 : * serialization, it may be worthwhile to implement a specialized version for
1332 : * CSizeComputer, which uses the s.seek() method to record bytes that would
1333 : * be written instead.
1334 : */
1335 : class CSizeComputer
1336 : {
1337 : protected:
1338 : size_t nSize;
1339 :
1340 : const int nVersion;
1341 :
1342 : public:
1343 2738778 : explicit CSizeComputer(int nVersionIn) : nSize(0), nVersion(nVersionIn) {}
1344 :
1345 87164348 : void write(const char* psz, size_t _nSize)
1346 : {
1347 42156429 : this->nSize += _nSize;
1348 15089592 : }
1349 :
1350 : /** Pretend _nSize bytes are written, without specifying them. */
1351 23172404 : void seek(size_t _nSize)
1352 : {
1353 23172404 : this->nSize += _nSize;
1354 : }
1355 :
1356 : template <typename T>
1357 14850387 : CSizeComputer& operator<<(const T& obj)
1358 : {
1359 5071632 : ::Serialize(*this, obj);
1360 20855 : return (*this);
1361 : }
1362 :
1363 2738778 : size_t size() const
1364 : {
1365 2738778 : return nSize;
1366 : }
1367 :
1368 906 : int GetVersion() const { return nVersion; }
1369 : };
1370 :
1371 : template<typename Stream>
1372 : void SerializeMany(Stream& s)
1373 : {
1374 : }
1375 :
1376 : template<typename Stream, typename Arg, typename... Args>
1377 490030576 : void SerializeMany(Stream& s, const Arg& arg, const Args&... args)
1378 : {
1379 490030576 : ::Serialize(s, arg);
1380 213119654 : ::SerializeMany(s, args...);
1381 490030576 : }
1382 :
1383 : template<typename Stream>
1384 14225898 : inline void UnserializeMany(Stream& s)
1385 : {
1386 : }
1387 :
1388 : template<typename Stream, typename Arg, typename... Args>
1389 45994618 : inline void UnserializeMany(Stream& s, Arg&& arg, Args&&... args)
1390 : {
1391 32760665 : ::Unserialize(s, arg);
1392 32794088 : ::UnserializeMany(s, args...);
1393 22752921 : }
1394 :
1395 : template<typename Stream, typename... Args>
1396 276256490 : inline void SerReadWriteMany(Stream& s, CSerActionSerialize ser_action, const Args&... args)
1397 : {
1398 275012801 : ::SerializeMany(s, args...);
1399 4814 : }
1400 :
1401 : template<typename Stream, typename... Args>
1402 15197123 : inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&&... args)
1403 : {
1404 13841195 : ::UnserializeMany(s, args...);
1405 896 : }
1406 :
1407 : template<typename Stream, typename Type, typename Fn>
1408 47063 : inline void SerRead(Stream& s, CSerActionSerialize ser_action, Type&&, Fn&&)
1409 : {
1410 : }
1411 :
1412 : template<typename Stream, typename Type, typename Fn>
1413 12067 : inline void SerRead(Stream& s, CSerActionUnserialize ser_action, Type&& obj, Fn&& fn)
1414 : {
1415 12067 : fn(s, std::forward<Type>(obj));
1416 168 : }
1417 :
1418 : template<typename Stream, typename Type, typename Fn>
1419 18151 : inline void SerWrite(Stream& s, CSerActionSerialize ser_action, Type&& obj, Fn&& fn)
1420 : {
1421 18151 : fn(s, std::forward<Type>(obj));
1422 169 : }
1423 :
1424 : template<typename Stream, typename Type, typename Fn>
1425 1205 : inline void SerWrite(Stream& s, CSerActionUnserialize ser_action, Type&&, Fn&&)
1426 : {
1427 : }
1428 :
1429 : template<typename I>
1430 : inline void WriteVarInt(CSizeComputer &s, I n)
1431 : {
1432 : s.seek(GetSizeOfVarInt<I>(n));
1433 : }
1434 :
1435 23172404 : inline void WriteCompactSize(CSizeComputer &s, uint64_t nSize)
1436 : {
1437 23191219 : s.seek(GetSizeOfCompactSize(nSize));
1438 : }
1439 :
1440 : template <typename T>
1441 2738778 : size_t GetSerializeSize(const T& t, int nVersion = 0)
1442 : {
1443 2738778 : return (CSizeComputer(nVersion) << t).size();
1444 : }
1445 :
1446 : template <typename... T>
1447 : size_t GetSerializeSizeMany(int nVersion, const T&... t)
1448 : {
1449 : CSizeComputer sc(nVersion);
1450 : SerializeMany(sc, t...);
1451 : return sc.size();
1452 : }
1453 :
1454 : /**
1455 : * optional
1456 : */
1457 : template<typename T>
1458 188 : unsigned int GetSerializeSize(const Optional<T> &item)
1459 : {
1460 188 : if (item) {
1461 188 : return 1 + GetSerializeSize(*item);
1462 : } else {
1463 : return 1;
1464 : }
1465 : }
1466 :
1467 : #endif // PIVX_SERIALIZE_H
|