mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 15:09:59 +01:00
overhaul serialization code
The implementation of each class' serialization/deserialization is no longer
passed within a macro. The implementation now lies within a template of form:
template <typename T, typename Stream, typename Operation>
inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) {
size_t nSerSize = 0;
/* CODE */
return nSerSize;
}
In cases when codepath should depend on whether or not we are just deserializing
(old fGetSize, fWrite, fRead flags) an additional clause can be used:
bool fRead = boost::is_same<Operation, CSerActionUnserialize>();
The IMPLEMENT_SERIALIZE macro will now be a freestanding clause added within
class' body (similiar to Qt's Q_OBJECT) to implement GetSerializeSize,
Serialize and Unserialize. These are now wrappers around
the "SerializationOp" template.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
class CAutoFile;
|
||||
class CDataStream;
|
||||
@@ -37,6 +38,14 @@ inline T& REF(const T& val)
|
||||
return const_cast<T&>(val);
|
||||
}
|
||||
|
||||
// Used to acquire a const pointer "this" and generate a const
|
||||
// serialization operation from a template
|
||||
template<typename T>
|
||||
inline T MAKE_CONST(T val)
|
||||
{
|
||||
return const_cast<const 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,48 +88,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) (nSerSize += ::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 { \
|
||||
ser_streamplaceholder s; \
|
||||
s.nType = nType; \
|
||||
s.nVersion = nVersion; \
|
||||
return SerializationOp(MAKE_CONST(this), s, CSerActionGetSerializeSize(), nType, nVersion); \
|
||||
} \
|
||||
template<typename Stream> \
|
||||
void Serialize(Stream& s, int nType, int nVersion) const { \
|
||||
SerializationOp(MAKE_CONST(this), s, CSerActionSerialize(), nType, nVersion); \
|
||||
} \
|
||||
template<typename Stream> \
|
||||
void Unserialize(Stream& s, int nType, int nVersion) { \
|
||||
SerializationOp(this, s, CSerActionUnserialize(), nType, nVersion); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user