Skip to content

Commit 7b6041d

Browse files
committed
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
2 parents 807d2ac + ece88fd commit 7b6041d

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

src/netaddress.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class CSubNet
141141
class CService : public CNetAddr
142142
{
143143
protected:
144-
unsigned short port; // host order
144+
uint16_t port; // host order
145145

146146
public:
147147
CService();
@@ -168,13 +168,7 @@ class CService : public CNetAddr
168168
template <typename Stream, typename Operation>
169169
inline void SerializationOp(Stream& s, Operation ser_action) {
170170
READWRITE(ip);
171-
172-
// TODO: introduce native support for BE serialization in serialize.h
173-
unsigned short portN = htons(port);
174-
READWRITE(Span<unsigned char>((unsigned char*)&portN, 2));
175-
if (ser_action.ForRead()) {
176-
port = ntohs(portN);
177-
}
171+
READWRITE(WrapBigEndian(port));
178172
}
179173
};
180174

src/serialize.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
7979
obj = htole16(obj);
8080
s.write((char*)&obj, 2);
8181
}
82+
template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj)
83+
{
84+
obj = htobe16(obj);
85+
s.write((char*)&obj, 2);
86+
}
8287
template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
8388
{
8489
obj = htole32(obj);
@@ -101,6 +106,12 @@ template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
101106
s.read((char*)&obj, 2);
102107
return le16toh(obj);
103108
}
109+
template<typename Stream> inline uint16_t ser_readdata16be(Stream &s)
110+
{
111+
uint16_t obj;
112+
s.read((char*)&obj, 2);
113+
return be16toh(obj);
114+
}
104115
template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
105116
{
106117
uint32_t obj;
@@ -416,6 +427,40 @@ class CVarInt
416427
}
417428
};
418429

430+
/** Serialization wrapper class for big-endian integers.
431+
*
432+
* Use this wrapper around integer types that are stored in memory in native
433+
* byte order, but serialized in big endian notation. This is only intended
434+
* to implement serializers that are compatible with existing formats, and
435+
* its use is not recommended for new data structures.
436+
*
437+
* Only 16-bit types are supported for now.
438+
*/
439+
template<typename I>
440+
class BigEndian
441+
{
442+
protected:
443+
I& m_val;
444+
public:
445+
explicit BigEndian(I& val) : m_val(val)
446+
{
447+
static_assert(std::is_unsigned<I>::value, "BigEndian type must be unsigned integer");
448+
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");
449+
}
450+
451+
template<typename Stream>
452+
void Serialize(Stream& s) const
453+
{
454+
ser_writedata16be(s, m_val);
455+
}
456+
457+
template<typename Stream>
458+
void Unserialize(Stream& s)
459+
{
460+
m_val = ser_readdata16be(s);
461+
}
462+
};
463+
419464
class CCompactSize
420465
{
421466
protected:
@@ -466,6 +511,9 @@ class LimitedString
466511
template<VarIntMode Mode=VarIntMode::DEFAULT, typename I>
467512
CVarInt<Mode, I> WrapVarInt(I& n) { return CVarInt<Mode, I>{n}; }
468513

514+
template<typename I>
515+
BigEndian<I> WrapBigEndian(I& n) { return BigEndian<I>(n); }
516+
469517
/**
470518
* Forward declarations
471519
*/

0 commit comments

Comments
 (0)