From 3d796f89962842e91e7d88e57c1d2d579f01052e Mon Sep 17 00:00:00 2001 From: Kamil Domanski Date: Wed, 20 Aug 2014 08:42:31 +0200 Subject: 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 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(); 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. --- src/protocol.h | 61 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 23 deletions(-) (limited to 'src/protocol.h') diff --git a/src/protocol.h b/src/protocol.h index d7565584af..851fca9d9e 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -36,12 +36,16 @@ class CMessageHeader bool IsValid() const; IMPLEMENT_SERIALIZE - ( - READWRITE(FLATDATA(pchMessageStart)); - READWRITE(FLATDATA(pchCommand)); - READWRITE(nMessageSize); - READWRITE(nChecksum); - ) + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + READWRITE(FLATDATA(thisPtr->pchMessageStart)); + READWRITE(FLATDATA(thisPtr->pchCommand)); + READWRITE(thisPtr->nMessageSize); + READWRITE(thisPtr->nChecksum); + return nSerSize; + } // TODO: make private (improves encapsulation) public: @@ -84,19 +88,26 @@ class CAddress : public CService void Init(); IMPLEMENT_SERIALIZE - ( - CAddress* pthis = const_cast(this); - CService* pip = (CService*)pthis; - if (fRead) - pthis->Init(); - if (nType & SER_DISK) - READWRITE(nVersion); - if ((nType & SER_DISK) || - (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) - READWRITE(nTime); - READWRITE(nServices); - READWRITE(*pip); - ) + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + bool fRead = boost::is_same(); + + CAddress* pthis = const_cast(thisPtr); + CService* pip = (CService*)pthis; + if (fRead) + pthis->Init(); + if (nType & SER_DISK) + READWRITE(nVersion); + if ((nType & SER_DISK) || + (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) + READWRITE(thisPtr->nTime); + READWRITE(thisPtr->nServices); + READWRITE(*pip); + + return nSerSize; + } // TODO: make private (improves encapsulation) public: @@ -118,10 +129,14 @@ class CInv CInv(const std::string& strType, const uint256& hashIn); IMPLEMENT_SERIALIZE - ( - READWRITE(type); - READWRITE(hash); - ) + + template + inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + size_t nSerSize = 0; + READWRITE(thisPtr->type); + READWRITE(thisPtr->hash); + return nSerSize; + } friend bool operator<(const CInv& a, const CInv& b); -- cgit v1.2.3 From 84881f8c472cc67dc757686eb7dc3b495b13cab8 Mon Sep 17 00:00:00 2001 From: Kamil Domanski Date: Wed, 20 Aug 2014 22:44:38 +0200 Subject: rework overhauled serialization methods to non-static Thanks to Pieter Wuille for most of the work on this commit. I did not fixup the overhaul commit, because a rebase conflicted with "remove fields of ser_streamplaceholder". I prefer not to risk making a mistake while resolving it. --- src/protocol.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src/protocol.h') diff --git a/src/protocol.h b/src/protocol.h index 851fca9d9e..0f5c5559d1 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -35,15 +35,15 @@ class CMessageHeader std::string GetCommand() const; bool IsValid() const; - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; - READWRITE(FLATDATA(thisPtr->pchMessageStart)); - READWRITE(FLATDATA(thisPtr->pchCommand)); - READWRITE(thisPtr->nMessageSize); - READWRITE(thisPtr->nChecksum); + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + READWRITE(nChecksum); return nSerSize; } @@ -87,14 +87,14 @@ class CAddress : public CService void Init(); - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; bool fRead = boost::is_same(); - CAddress* pthis = const_cast(thisPtr); + CAddress* pthis = const_cast(this); CService* pip = (CService*)pthis; if (fRead) pthis->Init(); @@ -102,8 +102,8 @@ class CAddress : public CService READWRITE(nVersion); if ((nType & SER_DISK) || (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) - READWRITE(thisPtr->nTime); - READWRITE(thisPtr->nServices); + READWRITE(nTime); + READWRITE(nServices); READWRITE(*pip); return nSerSize; @@ -128,13 +128,13 @@ class CInv CInv(int typeIn, const uint256& hashIn); CInv(const std::string& strType, const uint256& hashIn); - IMPLEMENT_SERIALIZE + IMPLEMENT_SERIALIZE; - template - inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) { + template + inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { size_t nSerSize = 0; - READWRITE(thisPtr->type); - READWRITE(thisPtr->hash); + READWRITE(type); + READWRITE(hash); return nSerSize; } -- cgit v1.2.3 From 31e9a8384a77947f6777d035992f4734618ed206 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 21 Aug 2014 00:49:32 +0200 Subject: Use CSizeComputer to avoid counting sizes in SerializationOp --- src/protocol.h | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'src/protocol.h') diff --git a/src/protocol.h b/src/protocol.h index 0f5c5559d1..e4b0991774 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -38,13 +38,11 @@ class CMessageHeader IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(FLATDATA(pchMessageStart)); READWRITE(FLATDATA(pchCommand)); READWRITE(nMessageSize); READWRITE(nChecksum); - return nSerSize; } // TODO: make private (improves encapsulation) @@ -90,12 +88,10 @@ class CAddress : public CService IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; - bool fRead = boost::is_same(); + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); CAddress* pthis = const_cast(this); - CService* pip = (CService*)pthis; if (fRead) pthis->Init(); if (nType & SER_DISK) @@ -104,9 +100,7 @@ class CAddress : public CService (nVersion >= CADDR_TIME_VERSION && !(nType & SER_GETHASH))) READWRITE(nTime); READWRITE(nServices); - READWRITE(*pip); - - return nSerSize; + READWRITE(*(CService*)this); } // TODO: make private (improves encapsulation) @@ -131,11 +125,9 @@ class CInv IMPLEMENT_SERIALIZE; template - inline size_t SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - size_t nSerSize = 0; + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(type); READWRITE(hash); - return nSerSize; } friend bool operator<(const CInv& a, const CInv& b); -- cgit v1.2.3