mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 06:58:57 +01:00
Merge pull request #4737
31e9a83Use CSizeComputer to avoid counting sizes in SerializationOp (Pieter Wuille)84881f8rework overhauled serialization methods to non-static (Kamil Domanski)5d96b4aremove fields of ser_streamplaceholder (Kamil Domanski)3d796f8overhaul serialization code (Kamil Domanski)
This commit is contained in:
109
src/serialize.h
109
src/serialize.h
@@ -37,6 +37,14 @@ inline T& REF(const T& val)
|
||||
return const_cast<T&>(val);
|
||||
}
|
||||
|
||||
// Used to acquire a non-const pointer "this" to generate bodies
|
||||
// of const serialization operations from a template
|
||||
template<typename T>
|
||||
inline T* NCONST_PTR(const T* val)
|
||||
{
|
||||
return const_cast<T*>(val);
|
||||
}
|
||||
|
||||
/** Get begin pointer of vector (non-const version).
|
||||
* @note These functions avoid the undefined case of indexing into an empty
|
||||
* vector, as well as that of indexing after the end of the vector.
|
||||
@@ -79,49 +87,27 @@ enum
|
||||
SER_GETHASH = (1 << 2),
|
||||
};
|
||||
|
||||
#define IMPLEMENT_SERIALIZE(statements) \
|
||||
unsigned int GetSerializeSize(int nType, int nVersion) const \
|
||||
{ \
|
||||
CSerActionGetSerializeSize ser_action; \
|
||||
const bool fGetSize = true; \
|
||||
const bool fWrite = false; \
|
||||
const bool fRead = false; \
|
||||
unsigned int nSerSize = 0; \
|
||||
ser_streamplaceholder s; \
|
||||
assert(fGetSize||fWrite||fRead); /* suppress warning */ \
|
||||
s.nType = nType; \
|
||||
s.nVersion = nVersion; \
|
||||
{statements} \
|
||||
return nSerSize; \
|
||||
} \
|
||||
template<typename Stream> \
|
||||
void Serialize(Stream& s, int nType, int nVersion) const \
|
||||
{ \
|
||||
CSerActionSerialize ser_action; \
|
||||
const bool fGetSize = false; \
|
||||
const bool fWrite = true; \
|
||||
const bool fRead = false; \
|
||||
unsigned int nSerSize = 0; \
|
||||
assert(fGetSize||fWrite||fRead); /* suppress warning */ \
|
||||
{statements} \
|
||||
} \
|
||||
template<typename Stream> \
|
||||
void Unserialize(Stream& s, int nType, int nVersion) \
|
||||
{ \
|
||||
CSerActionUnserialize ser_action; \
|
||||
const bool fGetSize = false; \
|
||||
const bool fWrite = false; \
|
||||
const bool fRead = true; \
|
||||
unsigned int nSerSize = 0; \
|
||||
assert(fGetSize||fWrite||fRead); /* suppress warning */ \
|
||||
{statements} \
|
||||
#define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))
|
||||
|
||||
/* Implement three methods for serializable objects. These are actually wrappers over
|
||||
* "SerializationOp" template, which implements the body of each class' serialization
|
||||
* code. Adding "IMPLEMENT_SERIALIZE" in the body of the class causes these wrappers to be
|
||||
* added as members. */
|
||||
#define IMPLEMENT_SERIALIZE \
|
||||
size_t GetSerializeSize(int nType, int nVersion) const { \
|
||||
CSizeComputer s(nType, nVersion); \
|
||||
NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
|
||||
return s.size(); \
|
||||
} \
|
||||
template<typename Stream> \
|
||||
void Serialize(Stream& s, int nType, int nVersion) const { \
|
||||
NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
|
||||
} \
|
||||
template<typename Stream> \
|
||||
void Unserialize(Stream& s, int nType, int nVersion) { \
|
||||
SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
|
||||
}
|
||||
|
||||
#define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
@@ -823,37 +809,26 @@ void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
|
||||
//
|
||||
// Support for IMPLEMENT_SERIALIZE and READWRITE macro
|
||||
//
|
||||
class CSerActionGetSerializeSize { };
|
||||
class CSerActionSerialize { };
|
||||
class CSerActionUnserialize { };
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action)
|
||||
struct CSerActionSerialize
|
||||
{
|
||||
return ::GetSerializeSize(obj, nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
|
||||
bool ForRead() const { return false; }
|
||||
};
|
||||
struct CSerActionUnserialize
|
||||
{
|
||||
::Serialize(s, obj, nType, nVersion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
|
||||
{
|
||||
::Unserialize(s, obj, nType, nVersion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ser_streamplaceholder
|
||||
{
|
||||
int nType;
|
||||
int nVersion;
|
||||
bool ForRead() const { return true; }
|
||||
};
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
|
||||
{
|
||||
::Serialize(s, obj, nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
|
||||
{
|
||||
::Unserialize(s, obj, nType, nVersion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user