aboutsummaryrefslogtreecommitdiff
path: root/src/serialize.h
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2018-04-08 09:39:05 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2018-04-08 15:31:01 -0700
commitece88fd26995350dfaa4675b4291605a20203527 (patch)
tree580a594a66289796f73812d5a5f98c5a0d8d4476 /src/serialize.h
parent97785863e2faa4a6d4e1130e300011985df0858c (diff)
downloadbitcoin-ece88fd26995350dfaa4675b4291605a20203527.tar.xz
Introduce BigEndian wrapper and use it for netaddress ports
Diffstat (limited to 'src/serialize.h')
-rw-r--r--src/serialize.h48
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
*/