diff --git a/src/addrdb.cpp b/src/addrdb.cpp --- a/src/addrdb.cpp +++ b/src/addrdb.cpp @@ -23,8 +23,8 @@ // Write and commit header, data try { CHashWriter hasher(SER_DISK, CLIENT_VERSION); - stream << FLATDATA(chainParams.DiskMagic()) << data; - hasher << FLATDATA(chainParams.DiskMagic()) << data; + stream << chainParams.DiskMagic() << data; + hasher << chainParams.DiskMagic() << data; stream << hasher.GetHash(); } catch (const std::exception &e) { return error("%s: Serialize or I/O error - %s", __func__, e.what()); @@ -73,7 +73,7 @@ CHashVerifier verifier(&stream); // de-serialize file header (network specific magic number) and .. uint8_t pchMsgTmp[4]; - verifier >> FLATDATA(pchMsgTmp); + verifier >> pchMsgTmp; // ... verify the network matches ours if (memcmp(pchMsgTmp, std::begin(chainParams.DiskMagic()), sizeof(pchMsgTmp))) { diff --git a/src/netaddress.h b/src/netaddress.h --- a/src/netaddress.h +++ b/src/netaddress.h @@ -114,7 +114,7 @@ template inline void SerializationOp(Stream &s, Operation ser_action) { - READWRITE(FLATDATA(ip)); + READWRITE(ip); } friend class CSubNet; @@ -153,8 +153,8 @@ template inline void SerializationOp(Stream &s, Operation ser_action) { READWRITE(network); - READWRITE(FLATDATA(netmask)); - READWRITE(FLATDATA(valid)); + READWRITE(netmask); + READWRITE(valid); } }; @@ -189,7 +189,7 @@ template inline void SerializationOp(Stream &s, Operation ser_action) { - READWRITE(FLATDATA(ip)); + READWRITE(ip); unsigned short portN = htons(port); READWRITE(FLATDATA(portN)); if (ser_action.ForRead()) { diff --git a/src/protocol.h b/src/protocol.h --- a/src/protocol.h +++ b/src/protocol.h @@ -61,10 +61,10 @@ template inline void SerializationOp(Stream &s, Operation ser_action) { - READWRITE(FLATDATA(pchMessageStart)); - READWRITE(FLATDATA(pchCommand)); + READWRITE(pchMessageStart); + READWRITE(pchCommand); READWRITE(nMessageSize); - READWRITE(FLATDATA(pchChecksum)); + READWRITE(pchChecksum); } MessageMagic pchMessageStart; diff --git a/src/serialize.h b/src/serialize.h --- a/src/serialize.h +++ b/src/serialize.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -53,6 +54,20 @@ return const_cast(val); } +//! Safely convert odd char pointer types to standard ones. +inline char *CharCast(char *c) { + return c; +} +inline char *CharCast(uint8_t *c) { + return (char *)c; +} +inline const char *CharCast(const char *c) { + return c; +} +inline const char *CharCast(const uint8_t *c) { + return (const char *)c; +} + /** * Lowest-level serialization and conversion. * @note Sizes of these types are verified in the tests @@ -215,11 +230,35 @@ template inline void Serialize(Stream &s, double a) { ser_writedata64(s, ser_double_to_uint64(a)); } +template +inline void Serialize(Stream &s, const int8_t (&a)[N]) { + s.write(a, N); +} +template +inline void Serialize(Stream &s, const uint8_t (&a)[N]) { + s.write(CharCast(a), N); +} +template +inline void Serialize(Stream &s, const std::array &a) { + s.write(a.data(), N); +} +template +inline void Serialize(Stream &s, const std::array &a) { + s.write(CharCast(a.data()), N); +} #ifndef CHAR_EQUALS_INT8 // TODO Get rid of bare char template inline void Unserialize(Stream &s, char &a) { a = ser_readdata8(s); } +template +inline void Serialize(Stream &s, const char (&a)[N]) { + s.write(a, N); +} +template +inline void Serialize(Stream &s, const std::array &a) { + s.write(a.data(), N); +} #endif template inline void Unserialize(Stream &s, int8_t &a) { a = ser_readdata8(s); @@ -251,6 +290,32 @@ template inline void Unserialize(Stream &s, double &a) { a = ser_uint64_to_double(ser_readdata64(s)); } +template +inline void Unserialize(Stream &s, int8_t (&a)[N]) { + s.read(a, N); +} +template +inline void Unserialize(Stream &s, uint8_t (&a)[N]) { + s.read(CharCast(a), N); +} +template +inline void Unserialize(Stream &s, std::array &a) { + s.read(a.data(), N); +} +template +inline void Unserialize(Stream &s, std::array &a) { + s.read(CharCast(a.data()), N); +} +#ifndef CHAR_EQUALS_INT8 +template +inline void Unserialize(Stream &s, char (&a)[N]) { + s.read(CharCast(a), N); +} +template +inline void Unserialize(Stream &s, std::array &a) { + s.read(CharCast(a.data()), N); +} +#endif template inline void Serialize(Stream &s, bool a) { char f = a; diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -74,7 +74,7 @@ static CDataStream AddrmanToStream(CAddrManSerializationMock &_addrman) { CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION); - ssPeersIn << FLATDATA(Params().DiskMagic()); + ssPeersIn << Params().DiskMagic(); ssPeersIn << _addrman; std::string str = ssPeersIn.str(); std::vector vchData(str.begin(), str.end()); @@ -118,7 +118,7 @@ BOOST_CHECK(addrman1.size() == 0); try { uint8_t pchMsgTmp[4]; - ssPeers1 >> FLATDATA(pchMsgTmp); + ssPeers1 >> pchMsgTmp; ssPeers1 >> addrman1; } catch (const std::exception &e) { exceptionThrown = true; @@ -149,7 +149,7 @@ BOOST_CHECK(addrman1.size() == 0); try { uint8_t pchMsgTmp[4]; - ssPeers1 >> FLATDATA(pchMsgTmp); + ssPeers1 >> pchMsgTmp; ssPeers1 >> addrman1; } catch (const std::exception &e) { exceptionThrown = true; diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -22,7 +22,7 @@ int intval; bool boolval; std::string stringval; - const char *charstrval; + char charstrval[16]; CTransactionRef txval; public: @@ -32,8 +32,9 @@ const char *charstrvalin, const CTransactionRef &txvalin) : intval(intvalin), boolval(boolvalin), - stringval(std::move(stringvalin)), charstrval(charstrvalin), - txval(txvalin) {} + stringval(std::move(stringvalin)), txval(txvalin) { + memcpy(charstrval, charstrvalin, sizeof(charstrval)); + } ADD_SERIALIZE_METHODS; @@ -42,7 +43,7 @@ READWRITE(intval); READWRITE(boolval); READWRITE(stringval); - READWRITE(FLATDATA(charstrval)); + READWRITE(charstrval); READWRITE(txval); } @@ -60,7 +61,7 @@ template inline void SerializationOp(Stream &s, Operation ser_action) { - READWRITE(intval, boolval, stringval, FLATDATA(charstrval), txval); + READWRITE(intval, boolval, stringval, charstrval, txval); } }; @@ -410,7 +411,7 @@ int intval(100); bool boolval(true); std::string stringval("testing"); - const char *charstrval("testing charstr"); + const char charstrval[16] = "testing charstr"; CMutableTransaction txval; CTransactionRef tx_ref{MakeTransactionRef(txval)}; CSerializeMethodsTestSingle methodtest1(intval, boolval, stringval, @@ -430,7 +431,7 @@ BOOST_CHECK(methodtest3 == methodtest4); CDataStream ss2(SER_DISK, PROTOCOL_VERSION, intval, boolval, stringval, - FLATDATA(charstrval), txval); + charstrval, txval); ss2 >> methodtest3; BOOST_CHECK(methodtest3 == methodtest4); } diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -58,18 +58,16 @@ BOOST_CHECK((vch == std::vector{{0, 0, 0, 0, 1, 2}})); vch.clear(); - CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, FLATDATA(bytes)); + CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes); BOOST_CHECK((vch == std::vector{{3, 4, 5, 6}})); - CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, FLATDATA(bytes)); + CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes); BOOST_CHECK((vch == std::vector{{3, 4, 5, 6}})); vch.clear(); vch.resize(4, 8); - CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, FLATDATA(bytes), - b); + CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b); BOOST_CHECK((vch == std::vector{{8, 8, 1, 3, 4, 5, 6, 2}})); - CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, FLATDATA(bytes), - b); + CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b); BOOST_CHECK((vch == std::vector{{8, 8, 1, 3, 4, 5, 6, 2}})); vch.clear(); } diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -945,7 +945,7 @@ // Write index header unsigned int nSize = GetSerializeSize(fileout, block); - fileout << FLATDATA(messageStart) << nSize; + fileout << messageStart << nSize; // Write block long fileOutPos = ftell(fileout.Get()); @@ -1357,7 +1357,7 @@ // Write index header unsigned int nSize = GetSerializeSize(fileout, blockundo); - fileout << FLATDATA(messageStart) << nSize; + fileout << messageStart << nSize; // Write undo data long fileOutPos = ftell(fileout.Get()); @@ -5117,8 +5117,8 @@ uint8_t buf[CMessageHeader::MESSAGE_START_SIZE]; blkdat.FindByte(chainparams.DiskMagic()[0]); nRewind = blkdat.GetPos() + 1; - blkdat >> FLATDATA(buf); - if (memcmp(buf, std::begin(chainparams.DiskMagic()), + blkdat >> buf; + if (memcmp(buf, chainparams.DiskMagic().data(), CMessageHeader::MESSAGE_START_SIZE)) { continue; }