6 #ifndef BITCOIN_SERIALIZE_H 7 #define BITCOIN_SERIALIZE_H 27 static const unsigned int MAX_SIZE = 0x02000000;
48 inline T&
REF(
const T& val)
50 return const_cast<T&
>(val);
60 return const_cast<T*
>(val);
65 inline char*
CharCast(
unsigned char* c) {
return (
char*)c; }
66 inline const char*
CharCast(
const char* c) {
return c; }
67 inline const char*
CharCast(
const unsigned char* c) {
return (
const char*)c; }
75 s.write((
char*)&obj, 1);
80 s.write((
char*)&obj, 2);
85 s.write((
char*)&obj, 2);
90 s.write((
char*)&obj, 4);
95 s.write((
char*)&obj, 8);
100 s.read((
char*)&obj, 1);
106 s.read((
char*)&obj, 2);
112 s.read((
char*)&obj, 2);
118 s.read((
char*)&obj, 4);
124 s.read((
char*)&obj, 8);
129 union {
double x; uint64_t y; } tmp;
135 union {
float x; uint32_t y; } tmp;
141 union {
double x; uint64_t y; } tmp;
147 union {
float x; uint32_t y; } tmp;
173 #define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__)) 174 #define READWRITEAS(type, obj) (::SerReadWriteMany(s, ser_action, ReadWriteAsHelper<type>(obj))) 182 #define ADD_SERIALIZE_METHODS \ 183 template<typename Stream> \ 184 void Serialize(Stream& s) const { \ 185 NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize()); \ 187 template<typename Stream> \ 188 void Unserialize(Stream& s) { \ 189 SerializationOp(s, CSerActionUnserialize()); \ 192 #ifndef CHAR_EQUALS_INT8 205 template<
typename Stream,
int N>
inline void Serialize(Stream& s,
const char (&a)[N]) { s.write(a, N); }
206 template<
typename Stream,
int N>
inline void Serialize(Stream& s,
const unsigned char (&a)[N]) { s.write(
CharCast(a), N); }
210 #ifndef CHAR_EQUALS_INT8 223 template<
typename Stream,
int N>
inline void Unserialize(Stream& s,
char (&a)[N]) { s.read(a, N); }
224 template<
typename Stream,
int N>
inline void Unserialize(Stream& s,
unsigned char (&a)[N]) { s.read(
CharCast(a), N); }
244 if (
nSize < 253)
return sizeof(
unsigned char);
245 else if (
nSize <= std::numeric_limits<unsigned short>::max())
return sizeof(
unsigned char) +
sizeof(
unsigned short);
246 else if (
nSize <= std::numeric_limits<unsigned int>::max())
return sizeof(
unsigned char) +
sizeof(
unsigned int);
247 else return sizeof(
unsigned char) +
sizeof(uint64_t);
252 template<
typename Stream>
259 else if (
nSize <= std::numeric_limits<unsigned short>::max())
264 else if (
nSize <= std::numeric_limits<unsigned int>::max())
277 template<
typename Stream>
281 uint64_t nSizeRet = 0;
286 else if (chSize == 253)
290 throw std::ios_base::failure(
"non-canonical ReadCompactSize()");
292 else if (chSize == 254)
295 if (nSizeRet < 0x10000u)
296 throw std::ios_base::failure(
"non-canonical ReadCompactSize()");
301 if (nSizeRet < 0x100000000ULL)
302 throw std::ios_base::failure(
"non-canonical ReadCompactSize()");
304 if (nSizeRet > (uint64_t)MAX_SIZE)
305 throw std::ios_base::failure(
"ReadCompactSize(): size too large");
345 template <VarIntMode Mode,
typename I>
349 static_assert(Mode !=
VarIntMode::DEFAULT || std::is_unsigned<I>::value,
"Unsigned type required with mode DEFAULT.");
354 template<VarIntMode Mode,
typename I>
371 template<
typename Stream, VarIntMode Mode,
typename I>
375 unsigned char tmp[(
sizeof(n)*8+6)/7];
378 tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
389 template<
typename Stream, VarIntMode Mode,
typename I>
396 if (n > (std::numeric_limits<I>::max() >> 7)) {
397 throw std::ios_base::failure(
"ReadVarInt(): size too large");
399 n = (n << 7) | (chData & 0x7F);
401 if (n == std::numeric_limits<I>::max()) {
402 throw std::ios_base::failure(
"ReadVarInt(): size too large");
411 #define VARINT(obj, ...) WrapVarInt<__VA_ARGS__>(REF(obj)) 412 #define COMPACTSIZE(obj) CCompactSize(REF(obj)) 413 #define LIMITED_STRING(obj,n) LimitedString< n >(REF(obj)) 415 template<VarIntMode Mode,
typename I>
423 template<
typename Stream>
425 WriteVarInt<Stream,Mode,I>(s,
n);
428 template<
typename Stream>
430 n = ReadVarInt<Stream,Mode,I>(s);
451 static_assert(std::is_unsigned<I>::value,
"BigEndian type must be unsigned integer");
452 static_assert(
sizeof(I) == 2 && std::numeric_limits<I>::min() == 0 && std::numeric_limits<I>::max() == std::numeric_limits<uint16_t>::max(),
"Unsupported BigEndian size");
455 template<
typename Stream>
461 template<
typename Stream>
475 template<
typename Stream>
477 WriteCompactSize<Stream>(s,
n);
480 template<
typename Stream>
482 n = ReadCompactSize<Stream>(s);
486 template<
size_t Limit>
494 template<
typename Stream>
499 throw std::ios_base::failure(
"String length limit exceeded");
503 s.read((
char*)
string.data(), size);
506 template<
typename Stream>
511 s.write((
char*)
string.data(),
string.size());
515 template<VarIntMode Mode=VarIntMode::DEFAULT,
typename I>
528 template<
typename Stream,
typename C>
void Serialize(Stream& os,
const std::basic_string<C>& str);
529 template<
typename Stream,
typename C>
void Unserialize(Stream& is, std::basic_string<C>& str);
546 template<
typename Stream,
typename T,
typename A>
void Serialize_impl(Stream& os,
const std::vector<T, A>& v,
const unsigned char&);
547 template<
typename Stream,
typename T,
typename A,
typename V>
void Serialize_impl(Stream& os,
const std::vector<T, A>& v,
const V&);
548 template<
typename Stream,
typename T,
typename A>
inline void Serialize(Stream& os,
const std::vector<T, A>& v);
549 template<
typename Stream,
typename T,
typename A>
void Unserialize_impl(Stream& is, std::vector<T, A>& v,
const unsigned char&);
550 template<
typename Stream,
typename T,
typename A,
typename V>
void Unserialize_impl(Stream& is, std::vector<T, A>& v,
const V&);
551 template<
typename Stream,
typename T,
typename A>
inline void Unserialize(Stream& is, std::vector<T, A>& v);
556 template<
typename Stream,
typename K,
typename T>
void Serialize(Stream& os,
const std::pair<K, T>& item);
557 template<
typename Stream,
typename K,
typename T>
void Unserialize(Stream& is, std::pair<K, T>& item);
562 template<
typename Stream,
typename K,
typename T,
typename Pred,
typename A>
void Serialize(Stream& os,
const std::map<K, T, Pred, A>& m);
563 template<
typename Stream,
typename K,
typename T,
typename Pred,
typename A>
void Unserialize(Stream& is, std::map<K, T, Pred, A>& m);
568 template<
typename Stream,
typename K,
typename Pred,
typename A>
void Serialize(Stream& os,
const std::set<K, Pred, A>& m);
569 template<
typename Stream,
typename K,
typename Pred,
typename A>
void Unserialize(Stream& is, std::set<K, Pred, A>& m);
574 template<
typename Stream,
typename T>
void Serialize(Stream& os,
const std::shared_ptr<const T>& p);
575 template<
typename Stream,
typename T>
void Unserialize(Stream& os, std::shared_ptr<const T>& p);
580 template<
typename Stream,
typename T>
void Serialize(Stream& os,
const std::unique_ptr<const T>& p);
581 template<
typename Stream,
typename T>
void Unserialize(Stream& os, std::unique_ptr<const T>& p);
588 template<
typename Stream,
typename T>
594 template<
typename Stream,
typename T>
607 template<
typename Stream,
typename C>
608 void Serialize(Stream& os,
const std::basic_string<C>& str)
612 os.write((
char*)str.data(), str.size() *
sizeof(C));
615 template<
typename Stream,
typename C>
621 is.read((
char*)str.data(), nSize *
sizeof(C));
629 template<
typename Stream,
unsigned int N,
typename T>
634 os.write((
char*)v.
data(), v.
size() *
sizeof(T));
637 template<
typename Stream,
unsigned int N,
typename T,
typename V>
645 template<
typename Stream,
unsigned int N,
typename T>
652 template<
typename Stream,
unsigned int N,
typename T>
661 unsigned int blk = std::min(nSize - i, (
unsigned int)(1 + 4999999 /
sizeof(T)));
663 is.read((
char*)&v[i], blk *
sizeof(T));
668 template<
typename Stream,
unsigned int N,
typename T,
typename V>
674 unsigned int nMid = 0;
677 nMid += 5000000 /
sizeof(T);
681 for (; i < nMid; i++)
686 template<
typename Stream,
unsigned int N,
typename T>
697 template<
typename Stream,
typename T,
typename A>
698 void Serialize_impl(Stream& os,
const std::vector<T, A>& v,
const unsigned char&)
702 os.write((
char*)v.data(), v.size() *
sizeof(T));
705 template<
typename Stream,
typename T,
typename A,
typename V>
709 for (
typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
713 template<
typename Stream,
typename T,
typename A>
714 inline void Serialize(Stream& os,
const std::vector<T, A>& v)
720 template<
typename Stream,
typename T,
typename A>
729 unsigned int blk = std::min(nSize - i, (
unsigned int)(1 + 4999999 /
sizeof(T)));
731 is.read((
char*)&v[i], blk *
sizeof(T));
736 template<
typename Stream,
typename T,
typename A,
typename V>
742 unsigned int nMid = 0;
745 nMid += 5000000 /
sizeof(T);
749 for (; i < nMid; i++)
754 template<
typename Stream,
typename T,
typename A>
765 template<
typename Stream,
typename K,
typename T>
772 template<
typename Stream,
typename K,
typename T>
784 template<
typename Stream,
typename K,
typename T,
typename Pred,
typename A>
785 void Serialize(Stream& os,
const std::map<K, T, Pred, A>& m)
788 for (
const auto& entry : m)
792 template<
typename Stream,
typename K,
typename T,
typename Pred,
typename A>
797 typename std::map<K, T, Pred, A>::iterator mi = m.begin();
798 for (
unsigned int i = 0; i < nSize; i++)
800 std::pair<K, T> item;
802 mi = m.insert(mi, item);
811 template<
typename Stream,
typename K,
typename Pred,
typename A>
812 void Serialize(Stream& os,
const std::set<K, Pred, A>& m)
815 for (
typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
819 template<
typename Stream,
typename K,
typename Pred,
typename A>
824 typename std::set<K, Pred, A>::iterator it = m.begin();
825 for (
unsigned int i = 0; i < nSize; i++)
829 it = m.insert(it, key);
838 template<
typename Stream,
typename T>
void 839 Serialize(Stream& os,
const std::unique_ptr<const T>& p)
844 template<
typename Stream,
typename T>
855 template<
typename Stream,
typename T>
void 856 Serialize(Stream& os,
const std::shared_ptr<const T>& p)
861 template<
typename Stream,
typename T>
874 constexpr
bool ForRead()
const {
return false; }
878 constexpr
bool ForRead()
const {
return true; }
908 void write(
const char *psz,
size_t _nSize)
910 this->nSize += _nSize;
916 this->nSize += _nSize;
933 template<
typename Stream>
938 template<
typename Stream,
typename Arg,
typename... Args>
945 template<
typename Stream>
950 template<
typename Stream,
typename Arg,
typename... Args>
957 template<
typename Stream,
typename... Args>
963 template<
typename Stream,
typename... Args>
972 s.
seek(GetSizeOfVarInt<I>(n));
980 template <
typename T>
986 template <
typename... T>
994 #endif // BITCOIN_SERIALIZE_H uint64_t ser_double_to_uint64(double x)
CSizeComputer(int nVersionIn)
X & ReadWriteAsHelper(X &x)
Convert the reference base type to X, without changing constness or reference type.
void Unserialize(Stream &s)
constexpr std::ptrdiff_t size() const noexcept
void resize(size_type new_size)
uint32_t ser_float_to_uint32(float x)
uint8_t ser_readdata8(Stream &s)
void ser_writedata64(Stream &s, uint64_t obj)
uint64_t ReadCompactSize(Stream &is)
void WriteVarInt(CSizeComputer &os, I n)
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
void ser_writedata32(Stream &s, uint32_t obj)
constexpr deserialize_type deserialize
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 ...
CCompactSize(uint64_t &nIn)
void Unserialize(Stream &s)
void UnserializeMany(Stream &s)
BigEndian< I > WrapBigEndian(I &n)
uint32_t htole32(uint32_t host_32bits)
Dummy data type to identify deserializing constructors.
char * CharCast(char *c)
Safely convert odd char pointer types to standard ones.
size_t GetSerializeSize(const T &t, int nVersion=0)
void Serialize(Stream &s, char a)
CVarInt< Mode, I > WrapVarInt(I &n)
void Unserialize(Stream &s)
CSizeComputer & operator<<(const T &obj)
void Serialize(Stream &s) const
void SerReadWriteMany(Stream &s, CSerActionSerialize ser_action, const Args &... args)
uint16_t ser_readdata16(Stream &s)
uint32_t ser_readdata32(Stream &s)
void Serialize(Stream &s) const
Serialization wrapper class for big-endian integers.
constexpr CheckVarIntMode()
void ser_writedata16(Stream &s, uint16_t obj)
uint16_t htobe16(uint16_t host_16bits)
constexpr bool ForRead() const
VarIntMode
Variable-length integers: bytes are a MSB base-128 encoding of the number.
uint16_t le16toh(uint16_t little_endian_16bits)
double ser_uint64_to_double(uint64_t y)
Support for ADD_SERIALIZE_METHODS and READWRITE macro.
constexpr bool ForRead() const
void SerializeMany(Stream &s)
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
uint64_t ser_readdata64(Stream &s)
void seek(size_t _nSize)
Pretend _nSize bytes are written, without specifying them.
uint16_t htole16(uint16_t host_16bits)
uint16_t ser_readdata16be(Stream &s)
uint64_t le64toh(uint64_t little_endian_64bits)
uint16_t be16toh(uint16_t big_endian_16bits)
constexpr C * data() const noexcept
void Unserialize(Stream &s)
uint64_t htole64(uint64_t host_64bits)
void write(const char *psz, size_t _nSize)
void Serialize(Stream &s) const
unsigned int GetSizeOfVarInt(I n)
size_t GetSerializeSizeMany(int nVersion, const T &... t)
void Unserialize(Stream &s, char &a)
void ser_writedata16be(Stream &s, uint16_t obj)
void Serialize(Stream &s) const
A Span is an object that can refer to a contiguous sequence of objects.
void Serialize_impl(Stream &os, const prevector< N, T > &v, const unsigned char &)
prevector prevectors of unsigned char are a special case and are intended to be serialized as a singl...
T * NCONST_PTR(const T *val)
Used to acquire a non-const pointer "this" to generate bodies of const serialization operations from ...
void Unserialize_impl(Stream &is, prevector< N, T > &v, const unsigned char &)
uint32_t le32toh(uint32_t little_endian_32bits)
T & REF(const T &val)
Used to bypass the rule against non-const reference to temporary where it makes sense with wrappers...
LimitedString(std::string &_string)
void ser_writedata8(Stream &s, uint8_t obj)
float ser_uint32_to_float(uint32_t y)