Add serialization for primitive boost::optional<T>.
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/array.hpp>
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
class CScript;
|
class CScript;
|
||||||
|
|
||||||
@@ -508,6 +509,13 @@ extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVe
|
|||||||
template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion);
|
template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion);
|
||||||
template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
|
template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional
|
||||||
|
*/
|
||||||
|
template<typename T> unsigned int GetSerializeSize(const boost::optional<T> &item, int nType, int nVersion);
|
||||||
|
template<typename Stream, typename T> void Serialize(Stream& os, const boost::optional<T>& item, int nType, int nVersion);
|
||||||
|
template<typename Stream, typename T> void Unserialize(Stream& is, boost::optional<T>& item, int nType, int nVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* array
|
* array
|
||||||
*/
|
*/
|
||||||
@@ -707,6 +715,52 @@ void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
unsigned int GetSerializeSize(const boost::optional<T> &item, int nType, int nVersion)
|
||||||
|
{
|
||||||
|
if (item) {
|
||||||
|
return 1 + GetSerializeSize(*item, nType, nVersion);
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename T>
|
||||||
|
void Serialize(Stream& os, const boost::optional<T>& item, int nType, int nVersion)
|
||||||
|
{
|
||||||
|
// If the value is there, put 0x01 and then serialize the value.
|
||||||
|
// If it's not, put 0x00.
|
||||||
|
if (item) {
|
||||||
|
unsigned char discriminant = 0x01;
|
||||||
|
Serialize(os, discriminant, nType, nVersion);
|
||||||
|
Serialize(os, *item, nType, nVersion);
|
||||||
|
} else {
|
||||||
|
unsigned char discriminant = 0x00;
|
||||||
|
Serialize(os, discriminant, nType, nVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename T>
|
||||||
|
void Unserialize(Stream& is, boost::optional<T>& item, int nType, int nVersion)
|
||||||
|
{
|
||||||
|
unsigned char discriminant = 0x00;
|
||||||
|
Unserialize(is, discriminant, nType, nVersion);
|
||||||
|
|
||||||
|
if (discriminant == 0x00) {
|
||||||
|
item = boost::none;
|
||||||
|
} else {
|
||||||
|
T object;
|
||||||
|
Unserialize(is, object, nType, nVersion);
|
||||||
|
item = object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* array
|
* array
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -11,11 +11,38 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void check_ser_rep(T thing, std::vector<unsigned char> expected)
|
||||||
|
{
|
||||||
|
CDataStream ss(SER_DISK, 0);
|
||||||
|
ss << thing;
|
||||||
|
|
||||||
|
BOOST_CHECK(GetSerializeSize(thing, 0, 0) == ss.size());
|
||||||
|
|
||||||
|
std::vector<unsigned char> serialized_representation(ss.begin(), ss.end());
|
||||||
|
|
||||||
|
BOOST_CHECK(serialized_representation == expected);
|
||||||
|
|
||||||
|
T thing_deserialized;
|
||||||
|
ss >> thing_deserialized;
|
||||||
|
|
||||||
|
BOOST_CHECK(thing_deserialized == thing);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
|
BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(boost_optional)
|
||||||
|
{
|
||||||
|
check_ser_rep<boost::optional<unsigned char>>(0xff, {0x01, 0xff});
|
||||||
|
check_ser_rep<boost::optional<unsigned char>>(boost::none, {0x00});
|
||||||
|
check_ser_rep<boost::optional<std::string>>(std::string("Test"), {0x01, 0x04, 'T', 'e', 's', 't'});
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(boost_arrays)
|
BOOST_AUTO_TEST_CASE(boost_arrays)
|
||||||
{
|
{
|
||||||
boost::array<std::string, 2> test_case = {string("zub"), string("baz")};
|
boost::array<std::string, 2> test_case = {string("zub"), string("baz")};
|
||||||
|
|||||||
Reference in New Issue
Block a user