Avoid creating a temporary vector for size-prefixed elements
This commit is contained in:
parent
4a3e8c5aa6
commit
84547fa6d4
2 changed files with 16 additions and 10 deletions
|
@ -116,26 +116,24 @@ static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02;
|
||||||
// as a 0 length key which indicates that this is the separator. The separator has no value.
|
// as a 0 length key which indicates that this is the separator. The separator has no value.
|
||||||
static constexpr uint8_t PSBT_SEPARATOR = 0x00;
|
static constexpr uint8_t PSBT_SEPARATOR = 0x00;
|
||||||
|
|
||||||
// Takes a stream and multiple arguments and serializes them into a vector and then into the stream
|
// Takes a stream and multiple arguments and serializes them as if first serialized into a vector and then into the stream
|
||||||
// The resulting output into the stream has the total serialized length of all of the objects followed by all objects concatenated with each other.
|
// The resulting output into the stream has the total serialized length of all of the objects followed by all objects concatenated with each other.
|
||||||
template<typename Stream, typename... X>
|
template<typename Stream, typename... X>
|
||||||
void SerializeToVector(Stream& s, const X&... args)
|
void SerializeToVector(Stream& s, const X&... args)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> ret;
|
WriteCompactSize(s, GetSerializeSizeMany(s, args...));
|
||||||
CVectorWriter ss(SER_NETWORK, PROTOCOL_VERSION, ret, 0);
|
SerializeMany(s, args...);
|
||||||
SerializeMany(ss, args...);
|
|
||||||
s << ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes a stream and multiple arguments and unserializes them first as a vector then each object individually in the order provided in the arguments
|
// Takes a stream and multiple arguments and unserializes them first as a vector then each object individually in the order provided in the arguments
|
||||||
template<typename Stream, typename... X>
|
template<typename Stream, typename... X>
|
||||||
void UnserializeFromVector(Stream& s, X&... args)
|
void UnserializeFromVector(Stream& s, X&... args)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> data;
|
size_t expected_size = ReadCompactSize(s);
|
||||||
s >> data;
|
size_t remaining_before = s.size();
|
||||||
CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION);
|
UnserializeMany(s, args...);
|
||||||
UnserializeMany(ss, args...);
|
size_t remaining_after = s.size();
|
||||||
if (!ss.eof()) {
|
if (remaining_after + expected_size != remaining_before) {
|
||||||
throw std::ios_base::failure("Size of value was not the stated size");
|
throw std::ios_base::failure("Size of value was not the stated size");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -991,4 +991,12 @@ size_t GetSerializeSize(const S& s, const T& t)
|
||||||
return (CSizeComputer(s.GetType(), s.GetVersion()) << t).size();
|
return (CSizeComputer(s.GetType(), s.GetVersion()) << t).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename S, typename... T>
|
||||||
|
size_t GetSerializeSizeMany(const S& s, const T&... t)
|
||||||
|
{
|
||||||
|
CSizeComputer sc(s.GetType(), s.GetVersion());
|
||||||
|
SerializeMany(sc, t...);
|
||||||
|
return sc.size();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // BITCOIN_SERIALIZE_H
|
#endif // BITCOIN_SERIALIZE_H
|
||||||
|
|
Loading…
Reference in a new issue