Skip to content

Commit b98c14c

Browse files
theunisipa
authored andcommitted
serialization: teach serializers variadics
Also add a variadic CDataStream ctor for ease-of-use.
1 parent 82077ef commit b98c14c

File tree

3 files changed

+126
-1
lines changed

3 files changed

+126
-1
lines changed

src/serialize.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ enum
160160
};
161161

162162
#define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
163+
#define READWRITEMANY(...) (::SerReadWriteMany(s, nType, nVersion, ser_action, __VA_ARGS__))
163164

164165
/**
165166
* Implement three methods for serializable objects. These are actually wrappers over
@@ -960,4 +961,52 @@ class CSizeComputer
960961
}
961962
};
962963

964+
template<typename Stream>
965+
void SerializeMany(Stream& s, int nType, int nVersion)
966+
{
967+
}
968+
969+
template<typename Stream, typename Arg>
970+
void SerializeMany(Stream& s, int nType, int nVersion, Arg&& arg)
971+
{
972+
::Serialize(s, std::forward<Arg>(arg), nType, nVersion);
973+
}
974+
975+
template<typename Stream, typename Arg, typename... Args>
976+
void SerializeMany(Stream& s, int nType, int nVersion, Arg&& arg, Args&&... args)
977+
{
978+
::Serialize(s, std::forward<Arg>(arg), nType, nVersion);
979+
::SerializeMany(s, nType, nVersion, std::forward<Args>(args)...);
980+
}
981+
982+
template<typename Stream>
983+
inline void UnserializeMany(Stream& s, int nType, int nVersion)
984+
{
985+
}
986+
987+
template<typename Stream, typename Arg>
988+
inline void UnserializeMany(Stream& s, int nType, int nVersion, Arg& arg)
989+
{
990+
::Unserialize(s, arg, nType, nVersion);
991+
}
992+
993+
template<typename Stream, typename Arg, typename... Args>
994+
inline void UnserializeMany(Stream& s, int nType, int nVersion, Arg& arg, Args&... args)
995+
{
996+
::Unserialize(s, arg, nType, nVersion);
997+
::UnserializeMany(s, nType, nVersion, args...);
998+
}
999+
1000+
template<typename Stream, typename... Args>
1001+
inline void SerReadWriteMany(Stream& s, int nType, int nVersion, CSerActionSerialize ser_action, Args&&... args)
1002+
{
1003+
::SerializeMany(s, nType, nVersion, std::forward<Args>(args)...);
1004+
}
1005+
1006+
template<typename Stream, typename... Args>
1007+
inline void SerReadWriteMany(Stream& s, int nType, int nVersion, CSerActionUnserialize ser_action, Args&... args)
1008+
{
1009+
::UnserializeMany(s, nType, nVersion, args...);
1010+
}
1011+
9631012
#endif // BITCOIN_SERIALIZE_H

src/streams.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ class CDataStream
112112
Init(nTypeIn, nVersionIn);
113113
}
114114

115+
template <typename... Args>
116+
CDataStream(int nTypeIn, int nVersionIn, Args&&... args)
117+
{
118+
Init(nTypeIn, nVersionIn);
119+
::SerializeMany(*this, nType, nVersion, std::forward<Args>(args)...);
120+
}
121+
115122
void Init(int nTypeIn, int nVersionIn)
116123
{
117124
nReadPos = 0;

src/test/serialize_tests.cpp

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,54 @@
1010
#include <stdint.h>
1111

1212
#include <boost/test/unit_test.hpp>
13-
1413
using namespace std;
1514

1615
BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
1716

17+
class CSerializeMethodsTestSingle
18+
{
19+
protected:
20+
int intval;
21+
bool boolval;
22+
std::string stringval;
23+
const char* charstrval;
24+
CTransaction txval;
25+
public:
26+
CSerializeMethodsTestSingle() = default;
27+
CSerializeMethodsTestSingle(int intvalin, bool boolvalin, std::string stringvalin, const char* charstrvalin, CTransaction txvalin) : intval(intvalin), boolval(boolvalin), stringval(std::move(stringvalin)), charstrval(charstrvalin), txval(txvalin){}
28+
ADD_SERIALIZE_METHODS;
29+
30+
template <typename Stream, typename Operation>
31+
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
32+
READWRITE(intval);
33+
READWRITE(boolval);
34+
READWRITE(stringval);
35+
READWRITE(FLATDATA(charstrval));
36+
READWRITE(txval);
37+
}
38+
39+
bool operator==(const CSerializeMethodsTestSingle& rhs)
40+
{
41+
return intval == rhs.intval && \
42+
boolval == rhs.boolval && \
43+
stringval == rhs.stringval && \
44+
strcmp(charstrval, rhs.charstrval) == 0 && \
45+
txval == rhs.txval;
46+
}
47+
};
48+
49+
class CSerializeMethodsTestMany : public CSerializeMethodsTestSingle
50+
{
51+
public:
52+
using CSerializeMethodsTestSingle::CSerializeMethodsTestSingle;
53+
ADD_SERIALIZE_METHODS;
54+
55+
template <typename Stream, typename Operation>
56+
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
57+
READWRITEMANY(intval, boolval, stringval, FLATDATA(charstrval), txval);
58+
}
59+
};
60+
1861
BOOST_AUTO_TEST_CASE(sizes)
1962
{
2063
BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0));
@@ -297,4 +340,30 @@ BOOST_AUTO_TEST_CASE(insert_delete)
297340
BOOST_CHECK_EQUAL(ss.size(), 0);
298341
}
299342

343+
BOOST_AUTO_TEST_CASE(class_methods)
344+
{
345+
int intval(100);
346+
bool boolval(true);
347+
std::string stringval("testing");
348+
const char* charstrval("testing charstr");
349+
CMutableTransaction txval;
350+
CSerializeMethodsTestSingle methodtest1(intval, boolval, stringval, charstrval, txval);
351+
CSerializeMethodsTestMany methodtest2(intval, boolval, stringval, charstrval, txval);
352+
CSerializeMethodsTestSingle methodtest3;
353+
CSerializeMethodsTestMany methodtest4;
354+
CDataStream ss(SER_DISK, PROTOCOL_VERSION);
355+
BOOST_CHECK(methodtest1 == methodtest2);
356+
ss << methodtest1;
357+
ss >> methodtest4;
358+
ss << methodtest2;
359+
ss >> methodtest3;
360+
BOOST_CHECK(methodtest1 == methodtest2);
361+
BOOST_CHECK(methodtest2 == methodtest3);
362+
BOOST_CHECK(methodtest3 == methodtest4);
363+
364+
CDataStream ss2(SER_DISK, PROTOCOL_VERSION, intval, boolval, stringval, FLATDATA(charstrval), txval);
365+
ss2 >> methodtest3;
366+
BOOST_CHECK(methodtest3 == methodtest4);
367+
}
368+
300369
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)