mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 06:58:57 +01:00
serialization: Accept multiple parameters in ParamsStream constructor
Before this change it was possible but awkward to create ParamStream streams with multiple parameter objects. After this change it is straightforward. The change to support multiple parameters is implemented by letting ParamsStream contain substream instances, instead of just references to external substreams. So a side-effect of this change is that ParamStream can now accept rvalue stream arguments and be easier to use in some other cases. A test for rvalues is added in this commit, and some simplifications to non-test code are made in the next commit.
This commit is contained in:
@@ -15,6 +15,18 @@
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
|
||||
|
||||
// For testing move-semantics, declare a version of datastream that can be moved
|
||||
// but is not copyable.
|
||||
class UncopyableStream : public DataStream
|
||||
{
|
||||
public:
|
||||
using DataStream::DataStream;
|
||||
UncopyableStream(const UncopyableStream&) = delete;
|
||||
UncopyableStream& operator=(const UncopyableStream&) = delete;
|
||||
UncopyableStream(UncopyableStream&&) noexcept = default;
|
||||
UncopyableStream& operator=(UncopyableStream&&) noexcept = default;
|
||||
};
|
||||
|
||||
class CSerializeMethodsTestSingle
|
||||
{
|
||||
protected:
|
||||
@@ -344,6 +356,73 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct OtherParam {
|
||||
uint8_t param;
|
||||
SER_PARAMS_OPFUNC
|
||||
};
|
||||
|
||||
//! Checker for value of OtherParam. When being serialized, serializes the
|
||||
//! param to the stream. When being unserialized, verifies the value in the
|
||||
//! stream matches the param.
|
||||
class OtherParamChecker
|
||||
{
|
||||
public:
|
||||
template <typename Stream>
|
||||
void Serialize(Stream& s) const
|
||||
{
|
||||
const uint8_t param = s.template GetParams<OtherParam>().param;
|
||||
s << param;
|
||||
}
|
||||
|
||||
template <typename Stream>
|
||||
void Unserialize(Stream& s) const
|
||||
{
|
||||
const uint8_t param = s.template GetParams<OtherParam>().param;
|
||||
uint8_t value;
|
||||
s >> value;
|
||||
BOOST_CHECK_EQUAL(value, param);
|
||||
}
|
||||
};
|
||||
|
||||
//! Test creating a stream with multiple parameters and making sure
|
||||
//! serialization code requiring different parameters can retrieve them. Also
|
||||
//! test that earlier parameters take precedence if the same parameter type is
|
||||
//! specified twice. (Choice of whether earlier or later values take precedence
|
||||
//! or multiple values of the same type are allowed was arbitrary, and just
|
||||
//! decided based on what would require smallest amount of ugly C++ template
|
||||
//! code. Intent of the test is to just ensure there is no unexpected behavior.)
|
||||
BOOST_AUTO_TEST_CASE(with_params_multi)
|
||||
{
|
||||
const OtherParam other_param_used{.param = 0x10};
|
||||
const OtherParam other_param_ignored{.param = 0x11};
|
||||
const OtherParam other_param_override{.param = 0x12};
|
||||
const OtherParamChecker check;
|
||||
DataStream stream;
|
||||
ParamsStream pstream{stream, RAW, other_param_used, other_param_ignored};
|
||||
|
||||
Base base1{0x20};
|
||||
pstream << base1 << check << other_param_override(check);
|
||||
BOOST_CHECK_EQUAL(stream.str(), "\x20\x10\x12");
|
||||
|
||||
Base base2;
|
||||
pstream >> base2 >> check >> other_param_override(check);
|
||||
BOOST_CHECK_EQUAL(base2.m_base_data, 0x20);
|
||||
}
|
||||
|
||||
//! Test creating a ParamsStream that moves from a stream argument.
|
||||
BOOST_AUTO_TEST_CASE(with_params_move)
|
||||
{
|
||||
UncopyableStream stream{};
|
||||
ParamsStream pstream{std::move(stream), RAW, HEX, RAW};
|
||||
|
||||
Base base1{0x20};
|
||||
pstream << base1;
|
||||
|
||||
Base base2;
|
||||
pstream >> base2;
|
||||
BOOST_CHECK_EQUAL(base2.m_base_data, 0x20);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(with_params_base)
|
||||
{
|
||||
Base b{0x0F};
|
||||
|
||||
Reference in New Issue
Block a user