6 #ifndef BITCOIN_SERIALIZE_H
7 #define BITCOIN_SERIALIZE_H
31 static constexpr uint64_t
MAX_SIZE = 0x02000000;
62 inline const char *
CharCast(
const uint8_t *c) {
63 return (
const char *)c;
70 template <
typename Stream>
inline void ser_writedata8(Stream &s, uint8_t obj) {
71 s.write((
char *)&obj, 1);
73 template <
typename Stream>
76 s.write((
char *)&obj, 2);
78 template <
typename Stream>
81 s.write((
char *)&obj, 2);
83 template <
typename Stream>
86 s.write((
char *)&obj, 4);
88 template <
typename Stream>
91 s.write((
char *)&obj, 4);
93 template <
typename Stream>
96 s.write((
char *)&obj, 8);
100 s.read((
char *)&obj, 1);
105 s.read((
char *)&obj, 2);
110 s.read((
char *)&obj, 2);
115 s.read((
char *)&obj, 4);
120 s.read((
char *)&obj, 4);
125 s.read((
char *)&obj, 8);
130 std::memcpy(&tmp, &x,
sizeof(x));
131 static_assert(
sizeof(tmp) ==
sizeof(x),
132 "double and uint64_t assumed to have the same size");
137 std::memcpy(&tmp, &x,
sizeof(x));
138 static_assert(
sizeof(tmp) ==
sizeof(x),
139 "float and uint32_t assumed to have the same size");
144 std::memcpy(&tmp, &y,
sizeof(y));
145 static_assert(
sizeof(tmp) ==
sizeof(y),
146 "double and uint64_t assumed to have the same size");
151 std::memcpy(&tmp, &y,
sizeof(y));
152 static_assert(
sizeof(tmp) ==
sizeof(y),
153 "float and uint32_t assumed to have the same size");
180 #define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
181 #define READWRITEAS(type, obj) \
182 (::SerReadWriteMany(s, ser_action, ReadWriteAsHelper<type>(obj)))
183 #define SER_READ(obj, code) \
185 s, ser_action, obj, \
186 [&](Stream &s, typename std::remove_const<Type>::type &obj) { code; })
187 #define SER_WRITE(obj, code) \
188 ::SerWrite(s, ser_action, obj, [&](Stream &s, const Type &obj) { code; })
208 #define FORMATTER_METHODS(cls, obj) \
209 template <typename Stream> static void Ser(Stream &s, const cls &obj) { \
210 SerializationOps(obj, s, CSerActionSerialize()); \
212 template <typename Stream> static void Unser(Stream &s, cls &obj) { \
213 SerializationOps(obj, s, CSerActionUnserialize()); \
215 template <typename Stream, typename Type, typename Operation> \
216 static inline void SerializationOps(Type &obj, Stream &s, \
217 Operation ser_action)
227 #define SERIALIZE_METHODS(cls, obj) \
228 template <typename Stream> void Serialize(Stream &s) const { \
229 static_assert(std::is_same<const cls &, decltype(*this)>::value, \
230 "Serialize type mismatch"); \
233 template <typename Stream> void Unserialize(Stream &s) { \
234 static_assert(std::is_same<cls &, decltype(*this)>::value, \
235 "Unserialize type mismatch"); \
238 FORMATTER_METHODS(cls, obj)
240 #ifndef CHAR_EQUALS_INT8
242 template <
typename Stream>
inline void Serialize(Stream &s,
char a) {
246 template <
typename Stream>
inline void Serialize(Stream &s, int8_t a) {
249 template <
typename Stream>
inline void Serialize(Stream &s, uint8_t a) {
252 template <
typename Stream>
inline void Serialize(Stream &s, int16_t a) {
255 template <
typename Stream>
inline void Serialize(Stream &s, uint16_t a) {
258 template <
typename Stream>
inline void Serialize(Stream &s, int32_t a) {
261 template <
typename Stream>
inline void Serialize(Stream &s, uint32_t a) {
264 template <
typename Stream>
inline void Serialize(Stream &s, int64_t a) {
267 template <
typename Stream>
inline void Serialize(Stream &s, uint64_t a) {
270 template <
typename Stream>
inline void Serialize(Stream &s,
float a) {
273 template <
typename Stream>
inline void Serialize(Stream &s,
double a) {
276 template <
typename Stream,
size_t N>
277 inline void Serialize(Stream &s,
const int8_t (&a)[N]) {
280 template <
typename Stream,
size_t N>
281 inline void Serialize(Stream &s,
const uint8_t (&a)[N]) {
284 template <
typename Stream,
size_t N>
285 inline void Serialize(Stream &s,
const std::array<int8_t, N> &a) {
286 s.write(a.data(), N);
288 template <
typename Stream,
size_t N>
289 inline void Serialize(Stream &s,
const std::array<uint8_t, N> &a) {
292 #ifndef CHAR_EQUALS_INT8
294 template <
typename Stream>
inline void Unserialize(Stream &s,
char &a) {
297 template <
typename Stream,
size_t N>
301 template <
typename Stream,
size_t N>
302 inline void Serialize(Stream &s,
const std::array<char, N> &a) {
303 s.write(a.data(), N);
306 template <
typename Stream>
310 template <
typename Stream>
314 template <
typename Stream>
inline void Unserialize(Stream &s, int8_t &a) {
317 template <
typename Stream>
inline void Unserialize(Stream &s, uint8_t &a) {
320 template <
typename Stream>
inline void Unserialize(Stream &s, int16_t &a) {
323 template <
typename Stream>
inline void Unserialize(Stream &s, uint16_t &a) {
326 template <
typename Stream>
inline void Unserialize(Stream &s, int32_t &a) {
329 template <
typename Stream>
inline void Unserialize(Stream &s, uint32_t &a) {
332 template <
typename Stream>
inline void Unserialize(Stream &s, int64_t &a) {
335 template <
typename Stream>
inline void Unserialize(Stream &s, uint64_t &a) {
338 template <
typename Stream>
inline void Unserialize(Stream &s,
float &a) {
341 template <
typename Stream>
inline void Unserialize(Stream &s,
double &a) {
344 template <
typename Stream,
size_t N>
348 template <
typename Stream,
size_t N>
352 template <
typename Stream,
size_t N>
356 template <
typename Stream,
size_t N>
360 #ifndef CHAR_EQUALS_INT8
361 template <
typename Stream,
size_t N>
365 template <
typename Stream,
size_t N>
371 template <
typename Stream>
inline void Serialize(Stream &s,
bool a) {
375 template <
typename Stream>
inline void Unserialize(Stream &s,
bool &a) {
379 template <
typename Stream>
393 return sizeof(uint8_t);
395 if (
nSize <= std::numeric_limits<uint16_t>::max()) {
396 return sizeof(uint8_t) +
sizeof(uint16_t);
398 if (
nSize <= std::numeric_limits<uint32_t>::max()) {
399 return sizeof(uint8_t) +
sizeof(uint32_t);
402 return sizeof(uint8_t) +
sizeof(uint64_t);
410 }
else if (
nSize <= std::numeric_limits<uint16_t>::max()) {
413 }
else if (
nSize <= std::numeric_limits<uint32_t>::max()) {
430 template <
typename Stream>
433 uint64_t nSizeRet = 0;
436 }
else if (chSize == 253) {
438 if (nSizeRet < 253) {
439 throw std::ios_base::failure(
"non-canonical ReadCompactSize()");
441 }
else if (chSize == 254) {
443 if (nSizeRet < 0x10000u) {
444 throw std::ios_base::failure(
"non-canonical ReadCompactSize()");
448 if (nSizeRet < 0x100000000ULL) {
449 throw std::ios_base::failure(
"non-canonical ReadCompactSize()");
452 if (range_check && nSizeRet >
MAX_SIZE) {
453 throw std::ios_base::failure(
"ReadCompactSize(): size too large");
497 "Unsigned type required with mode DEFAULT.");
499 std::is_signed<I>::value,
500 "Signed type required with mode NONNEGATIVE_SIGNED.");
504 template <VarIntMode Mode,
typename I>
519 template <
typename Stream, VarIntMode Mode,
typename I>
522 uint8_t tmp[(
sizeof(n) * 8 + 6) / 7];
525 tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);
537 template <
typename Stream, VarIntMode Mode,
typename I>
543 if (n > (std::numeric_limits<I>::max() >> 7)) {
544 throw std::ios_base::failure(
"ReadVarInt(): size too large");
546 n = (n << 7) | (chData & 0x7F);
547 if ((chData & 0x80) == 0) {
550 if (n == std::numeric_limits<I>::max()) {
551 throw std::ios_base::failure(
"ReadVarInt(): size too large");
561 template <
typename Formatter,
typename T>
class Wrapper {
562 static_assert(std::is_lvalue_reference<T>::value,
563 "Wrapper needs an lvalue reference type T");
570 template <
typename Stream>
void Serialize(Stream &s)
const {
591 template <
typename Formatter,
typename T>
596 #define VARINT_MODE(obj, mode) Using<VarIntFormatter<mode>>(obj)
597 #define VARINT(obj) Using<VarIntFormatter<VarIntMode::DEFAULT>>(obj)
598 #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj)
599 #define LIMITED_STRING(obj, n) Using<LimitedStringFormatter<n>>(obj)
605 template <
typename Stream,
typename I>
void Ser(Stream &s, I v) {
606 WriteVarInt<Stream, Mode, typename std::remove_cv<I>::type>(s, v);
609 template <
typename Stream,
typename I>
void Unser(Stream &s, I &v) {
610 v = ReadVarInt<Stream, Mode, typename std::remove_cv<I>::type>(s);
625 static_assert(Bytes > 0 && Bytes <= 8,
626 "CustomUintFormatter Bytes out of range");
627 static constexpr uint64_t
MAX = 0xffffffffffffffff >> (8 * (8 - Bytes));
629 template <
typename Stream,
typename I>
void Ser(Stream &s, I v) {
630 if (v < 0 || v >
MAX) {
631 throw std::ios_base::failure(
632 "CustomUintFormatter value out of range");
636 s.write(((
const char *)&raw) + 8 - Bytes, Bytes);
639 s.write((
const char *)&raw, Bytes);
643 template <
typename Stream,
typename I>
void Unser(Stream &s, I &v) {
644 using U =
typename std::conditional<std::is_enum<I>::value,
645 std::underlying_type<I>,
646 std::common_type<I>>::type::type;
647 static_assert(std::numeric_limits<U>::max() >=
MAX &&
648 std::numeric_limits<U>::min() <= 0,
649 "Assigned type too small");
652 s.read(((
char *)&raw) + 8 - Bytes, Bytes);
653 v =
static_cast<I
>(
be64toh(raw));
655 s.read((
char *)&raw, Bytes);
656 v =
static_cast<I
>(
le64toh(raw));
666 template <
typename Stream,
typename I>
void Unser(Stream &s, I &v) {
667 uint64_t n = ReadCompactSize<Stream>(s, RangeCheck);
668 if (n < std::numeric_limits<I>::min() ||
669 n > std::numeric_limits<I>::max()) {
670 throw std::ios_base::failure(
"CompactSize exceeds limit of type");
675 template <
typename Stream,
typename I>
void Ser(Stream &s, I v) {
676 static_assert(std::is_unsigned<I>::value,
677 "CompactSize only supported for unsigned integers");
678 static_assert(std::numeric_limits<I>::max() <=
679 std::numeric_limits<uint64_t>::max(),
680 "CompactSize only supports 64-bit integers and below");
682 WriteCompactSize<Stream>(s, v);
687 template <
typename Stream>
void Unser(Stream &s, std::string &v) {
690 throw std::ios_base::failure(
"String length limit exceeded");
694 s.read((
char *)v.data(), size);
698 template <
typename Stream>
void Ser(Stream &s,
const std::string &v) {
720 template <
typename Stream,
typename V>
void Ser(Stream &s,
const V &v) {
723 for (
const typename V::value_type &elem : v) {
724 formatter.Ser(s, elem);
728 template <
typename Stream,
typename V>
void Unser(Stream &s, V &v) {
732 size_t allocated = 0;
733 while (allocated < size) {
739 "Vector element size too large");
742 sizeof(
typename V::value_type));
743 v.reserve(allocated);
744 while (v.size() < allocated) {
746 formatter.Unser(s, v.back());
766 template <
typename Stream,
typename I>
void Ser(Stream &s, I v) {
767 if (v < m_shift || v >= std::numeric_limits<uint64_t>::max()) {
768 throw std::ios_base::failure(
"differential value overflow");
773 template <
typename Stream,
typename I>
void Unser(Stream &s, I &v) {
776 if (m_shift < n || m_shift >= std::numeric_limits<uint64_t>::max() ||
777 m_shift < std::numeric_limits<I>::min() ||
778 m_shift > std::numeric_limits<I>::max()) {
779 throw std::ios_base::failure(
"differential value overflow");
796 template <
typename Stream,
typename T>
void Ser(Stream &s, T v) {
801 template <
typename Stream,
typename T>
void Unser(Stream &s, T &v) {
814 template <
typename Stream,
typename C>
815 void Serialize(Stream &os,
const std::basic_string<C> &str);
816 template <
typename Stream,
typename C>
817 void Unserialize(Stream &is, std::basic_string<C> &str);
824 template <
typename Stream,
unsigned int N,
typename T>
826 template <
typename Stream,
unsigned int N,
typename T,
typename V>
828 template <
typename Stream,
unsigned int N,
typename T>
830 template <
typename Stream,
unsigned int N,
typename T>
832 template <
typename Stream,
unsigned int N,
typename T,
typename V>
834 template <
typename Stream,
unsigned int N,
typename T>
842 template <
typename Stream,
typename T,
typename A>
843 void Serialize_impl(Stream &os,
const std::vector<T, A> &v,
const uint8_t &);
844 template <
typename Stream,
typename T,
typename A>
845 void Serialize_impl(Stream &os,
const std::vector<T, A> &v,
const bool &);
846 template <
typename Stream,
typename T,
typename A,
typename V>
847 void Serialize_impl(Stream &os,
const std::vector<T, A> &v,
const V &);
848 template <
typename Stream,
typename T,
typename A>
849 inline void Serialize(Stream &os,
const std::vector<T, A> &v);
850 template <
typename Stream,
typename T,
typename A>
852 template <
typename Stream,
typename T,
typename A,
typename V>
854 template <
typename Stream,
typename T,
typename A>
855 inline void Unserialize(Stream &is, std::vector<T, A> &v);
860 template <
typename Stream,
typename K,
typename T>
861 void Serialize(Stream &os,
const std::pair<K, T> &item);
862 template <
typename Stream,
typename K,
typename T>
863 void Unserialize(Stream &is, std::pair<K, T> &item);
868 template <
typename Stream,
typename K,
typename T,
typename Pred,
typename A>
869 void Serialize(Stream &os,
const std::map<K, T, Pred, A> &m);
870 template <
typename Stream,
typename K,
typename T,
typename Pred,
typename A>
871 void Unserialize(Stream &is, std::map<K, T, Pred, A> &m);
876 template <
typename Stream,
typename K,
typename Pred,
typename A>
877 void Serialize(Stream &os,
const std::set<K, Pred, A> &m);
878 template <
typename Stream,
typename K,
typename Pred,
typename A>
879 void Unserialize(Stream &is, std::set<K, Pred, A> &m);
884 template <
typename Stream,
typename T>
885 void Serialize(Stream &os,
const std::shared_ptr<const T> &p);
886 template <
typename Stream,
typename T>
887 void Unserialize(Stream &os, std::shared_ptr<const T> &p);
892 template <
typename Stream,
typename T>
893 void Serialize(Stream &os,
const std::unique_ptr<const T> &p);
894 template <
typename Stream,
typename T>
895 void Unserialize(Stream &os, std::unique_ptr<const T> &p);
900 template <
typename Stream,
typename T>
902 template <
typename Stream,
typename T>
909 template <
typename Stream,
typename T>
914 template <
typename Stream,
typename T>
926 template <
typename Stream,
typename T>
927 static void Ser(Stream &s,
const T &t) {
931 template <
typename Stream,
typename T>
static void Unser(Stream &s, T &t) {
939 template <
typename Stream,
typename C>
940 void Serialize(Stream &os,
const std::basic_string<C> &str) {
943 os.write((
char *)str.data(), str.size() *
sizeof(C));
947 template <
typename Stream,
typename C>
952 is.read((
char *)str.data(), nSize *
sizeof(C));
959 template <
typename Stream,
unsigned int N,
typename T>
963 os.write((
char *)v.
data(), v.
size() *
sizeof(T));
967 template <
typename Stream,
unsigned int N,
typename T,
typename V>
972 template <
typename Stream,
unsigned int N,
typename T>
977 template <
typename Stream,
unsigned int N,
typename T>
984 size_t blk = std::min(nSize - i,
size_t(1 + 4999999 /
sizeof(T)));
986 is.read((
char *)&v[i], blk *
sizeof(T));
991 template <
typename Stream,
unsigned int N,
typename T,
typename V>
996 template <
typename Stream,
unsigned int N,
typename T>
1004 template <
typename Stream,
typename T,
typename A>
1008 os.write((
char *)v.data(), v.size() *
sizeof(T));
1012 template <
typename Stream,
typename T,
typename A>
1018 for (
bool elem : v) {
1023 template <
typename Stream,
typename T,
typename A,
typename V>
1028 template <
typename Stream,
typename T,
typename A>
1029 inline void Serialize(Stream &os,
const std::vector<T, A> &v) {
1033 template <
typename Stream,
typename T,
typename A>
1040 size_t blk = std::min(nSize - i,
size_t(1 + 4999999 /
sizeof(T)));
1042 is.read((
char *)&v[i], blk *
sizeof(T));
1047 template <
typename Stream,
typename T,
typename A,
typename V>
1052 template <
typename Stream,
typename T,
typename A>
1060 template <
typename Stream,
typename K,
typename T>
1066 template <
typename Stream,
typename K,
typename T>
1075 template <
typename Stream,
typename K,
typename T,
typename Pred,
typename A>
1076 void Serialize(Stream &os,
const std::map<K, T, Pred, A> &m) {
1078 for (
const auto &entry : m) {
1083 template <
typename Stream,
typename K,
typename T,
typename Pred,
typename A>
1087 typename std::map<K, T, Pred, A>::iterator mi = m.begin();
1088 for (
size_t i = 0; i < nSize; i++) {
1089 std::pair<K, T> item;
1091 mi = m.insert(mi, item);
1098 template <
typename Stream,
typename K,
typename Pred,
typename A>
1101 for (
const K &i : m) {
1106 template <
typename Stream,
typename K,
typename Pred,
typename A>
1110 typename std::set<K, Pred, A>::iterator it = m.begin();
1111 for (
size_t i = 0; i < nSize; i++) {
1114 it = m.insert(it, key);
1121 template <
typename Stream,
typename T>
1122 void Serialize(Stream &os,
const std::unique_ptr<const T> &p) {
1126 template <
typename Stream,
typename T>
1134 template <
typename Stream,
typename T>
1135 void Serialize(Stream &os,
const std::shared_ptr<const T> &p) {
1139 template <
typename Stream,
typename T>
1147 template <
typename Stream,
typename T>
1152 template <
typename Stream,
typename T>
1188 void write(
const char *psz,
size_t _nSize) { this->nSize += _nSize; }
1191 void seek(
size_t _nSize) { this->nSize += _nSize; }
1205 template <
typename Stream,
typename Arg,
typename... Args>
1213 template <
typename Stream,
typename Arg,
typename... Args>
1219 template <
typename Stream,
typename... Args>
1221 const Args &...args) {
1225 template <
typename Stream,
typename... Args>
1231 template <
typename Stream,
typename Type,
typename Fn>
1235 template <
typename Stream,
typename Type,
typename Fn>
1238 fn(s, std::forward<Type>(obj));
1241 template <
typename Stream,
typename Type,
typename Fn>
1244 fn(s, std::forward<Type>(obj));
1247 template <
typename Stream,
typename Type,
typename Fn>
1252 s.
seek(GetSizeOfVarInt<I>(n));
1263 template <
typename... T>
GetSerializeSize implementations
CSizeComputer & operator<<(const T &obj)
void write(const char *psz, size_t _nSize)
CSizeComputer(int nVersionIn)
void seek(size_t _nSize)
Pretend _nSize bytes are written, without specifying them.
static RCUPtr make(Args &&...args)
Construct a new object that is owned by the pointer.
A Span is an object that can refer to a contiguous sequence of objects.
constexpr std::size_t size() const noexcept
constexpr C * data() const noexcept
Simple wrapper class to serialize objects using a formatter; used by Using().
void Serialize(Stream &s) const
void Unserialize(Stream &s)
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
void resize_uninitialized(size_type new_size)
uint16_t be16toh(uint16_t big_endian_16bits)
uint16_t htobe16(uint16_t host_16bits)
uint32_t le32toh(uint32_t little_endian_32bits)
uint32_t htobe32(uint32_t host_32bits)
uint16_t le16toh(uint16_t little_endian_16bits)
uint64_t htobe64(uint64_t host_64bits)
uint64_t be64toh(uint64_t big_endian_64bits)
uint32_t be32toh(uint32_t big_endian_32bits)
uint64_t htole64(uint64_t host_64bits)
uint32_t htole32(uint32_t host_32bits)
uint16_t htole16(uint16_t host_16bits)
uint64_t le64toh(uint64_t little_endian_64bits)
void SerializeMany(Stream &s)
static const unsigned int MAX_VECTOR_ALLOCATE
Maximum amount of memory (in bytes) to allocate at once when deserializing vectors.
uint8_t ser_readdata8(Stream &s)
float ser_uint32_to_float(uint32_t y)
void ser_writedata32be(Stream &s, uint32_t obj)
void WriteVarInt(CSizeComputer &os, I n)
VarIntMode
Variable-length integers: bytes are a MSB base-128 encoding of the number.
void ser_writedata32(Stream &s, uint32_t obj)
size_t GetSerializeSizeMany(int nVersion, const T &...t)
uint32_t GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
constexpr deserialize_type deserialize
void Serialize(Stream &s, char a)
void ser_writedata16(Stream &s, uint16_t obj)
uint32_t ser_float_to_uint32(float x)
static Wrapper< Formatter, T & > Using(T &&t)
Cause serialization/deserialization of an object to be done using a specified formatter class.
X & ReadWriteAsHelper(X &x)
Convert the reference base type to X, without changing constness or reference type.
void Unserialize_impl(Stream &is, prevector< N, T > &v, const uint8_t &)
void Unserialize(Stream &s, char &a)
void SerReadWriteMany(Stream &s, CSerActionSerialize ser_action, const Args &...args)
void SerWrite(Stream &s, CSerActionSerialize ser_action, Type &&obj, Fn &&fn)
char * CharCast(char *c)
Safely convert odd char pointer types to standard ones.
void ser_writedata16be(Stream &s, uint16_t obj)
uint16_t ser_readdata16(Stream &s)
uint64_t ser_readdata64(Stream &s)
double ser_uint64_to_double(uint64_t y)
void ser_writedata8(Stream &s, uint8_t obj)
Lowest-level serialization and conversion.
uint64_t ReadCompactSize(Stream &is, bool range_check=true)
Decode a CompactSize-encoded variable-length integer.
unsigned int GetSizeOfVarInt(I n)
uint32_t ser_readdata32(Stream &s)
uint16_t ser_readdata16be(Stream &s)
void SerRead(Stream &s, CSerActionSerialize ser_action, Type &&, Fn &&)
void Serialize_impl(Stream &os, const prevector< N, T > &v, const uint8_t &)
prevector prevectors of uint8_t are a special case and are intended to be serialized as a single opaq...
size_t GetSerializeSize(const T &t, int nVersion=0)
void UnserializeMany(Stream &s)
uint64_t ser_double_to_uint64(double x)
void ser_writedata64(Stream &s, uint64_t obj)
uint32_t ser_readdata32be(Stream &s)
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Support for SERIALIZE_METHODS and READWRITE macro.
constexpr bool ForRead() const
constexpr bool ForRead() const
constexpr CheckVarIntMode()
Dummy data type to identify deserializing constructors.