Skip to content

Commit a7c45bc

Browse files
committed
Add native support for serializing char arrays without FLATDATA
Support is added to serialize arrays of type char or unsigned char directly, without any wrappers. All invocations of the FLATDATA wrappers that are obsoleted by this are removed. This includes a patch by Russell Yanofsky to make char casting type safe. The serialization of CSubNet is changed to serialize a bool directly rather than though FLATDATA. This makes the serialization independent of the size of the bool type (and will use 1 byte everywhere).
1 parent 4ba3d4f commit a7c45bc

File tree

8 files changed

+40
-26
lines changed

8 files changed

+40
-26
lines changed

src/addrdb.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ bool SerializeDB(Stream& stream, const Data& data)
2222
// Write and commit header, data
2323
try {
2424
CHashWriter hasher(SER_DISK, CLIENT_VERSION);
25-
stream << FLATDATA(Params().MessageStart()) << data;
26-
hasher << FLATDATA(Params().MessageStart()) << data;
25+
stream << Params().MessageStart() << data;
26+
hasher << Params().MessageStart() << data;
2727
stream << hasher.GetHash();
2828
} catch (const std::exception& e) {
2929
return error("%s: Serialize or I/O error - %s", __func__, e.what());
@@ -66,7 +66,7 @@ bool DeserializeDB(Stream& stream, Data& data, bool fCheckSum = true)
6666
CHashVerifier<Stream> verifier(&stream);
6767
// de-serialize file header (network specific magic number) and ..
6868
unsigned char pchMsgTmp[4];
69-
verifier >> FLATDATA(pchMsgTmp);
69+
verifier >> pchMsgTmp;
7070
// ... verify the network matches ours
7171
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
7272
return error("%s: Invalid network magic number", __func__);

src/netaddress.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class CNetAddr
9393

9494
template <typename Stream, typename Operation>
9595
inline void SerializationOp(Stream& s, Operation ser_action) {
96-
READWRITE(FLATDATA(ip));
96+
READWRITE(ip);
9797
}
9898

9999
friend class CSubNet;
@@ -131,8 +131,8 @@ class CSubNet
131131
template <typename Stream, typename Operation>
132132
inline void SerializationOp(Stream& s, Operation ser_action) {
133133
READWRITE(network);
134-
READWRITE(FLATDATA(netmask));
135-
READWRITE(FLATDATA(valid));
134+
READWRITE(netmask);
135+
READWRITE(valid);
136136
}
137137
};
138138

@@ -166,7 +166,7 @@ class CService : public CNetAddr
166166

167167
template <typename Stream, typename Operation>
168168
inline void SerializationOp(Stream& s, Operation ser_action) {
169-
READWRITE(FLATDATA(ip));
169+
READWRITE(ip);
170170
unsigned short portN = htons(port);
171171
READWRITE(FLATDATA(portN));
172172
if (ser_action.ForRead())

src/protocol.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ class CMessageHeader
4848
template <typename Stream, typename Operation>
4949
inline void SerializationOp(Stream& s, Operation ser_action)
5050
{
51-
READWRITE(FLATDATA(pchMessageStart));
52-
READWRITE(FLATDATA(pchCommand));
51+
READWRITE(pchMessageStart);
52+
READWRITE(pchCommand);
5353
READWRITE(nMessageSize);
54-
READWRITE(FLATDATA(pchChecksum));
54+
READWRITE(pchChecksum);
5555
}
5656

5757
char pchMessageStart[MESSAGE_START_SIZE];

src/serialize.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ inline T* NCONST_PTR(const T* val)
5959
return const_cast<T*>(val);
6060
}
6161

62+
//! Safely convert odd char pointer types to standard ones.
63+
inline char* CharCast(char* c) { return c; }
64+
inline char* CharCast(unsigned char* c) { return (char*)c; }
65+
inline const char* CharCast(const char* c) { return c; }
66+
inline const char* CharCast(const unsigned char* c) { return (const char*)c; }
67+
6268
/*
6369
* Lowest-level serialization and conversion.
6470
* @note Sizes of these types are verified in the tests
@@ -177,6 +183,8 @@ template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_wri
177183
template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
178184
template<typename Stream> inline void Serialize(Stream& s, float a ) { ser_writedata32(s, ser_float_to_uint32(a)); }
179185
template<typename Stream> inline void Serialize(Stream& s, double a ) { ser_writedata64(s, ser_double_to_uint64(a)); }
186+
template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a)[N]) { s.write(a, N); }
187+
template<typename Stream, int N> inline void Serialize(Stream& s, const unsigned char (&a)[N]) { s.write(CharCast(a), N); }
180188

181189
template<typename Stream> inline void Unserialize(Stream& s, char& a ) { a = ser_readdata8(s); } // TODO Get rid of bare char
182190
template<typename Stream> inline void Unserialize(Stream& s, int8_t& a ) { a = ser_readdata8(s); }
@@ -189,6 +197,8 @@ template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a =
189197
template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
190198
template<typename Stream> inline void Unserialize(Stream& s, float& a ) { a = ser_uint32_to_float(ser_readdata32(s)); }
191199
template<typename Stream> inline void Unserialize(Stream& s, double& a ) { a = ser_uint64_to_double(ser_readdata64(s)); }
200+
template<typename Stream, int N> inline void Unserialize(Stream& s, char (&a)[N]) { s.read(a, N); }
201+
template<typename Stream, int N> inline void Unserialize(Stream& s, unsigned char (&a)[N]) { s.read(CharCast(a), N); }
192202

193203
template<typename Stream> inline void Serialize(Stream& s, bool a) { char f=a; ser_writedata8(s, f); }
194204
template<typename Stream> inline void Unserialize(Stream& s, bool& a) { char f=ser_readdata8(s); a=f; }

src/test/net_tests.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class CAddrManCorrupted : public CAddrManSerializationMock
6464
CDataStream AddrmanToStream(CAddrManSerializationMock& _addrman)
6565
{
6666
CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION);
67-
ssPeersIn << FLATDATA(Params().MessageStart());
67+
ssPeersIn << Params().MessageStart();
6868
ssPeersIn << _addrman;
6969
std::string str = ssPeersIn.str();
7070
std::vector<unsigned char> vchData(str.begin(), str.end());
@@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read)
110110
BOOST_CHECK(addrman1.size() == 0);
111111
try {
112112
unsigned char pchMsgTmp[4];
113-
ssPeers1 >> FLATDATA(pchMsgTmp);
113+
ssPeers1 >> pchMsgTmp;
114114
ssPeers1 >> addrman1;
115115
} catch (const std::exception& e) {
116116
exceptionThrown = true;
@@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted)
142142
BOOST_CHECK(addrman1.size() == 0);
143143
try {
144144
unsigned char pchMsgTmp[4];
145-
ssPeers1 >> FLATDATA(pchMsgTmp);
145+
ssPeers1 >> pchMsgTmp;
146146
ssPeers1 >> addrman1;
147147
} catch (const std::exception& e) {
148148
exceptionThrown = true;

src/test/serialize_tests.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,23 @@ class CSerializeMethodsTestSingle
1919
int intval;
2020
bool boolval;
2121
std::string stringval;
22-
const char* charstrval;
22+
char charstrval[16];
2323
CTransactionRef txval;
2424
public:
2525
CSerializeMethodsTestSingle() = default;
26-
CSerializeMethodsTestSingle(int intvalin, bool boolvalin, std::string stringvalin, const char* charstrvalin, CTransaction txvalin) : intval(intvalin), boolval(boolvalin), stringval(std::move(stringvalin)), charstrval(charstrvalin), txval(MakeTransactionRef(txvalin)){}
26+
CSerializeMethodsTestSingle(int intvalin, bool boolvalin, std::string stringvalin, const char* charstrvalin, CTransaction txvalin) : intval(intvalin), boolval(boolvalin), stringval(std::move(stringvalin)), txval(MakeTransactionRef(txvalin))
27+
{
28+
memcpy(charstrval, charstrvalin, sizeof(charstrval));
29+
}
30+
2731
ADD_SERIALIZE_METHODS;
2832

2933
template <typename Stream, typename Operation>
3034
inline void SerializationOp(Stream& s, Operation ser_action) {
3135
READWRITE(intval);
3236
READWRITE(boolval);
3337
READWRITE(stringval);
34-
READWRITE(FLATDATA(charstrval));
38+
READWRITE(charstrval);
3539
READWRITE(txval);
3640
}
3741

@@ -53,7 +57,7 @@ class CSerializeMethodsTestMany : public CSerializeMethodsTestSingle
5357

5458
template <typename Stream, typename Operation>
5559
inline void SerializationOp(Stream& s, Operation ser_action) {
56-
READWRITE(intval, boolval, stringval, FLATDATA(charstrval), txval);
60+
READWRITE(intval, boolval, stringval, charstrval, txval);
5761
}
5862
};
5963

@@ -344,7 +348,7 @@ BOOST_AUTO_TEST_CASE(class_methods)
344348
int intval(100);
345349
bool boolval(true);
346350
std::string stringval("testing");
347-
const char* charstrval("testing charstr");
351+
const char charstrval[16] = "testing charstr";
348352
CMutableTransaction txval;
349353
CSerializeMethodsTestSingle methodtest1(intval, boolval, stringval, charstrval, txval);
350354
CSerializeMethodsTestMany methodtest2(intval, boolval, stringval, charstrval, txval);
@@ -360,7 +364,7 @@ BOOST_AUTO_TEST_CASE(class_methods)
360364
BOOST_CHECK(methodtest2 == methodtest3);
361365
BOOST_CHECK(methodtest3 == methodtest4);
362366

363-
CDataStream ss2(SER_DISK, PROTOCOL_VERSION, intval, boolval, stringval, FLATDATA(charstrval), txval);
367+
CDataStream ss2(SER_DISK, PROTOCOL_VERSION, intval, boolval, stringval, charstrval, txval);
364368
ss2 >> methodtest3;
365369
BOOST_CHECK(methodtest3 == methodtest4);
366370
}

src/test/streams_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,16 @@ BOOST_AUTO_TEST_CASE(streams_vector_writer)
5757
BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
5858
vch.clear();
5959

60-
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, FLATDATA(bytes));
60+
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes);
6161
BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
62-
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, FLATDATA(bytes));
62+
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes);
6363
BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
6464
vch.clear();
6565

6666
vch.resize(4, 8);
67-
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, FLATDATA(bytes), b);
67+
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b);
6868
BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
69-
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, FLATDATA(bytes), b);
69+
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b);
7070
BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
7171
vch.clear();
7272
}

src/validation.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ static bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMes
10771077

10781078
// Write index header
10791079
unsigned int nSize = GetSerializeSize(fileout, block);
1080-
fileout << FLATDATA(messageStart) << nSize;
1080+
fileout << messageStart << nSize;
10811081

10821082
// Write block
10831083
long fileOutPos = ftell(fileout.Get());
@@ -1441,7 +1441,7 @@ bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint
14411441

14421442
// Write index header
14431443
unsigned int nSize = GetSerializeSize(fileout, blockundo);
1444-
fileout << FLATDATA(messageStart) << nSize;
1444+
fileout << messageStart << nSize;
14451445

14461446
// Write undo data
14471447
long fileOutPos = ftell(fileout.Get());
@@ -4283,7 +4283,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
42834283
unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
42844284
blkdat.FindByte(chainparams.MessageStart()[0]);
42854285
nRewind = blkdat.GetPos()+1;
4286-
blkdat >> FLATDATA(buf);
4286+
blkdat >> buf;
42874287
if (memcmp(buf, chainparams.MessageStart(), CMessageHeader::MESSAGE_START_SIZE))
42884288
continue;
42894289
// read size

0 commit comments

Comments
 (0)