diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2018-04-08 09:39:05 -0700 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2018-04-08 15:31:01 -0700 |
commit | ece88fd26995350dfaa4675b4291605a20203527 (patch) | |
tree | 580a594a66289796f73812d5a5f98c5a0d8d4476 /src/serialize.h | |
parent | 97785863e2faa4a6d4e1130e300011985df0858c (diff) |
Introduce BigEndian wrapper and use it for netaddress ports
Diffstat (limited to 'src/serialize.h')
-rw-r--r-- | src/serialize.h | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/serialize.h b/src/serialize.h index e90b041cc2..2491879c36 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -79,6 +79,11 @@ template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj) obj = htole16(obj); s.write((char*)&obj, 2); } +template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj) +{ + obj = htobe16(obj); + s.write((char*)&obj, 2); +} template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj) { obj = htole32(obj); @@ -101,6 +106,12 @@ template<typename Stream> inline uint16_t ser_readdata16(Stream &s) s.read((char*)&obj, 2); return le16toh(obj); } +template<typename Stream> inline uint16_t ser_readdata16be(Stream &s) +{ + uint16_t obj; + s.read((char*)&obj, 2); + return be16toh(obj); +} template<typename Stream> inline uint32_t ser_readdata32(Stream &s) { uint32_t obj; @@ -411,6 +422,40 @@ public: } }; +/** Serialization wrapper class for big-endian integers. + * + * Use this wrapper around integer types that are stored in memory in native + * byte order, but serialized in big endian notation. This is only intended + * to implement serializers that are compatible with existing formats, and + * its use is not recommended for new data structures. + * + * Only 16-bit types are supported for now. + */ +template<typename I> +class BigEndian +{ +protected: + I& m_val; +public: + explicit BigEndian(I& val) : m_val(val) + { + static_assert(std::is_unsigned<I>::value, "BigEndian type must be unsigned integer"); + 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"); + } + + template<typename Stream> + void Serialize(Stream& s) const + { + ser_writedata16be(s, m_val); + } + + template<typename Stream> + void Unserialize(Stream& s) + { + m_val = ser_readdata16be(s); + } +}; + class CCompactSize { protected: @@ -461,6 +506,9 @@ public: template<VarIntMode Mode=VarIntMode::DEFAULT, typename I> CVarInt<Mode, I> WrapVarInt(I& n) { return CVarInt<Mode, I>{n}; } +template<typename I> +BigEndian<I> WrapBigEndian(I& n) { return BigEndian<I>(n); } + /** * Forward declarations */ |