Merge f138422d37 into merged_master (Bitcoin PR bitcoin/bitcoin#28203)

This commit is contained in:
Byron Hambly 2025-07-03 15:36:18 +02:00
commit f6e42fef43

View file

@ -655,23 +655,14 @@ template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_st
* prevector
* prevectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
*/
template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&);
template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&);
template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v);
template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&);
template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&);
template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v);
/**
* vector
* vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.
*/
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&);
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const bool&);
template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&);
template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v);
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&);
template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&);
template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v);
/**
@ -764,122 +755,82 @@ void Unserialize(Stream& is, std::basic_string<C>& str)
/**
* prevector
*/
template<typename Stream, unsigned int N, typename T>
void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
template <typename Stream, unsigned int N, typename T>
void Serialize(Stream& os, const prevector<N, T>& v)
{
WriteCompactSize(os, v.size());
if (!v.empty())
os.write(MakeByteSpan(v));
}
template<typename Stream, unsigned int N, typename T, typename V>
void Serialize_impl(Stream& os, const prevector<N, T>& v, const V&)
{
Serialize(os, Using<VectorFormatter<DefaultFormatter>>(v));
}
template<typename Stream, unsigned int N, typename T>
inline void Serialize(Stream& os, const prevector<N, T>& v)
{
Serialize_impl(os, v, T());
}
template<typename Stream, unsigned int N, typename T>
void Unserialize_impl(Stream& is, prevector<N, T>& v, const unsigned char&)
{
// Limit size per read so bogus size value won't cause out of memory
v.clear();
unsigned int nSize = ReadCompactSize(is);
unsigned int i = 0;
while (i < nSize)
{
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
v.resize_uninitialized(i + blk);
is.read(AsWritableBytes(Span{&v[i], blk}));
i += blk;
if constexpr (std::is_same_v<T, unsigned char>) {
WriteCompactSize(os, v.size());
if (!v.empty())
os.write(MakeByteSpan(v));
} else {
Serialize(os, Using<VectorFormatter<DefaultFormatter>>(v));
}
}
template<typename Stream, unsigned int N, typename T, typename V>
void Unserialize_impl(Stream& is, prevector<N, T>& v, const V&)
{
Unserialize(is, Using<VectorFormatter<DefaultFormatter>>(v));
}
template<typename Stream, unsigned int N, typename T>
inline void Unserialize(Stream& is, prevector<N, T>& v)
template <typename Stream, unsigned int N, typename T>
void Unserialize(Stream& is, prevector<N, T>& v)
{
Unserialize_impl(is, v, T());
if constexpr (std::is_same_v<T, unsigned char>) {
// Limit size per read so bogus size value won't cause out of memory
v.clear();
unsigned int nSize = ReadCompactSize(is);
unsigned int i = 0;
while (i < nSize) {
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
v.resize_uninitialized(i + blk);
is.read(AsWritableBytes(Span{&v[i], blk}));
i += blk;
}
} else {
Unserialize(is, Using<VectorFormatter<DefaultFormatter>>(v));
}
}
/**
* vector
*/
template<typename Stream, typename T, typename A>
void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&)
template <typename Stream, typename T, typename A>
void Serialize(Stream& os, const std::vector<T, A>& v)
{
WriteCompactSize(os, v.size());
if (!v.empty())
os.write(MakeByteSpan(v));
}
template<typename Stream, typename T, typename A>
void Serialize_impl(Stream& os, const std::vector<T, A>& v, const bool&)
{
// A special case for std::vector<bool>, as dereferencing
// std::vector<bool>::const_iterator does not result in a const bool&
// due to std::vector's special casing for bool arguments.
WriteCompactSize(os, v.size());
for (bool elem : v) {
::Serialize(os, elem);
if constexpr (std::is_same_v<T, unsigned char>) {
WriteCompactSize(os, v.size());
if (!v.empty())
os.write(MakeByteSpan(v));
} else if constexpr (std::is_same_v<T, bool>) {
// A special case for std::vector<bool>, as dereferencing
// std::vector<bool>::const_iterator does not result in a const bool&
// due to std::vector's special casing for bool arguments.
WriteCompactSize(os, v.size());
for (bool elem : v) {
::Serialize(os, elem);
}
} else {
Serialize(os, Using<VectorFormatter<DefaultFormatter>>(v));
}
}
template<typename Stream, typename T, typename A, typename V>
void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&)
{
Serialize(os, Using<VectorFormatter<DefaultFormatter>>(v));
}
template<typename Stream, typename T, typename A>
inline void Serialize(Stream& os, const std::vector<T, A>& v)
template <typename Stream, typename T, typename A>
void Unserialize(Stream& is, std::vector<T, A>& v)
{
Serialize_impl(os, v, T());
}
template<typename Stream, typename T, typename A>
void Unserialize_impl(Stream& is, std::vector<T, A>& v, const unsigned char&)
{
// Limit size per read so bogus size value won't cause out of memory
v.clear();
unsigned int nSize = ReadCompactSize(is);
unsigned int i = 0;
while (i < nSize)
{
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
v.resize(i + blk);
is.read(AsWritableBytes(Span{&v[i], blk}));
i += blk;
if constexpr (std::is_same_v<T, unsigned char>) {
// Limit size per read so bogus size value won't cause out of memory
v.clear();
unsigned int nSize = ReadCompactSize(is);
unsigned int i = 0;
while (i < nSize) {
unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
v.resize(i + blk);
is.read(AsWritableBytes(Span{&v[i], blk}));
i += blk;
}
} else {
Unserialize(is, Using<VectorFormatter<DefaultFormatter>>(v));
}
}
template<typename Stream, typename T, typename A, typename V>
void Unserialize_impl(Stream& is, std::vector<T, A>& v, const V&)
{
Unserialize(is, Using<VectorFormatter<DefaultFormatter>>(v));
}
template<typename Stream, typename T, typename A>
inline void Unserialize(Stream& is, std::vector<T, A>& v)
{
Unserialize_impl(is, v, T());
}
/**
* pair
@ -1055,28 +1006,16 @@ public:
int GetType() const { return 0; }
};
template<typename Stream>
void SerializeMany(Stream& s)
template <typename Stream, typename... Args>
void SerializeMany(Stream& s, const Args&... args)
{
(::Serialize(s, args), ...);
}
template<typename Stream, typename Arg, typename... Args>
void SerializeMany(Stream& s, const Arg& arg, const Args&... args)
template <typename Stream, typename... Args>
inline void UnserializeMany(Stream& s, Args&&... args)
{
::Serialize(s, arg);
::SerializeMany(s, args...);
}
template<typename Stream>
inline void UnserializeMany(Stream& s)
{
}
template<typename Stream, typename Arg, typename... Args>
inline void UnserializeMany(Stream& s, Arg&& arg, Args&&... args)
{
::Unserialize(s, arg);
::UnserializeMany(s, args...);
(::Unserialize(s, args), ...);
}
template<typename Stream, typename... Args>