serialization: teach serializers variadics
Also add a variadic CDataStream ctor for ease-of-use.
This commit is contained in:
parent
82077ef6e4
commit
b98c14c4e3
|
@ -160,6 +160,7 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
#define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
|
#define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
|
||||||
|
#define READWRITEMANY(...) (::SerReadWriteMany(s, nType, nVersion, ser_action, __VA_ARGS__))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement three methods for serializable objects. These are actually wrappers over
|
* Implement three methods for serializable objects. These are actually wrappers over
|
||||||
|
@ -960,4 +961,52 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Stream>
|
||||||
|
void SerializeMany(Stream& s, int nType, int nVersion)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename Arg>
|
||||||
|
void SerializeMany(Stream& s, int nType, int nVersion, Arg&& arg)
|
||||||
|
{
|
||||||
|
::Serialize(s, std::forward<Arg>(arg), nType, nVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename Arg, typename... Args>
|
||||||
|
void SerializeMany(Stream& s, int nType, int nVersion, Arg&& arg, Args&&... args)
|
||||||
|
{
|
||||||
|
::Serialize(s, std::forward<Arg>(arg), nType, nVersion);
|
||||||
|
::SerializeMany(s, nType, nVersion, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream>
|
||||||
|
inline void UnserializeMany(Stream& s, int nType, int nVersion)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename Arg>
|
||||||
|
inline void UnserializeMany(Stream& s, int nType, int nVersion, Arg& arg)
|
||||||
|
{
|
||||||
|
::Unserialize(s, arg, nType, nVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename Arg, typename... Args>
|
||||||
|
inline void UnserializeMany(Stream& s, int nType, int nVersion, Arg& arg, Args&... args)
|
||||||
|
{
|
||||||
|
::Unserialize(s, arg, nType, nVersion);
|
||||||
|
::UnserializeMany(s, nType, nVersion, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename... Args>
|
||||||
|
inline void SerReadWriteMany(Stream& s, int nType, int nVersion, CSerActionSerialize ser_action, Args&&... args)
|
||||||
|
{
|
||||||
|
::SerializeMany(s, nType, nVersion, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename... Args>
|
||||||
|
inline void SerReadWriteMany(Stream& s, int nType, int nVersion, CSerActionUnserialize ser_action, Args&... args)
|
||||||
|
{
|
||||||
|
::UnserializeMany(s, nType, nVersion, args...);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // BITCOIN_SERIALIZE_H
|
#endif // BITCOIN_SERIALIZE_H
|
||||||
|
|
|
@ -112,6 +112,13 @@ public:
|
||||||
Init(nTypeIn, nVersionIn);
|
Init(nTypeIn, nVersionIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
CDataStream(int nTypeIn, int nVersionIn, Args&&... args)
|
||||||
|
{
|
||||||
|
Init(nTypeIn, nVersionIn);
|
||||||
|
::SerializeMany(*this, nType, nVersion, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
void Init(int nTypeIn, int nVersionIn)
|
void Init(int nTypeIn, int nVersionIn)
|
||||||
{
|
{
|
||||||
nReadPos = 0;
|
nReadPos = 0;
|
||||||
|
|
|
@ -10,11 +10,54 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
|
BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
|
||||||
|
|
||||||
|
class CSerializeMethodsTestSingle
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
int intval;
|
||||||
|
bool boolval;
|
||||||
|
std::string stringval;
|
||||||
|
const char* charstrval;
|
||||||
|
CTransaction txval;
|
||||||
|
public:
|
||||||
|
CSerializeMethodsTestSingle() = default;
|
||||||
|
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){}
|
||||||
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
template <typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||||
|
READWRITE(intval);
|
||||||
|
READWRITE(boolval);
|
||||||
|
READWRITE(stringval);
|
||||||
|
READWRITE(FLATDATA(charstrval));
|
||||||
|
READWRITE(txval);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const CSerializeMethodsTestSingle& rhs)
|
||||||
|
{
|
||||||
|
return intval == rhs.intval && \
|
||||||
|
boolval == rhs.boolval && \
|
||||||
|
stringval == rhs.stringval && \
|
||||||
|
strcmp(charstrval, rhs.charstrval) == 0 && \
|
||||||
|
txval == rhs.txval;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CSerializeMethodsTestMany : public CSerializeMethodsTestSingle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CSerializeMethodsTestSingle::CSerializeMethodsTestSingle;
|
||||||
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
template <typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||||
|
READWRITEMANY(intval, boolval, stringval, FLATDATA(charstrval), txval);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(sizes)
|
BOOST_AUTO_TEST_CASE(sizes)
|
||||||
{
|
{
|
||||||
BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0));
|
BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0));
|
||||||
|
@ -297,4 +340,30 @@ BOOST_AUTO_TEST_CASE(insert_delete)
|
||||||
BOOST_CHECK_EQUAL(ss.size(), 0);
|
BOOST_CHECK_EQUAL(ss.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(class_methods)
|
||||||
|
{
|
||||||
|
int intval(100);
|
||||||
|
bool boolval(true);
|
||||||
|
std::string stringval("testing");
|
||||||
|
const char* charstrval("testing charstr");
|
||||||
|
CMutableTransaction txval;
|
||||||
|
CSerializeMethodsTestSingle methodtest1(intval, boolval, stringval, charstrval, txval);
|
||||||
|
CSerializeMethodsTestMany methodtest2(intval, boolval, stringval, charstrval, txval);
|
||||||
|
CSerializeMethodsTestSingle methodtest3;
|
||||||
|
CSerializeMethodsTestMany methodtest4;
|
||||||
|
CDataStream ss(SER_DISK, PROTOCOL_VERSION);
|
||||||
|
BOOST_CHECK(methodtest1 == methodtest2);
|
||||||
|
ss << methodtest1;
|
||||||
|
ss >> methodtest4;
|
||||||
|
ss << methodtest2;
|
||||||
|
ss >> methodtest3;
|
||||||
|
BOOST_CHECK(methodtest1 == methodtest2);
|
||||||
|
BOOST_CHECK(methodtest2 == methodtest3);
|
||||||
|
BOOST_CHECK(methodtest3 == methodtest4);
|
||||||
|
|
||||||
|
CDataStream ss2(SER_DISK, PROTOCOL_VERSION, intval, boolval, stringval, FLATDATA(charstrval), txval);
|
||||||
|
ss2 >> methodtest3;
|
||||||
|
BOOST_CHECK(methodtest3 == methodtest4);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Reference in New Issue