aboutsummaryrefslogtreecommitdiff
path: root/src/serialize.h
diff options
context:
space:
mode:
authorKamil Domanski <kdomanski@kdemail.net>2014-08-20 08:42:31 +0200
committerKamil Domanski <kdomanski@kdemail.net>2014-08-31 02:14:20 +0200
commit3d796f89962842e91e7d88e57c1d2d579f01052e (patch)
treed4be736c23fbc4d453a1e4e281eafb4f51cdffd8 /src/serialize.h
parent9f3d47677973cb894fdbb437b9b322e2062a1bf1 (diff)
downloadbitcoin-3d796f89962842e91e7d88e57c1d2d579f01052e.tar.xz
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.
Diffstat (limited to 'src/serialize.h')
-rw-r--r--src/serialize.h68
1 files changed, 28 insertions, 40 deletions
diff --git a/src/serialize.h b/src/serialize.h
index 17cb724bee..7e0ecc2edf 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -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); \
+ }