diff --git a/src/serialize.h b/src/serialize.h --- a/src/serialize.h +++ b/src/serialize.h @@ -606,7 +606,7 @@ #define VARINT_MODE(obj, mode) Using>(obj) #define VARINT(obj) Using>(obj) -#define COMPACTSIZE(obj) CCompactSize(REF(obj)) +#define COMPACTSIZE(obj) Using(obj) #define LIMITED_STRING(obj, n) LimitedString(REF(obj)) /** @@ -654,19 +654,25 @@ } }; -class CCompactSize { -protected: - uint64_t &n; - -public: - explicit CCompactSize(uint64_t &nIn) : n(nIn) {} - - template void Serialize(Stream &s) const { - WriteCompactSize(s, n); +/** Formatter for integers in CompactSize format. */ +struct CompactSizeFormatter { + template void Unser(Stream &s, I &v) { + uint64_t n = ReadCompactSize(s); + if (n < std::numeric_limits::min() || + n > std::numeric_limits::max()) { + throw std::ios_base::failure("CompactSize exceeds limit of type"); + } + v = n; } - template void Unserialize(Stream &s) { - n = ReadCompactSize(s); + template void Ser(Stream &s, I v) { + static_assert(std::is_unsigned::value, + "CompactSize only supported for unsigned integers"); + static_assert(std::numeric_limits::max() <= + std::numeric_limits::max(), + "CompactSize only supports 64-bit integers and below"); + + WriteCompactSize(s, v); } };