Merge #12916: Introduce BigEndian wrapper and use it for netaddress ports
ece88fd
Introduce BigEndian wrapper and use it for netaddress ports (Pieter Wuille)
Pull request description:
This is another small improvement taken from #10785.
Instead of manually converting from/to BE format in the `CService` serializer, provide a generic way in serialize.h to serialize BE data (only 16 bits for now).
Tree-SHA512: bd67cf7eed465dad08551fb62f659e755e0691e4597a9f59d285d2b79975b50e5710d35a34a185b5ad232e1deda9a4946615f9132b1ed7d96ed8087f73ace66b
This commit is contained in:
commit
7b6041d1a7
2 changed files with 50 additions and 8 deletions
|
@ -141,7 +141,7 @@ class CSubNet
|
||||||
class CService : public CNetAddr
|
class CService : public CNetAddr
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
unsigned short port; // host order
|
uint16_t port; // host order
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CService();
|
CService();
|
||||||
|
@ -168,13 +168,7 @@ class CService : public CNetAddr
|
||||||
template <typename Stream, typename Operation>
|
template <typename Stream, typename Operation>
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||||
READWRITE(ip);
|
READWRITE(ip);
|
||||||
|
READWRITE(WrapBigEndian(port));
|
||||||
// TODO: introduce native support for BE serialization in serialize.h
|
|
||||||
unsigned short portN = htons(port);
|
|
||||||
READWRITE(Span<unsigned char>((unsigned char*)&portN, 2));
|
|
||||||
if (ser_action.ForRead()) {
|
|
||||||
port = ntohs(portN);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,11 @@ template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
|
||||||
obj = htole16(obj);
|
obj = htole16(obj);
|
||||||
s.write((char*)&obj, 2);
|
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)
|
template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
|
||||||
{
|
{
|
||||||
obj = htole32(obj);
|
obj = htole32(obj);
|
||||||
|
@ -101,6 +106,12 @@ template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
|
||||||
s.read((char*)&obj, 2);
|
s.read((char*)&obj, 2);
|
||||||
return le16toh(obj);
|
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)
|
template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
|
||||||
{
|
{
|
||||||
uint32_t obj;
|
uint32_t obj;
|
||||||
|
@ -416,6 +427,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
|
class CCompactSize
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -466,6 +511,9 @@ public:
|
||||||
template<VarIntMode Mode=VarIntMode::DEFAULT, typename I>
|
template<VarIntMode Mode=VarIntMode::DEFAULT, typename I>
|
||||||
CVarInt<Mode, I> WrapVarInt(I& n) { return CVarInt<Mode, I>{n}; }
|
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
|
* Forward declarations
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue