Browse Source

serialization: teach serializers variadics

Also add a variadic CDataStream ctor for ease-of-use.
pull/4/head
Cory Fields 8 years ago
committed by Jack Grigg
parent
commit
d1c9ef8606
No known key found for this signature in database GPG Key ID: 665DBCD284F7DAFF
  1. 49
      src/serialize.h
  2. 11
      src/streams.h
  3. 70
      src/test/serialize_tests.cpp

49
src/serialize.h

@ -165,6 +165,7 @@ enum
};
#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
@ -1098,4 +1099,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

11
src/streams.h

@ -80,6 +80,13 @@ public:
Init(nTypeIn, nVersionIn);
}
template <typename... Args>
CBaseDataStream(int nTypeIn, int nVersionIn, Args&&... args)
{
Init(nTypeIn, nVersionIn);
::SerializeMany(*this, nType, nVersion, std::forward<Args>(args)...);
}
void Init(int nTypeIn, int nVersionIn)
{
nReadPos = 0;
@ -323,6 +330,10 @@ public:
CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn, int nVersionIn) :
CBaseDataStream(vchIn, nTypeIn, nVersionIn) { }
template <typename... Args>
CDataStream(int nTypeIn, int nVersionIn, Args&&... args) :
CBaseDataStream(nTypeIn, nVersionIn, args...) { }
};

70
src/test/serialize_tests.cpp

@ -36,6 +36,50 @@ void check_ser_rep(T thing, std::vector<unsigned char> expected)
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(boost_optional)
{
check_ser_rep<boost::optional<unsigned char>>(0xff, {0x01, 0xff});
@ -346,4 +390,30 @@ BOOST_AUTO_TEST_CASE(insert_delete)
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()

Loading…
Cancel
Save