aboutsummaryrefslogtreecommitdiff
path: root/src/serialize.h
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2014-09-01 21:00:32 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2014-09-01 21:23:01 +0200
commit2e731f24b5a5c894e013a6d752f1cd409303e916 (patch)
tree94ba6f1e3ab9ecb5ac1696b48b1aabc859aa8365 /src/serialize.h
parentf6a81050372810d8eebc15523bde28e91d045314 (diff)
parent31e9a8384a77947f6777d035992f4734618ed206 (diff)
downloadbitcoin-2e731f24b5a5c894e013a6d752f1cd409303e916.tar.xz
Merge pull request #4737
31e9a83 Use CSizeComputer to avoid counting sizes in SerializationOp (Pieter Wuille) 84881f8 rework overhauled serialization methods to non-static (Kamil Domanski) 5d96b4a remove fields of ser_streamplaceholder (Kamil Domanski) 3d796f8 overhaul serialization code (Kamil Domanski)
Diffstat (limited to 'src/serialize.h')
-rw-r--r--src/serialize.h97
1 files changed, 36 insertions, 61 deletions
diff --git a/src/serialize.h b/src/serialize.h
index d486181d78..1440676a16 100644
--- a/src/serialize.h
+++ b/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,48 +87,26 @@ 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))
-
-
+#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); \
+ }
@@ -823,38 +809,27 @@ 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);
-}
+ bool ForRead() const { return false; }
+};
+struct CSerActionUnserialize
+{
+ bool ForRead() const { return true; }
+};
template<typename Stream, typename T>
-inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
+inline void SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
{
::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)
+inline void 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;
-};
-
-
-