diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2014-09-01 21:00:32 +0200 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2014-09-01 21:23:01 +0200 |
commit | 2e731f24b5a5c894e013a6d752f1cd409303e916 (patch) | |
tree | 94ba6f1e3ab9ecb5ac1696b48b1aabc859aa8365 | |
parent | f6a81050372810d8eebc15523bde28e91d045314 (diff) | |
parent | 31e9a8384a77947f6777d035992f4734618ed206 (diff) |
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)
-rw-r--r-- | src/addrman.h | 10 | ||||
-rw-r--r-- | src/alert.h | 16 | ||||
-rw-r--r-- | src/bloom.h | 8 | ||||
-rw-r--r-- | src/core.h | 87 | ||||
-rw-r--r-- | src/crypter.h | 9 | ||||
-rw-r--r-- | src/main.h | 53 | ||||
-rw-r--r-- | src/netbase.h | 30 | ||||
-rw-r--r-- | src/protocol.h | 55 | ||||
-rw-r--r-- | src/qt/recentrequeststablemodel.h | 12 | ||||
-rw-r--r-- | src/qt/walletmodel.h | 10 | ||||
-rw-r--r-- | src/serialize.h | 97 | ||||
-rw-r--r-- | src/wallet.h | 69 | ||||
-rw-r--r-- | src/walletdb.h | 8 |
13 files changed, 271 insertions, 193 deletions
diff --git a/src/addrman.h b/src/addrman.h index 8f6ab60662..0790802b5c 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -46,13 +46,15 @@ private: public: - IMPLEMENT_SERIALIZE( - CAddress* pthis = (CAddress*)(this); - READWRITE(*pthis); + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(*(CAddress*)this); READWRITE(source); READWRITE(nLastSuccess); READWRITE(nAttempts); - ) + } void Init() { diff --git a/src/alert.h b/src/alert.h index d8254ba2cb..4a8736d60b 100644 --- a/src/alert.h +++ b/src/alert.h @@ -46,8 +46,10 @@ public: std::string strStatusBar; std::string strReserved; - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(this->nVersion); nVersion = this->nVersion; READWRITE(nRelayUntil); @@ -63,7 +65,7 @@ public: READWRITE(LIMITED_STRING(strComment, 65536)); READWRITE(LIMITED_STRING(strStatusBar, 256)); READWRITE(LIMITED_STRING(strReserved, 256)); - ) + } void SetNull(); @@ -82,11 +84,13 @@ public: SetNull(); } - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(vchMsg); READWRITE(vchSig); - ) + } void SetNull(); bool IsNull() const; diff --git a/src/bloom.h b/src/bloom.h index bedd8fbcd8..4a710928cc 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -62,13 +62,15 @@ public: CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak, unsigned char nFlagsIn); CBloomFilter() : isFull(true), isEmpty(false), nHashFuncs(0), nTweak(0), nFlags(0) {} - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(vData); READWRITE(nHashFuncs); READWRITE(nTweak); READWRITE(nFlags); - ) + } void insert(const std::vector<unsigned char>& vKey); void insert(const COutPoint& outpoint); diff --git a/src/core.h b/src/core.h index a3ec2346e2..34c00c4142 100644 --- a/src/core.h +++ b/src/core.h @@ -30,7 +30,14 @@ public: COutPoint() { SetNull(); } COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; } - IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(FLATDATA(*this)); + } + void SetNull() { hash = 0; n = (uint32_t) -1; } bool IsNull() const { return (hash == 0 && n == (uint32_t) -1); } @@ -84,12 +91,14 @@ public: explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max()); CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<uint32_t>::max()); - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(prevout); READWRITE(scriptSig); READWRITE(nSequence); - ) + } bool IsFinal() const { @@ -136,7 +145,12 @@ public: friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; } std::string ToString() const; - IMPLEMENT_SERIALIZE( READWRITE(nSatoshisPerK); ) + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(nSatoshisPerK); + } }; @@ -156,11 +170,13 @@ public: CTxOut(int64_t nValueIn, CScript scriptPubKeyIn); - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(nValue); READWRITE(scriptPubKey); - ) + } void SetNull() { @@ -237,7 +253,12 @@ public: CTransaction& operator=(const CTransaction& tx); - IMPLEMENT_SERIALIZE( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); + READWRITE(*const_cast<int32_t*>(&this->nVersion)); nVersion = this->nVersion; READWRITE(*const_cast<std::vector<CTxIn>*>(&vin)); @@ -245,7 +266,7 @@ public: READWRITE(*const_cast<uint32_t*>(&nLockTime)); if (fRead) UpdateHash(); - ) + } bool IsNull() const { return vin.empty() && vout.empty(); @@ -292,13 +313,16 @@ struct CMutableTransaction CMutableTransaction(); CMutableTransaction(const CTransaction& tx); - IMPLEMENT_SERIALIZE( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(this->nVersion); nVersion = this->nVersion; READWRITE(vin); READWRITE(vout); READWRITE(nLockTime); - ) + } /** Compute the hash of this CMutableTransaction. This is computed on the * fly, as opposed to GetHash() in CTransaction, which uses a cached result. @@ -318,7 +342,11 @@ public: CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } - IMPLEMENT_SERIALIZE(({ + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); if (!fRead) { uint64_t nVal = CompressAmount(txout.nValue); READWRITE(VARINT(nVal)); @@ -329,7 +357,7 @@ public: } CScriptCompressor cscript(REF(txout.scriptPubKey)); READWRITE(cscript); - });) + } }; /** Undo information for a CTxIn @@ -382,9 +410,12 @@ public: // undo information for all txins std::vector<CTxInUndo> vprevout; - IMPLEMENT_SERIALIZE( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(vprevout); - ) + } }; @@ -412,8 +443,10 @@ public: SetNull(); } - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(this->nVersion); nVersion = this->nVersion; READWRITE(hashPrevBlock); @@ -421,7 +454,7 @@ public: READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce); - ) + } void SetNull() { @@ -467,11 +500,13 @@ public: *((CBlockHeader*)this) = header; } - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(*(CBlockHeader*)this); READWRITE(vtx); - ) + } void SetNull() { @@ -515,12 +550,14 @@ struct CBlockLocator vHave = vHaveIn; } - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { if (!(nType & SER_GETHASH)) READWRITE(nVersion); READWRITE(vHave); - ) + } void SetNull() { diff --git a/src/crypter.h b/src/crypter.h index 9b592dbcdc..59efc76508 100644 --- a/src/crypter.h +++ b/src/crypter.h @@ -43,14 +43,17 @@ public: // such as the various parameters to scrypt std::vector<unsigned char> vchOtherDerivationParameters; - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(vchCryptedKey); READWRITE(vchSalt); READWRITE(nDerivationMethod); READWRITE(nDeriveIterations); READWRITE(vchOtherDerivationParameters); - ) + } + CMasterKey() { // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M diff --git a/src/main.h b/src/main.h index e0836960b3..31a1131b83 100644 --- a/src/main.h +++ b/src/main.h @@ -197,10 +197,13 @@ struct CDiskBlockPos int nFile; unsigned int nPos; - IMPLEMENT_SERIALIZE( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(VARINT(nFile)); READWRITE(VARINT(nPos)); - ) + } CDiskBlockPos() { SetNull(); @@ -227,10 +230,13 @@ struct CDiskTxPos : public CDiskBlockPos { unsigned int nTxOffset; // after header - IMPLEMENT_SERIALIZE( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(*(CDiskBlockPos*)this); READWRITE(VARINT(nTxOffset)); - ) + } CDiskTxPos(const CDiskBlockPos &blockIn, unsigned int nTxOffsetIn) : CDiskBlockPos(blockIn.nFile, blockIn.nPos), nTxOffset(nTxOffsetIn) { } @@ -307,9 +313,12 @@ class CBlockUndo public: std::vector<CTxUndo> vtxundo; // for all but the coinbase - IMPLEMENT_SERIALIZE( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(vtxundo); - ) + } bool WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock); bool ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock); @@ -411,7 +420,12 @@ protected: public: // serialization implementation - IMPLEMENT_SERIALIZE( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); + READWRITE(nTransactions); READWRITE(vHash); std::vector<unsigned char> vBytes; @@ -428,7 +442,7 @@ public: vBytes[p / 8] |= vBits[p] << (p % 8); READWRITE(vBytes); } - ) + } // Construct a partial merkle tree from a list of transaction id's, and a mask that selects a subset of them CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch); @@ -484,7 +498,10 @@ public: uint64_t nTimeFirst; // earliest time of block in file uint64_t nTimeLast; // latest time of block in file - IMPLEMENT_SERIALIZE( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(VARINT(nBlocks)); READWRITE(VARINT(nSize)); READWRITE(VARINT(nUndoSize)); @@ -492,7 +509,7 @@ public: READWRITE(VARINT(nHeightLast)); READWRITE(VARINT(nTimeFirst)); READWRITE(VARINT(nTimeLast)); - ) + } void SetNull() { nBlocks = 0; @@ -755,8 +772,10 @@ public: hashPrev = (pprev ? pprev->GetBlockHash() : 0); } - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { if (!(nType & SER_GETHASH)) READWRITE(VARINT(nVersion)); @@ -777,7 +796,7 @@ public: READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce); - ) + } uint256 GetBlockHash() const { @@ -975,11 +994,13 @@ public: // thus the filter will likely be modified. CMerkleBlock(const CBlock& block, CBloomFilter& filter); - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(header); READWRITE(txn); - ) + } }; diff --git a/src/netbase.h b/src/netbase.h index d4d266e0a8..9b52c0a415 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -88,10 +88,12 @@ class CNetAddr friend bool operator!=(const CNetAddr& a, const CNetAddr& b); friend bool operator<(const CNetAddr& a, const CNetAddr& b); - IMPLEMENT_SERIALIZE - ( - READWRITE(FLATDATA(ip)); - ) + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(FLATDATA(ip)); + } }; class CSubNet @@ -148,15 +150,17 @@ class CService : public CNetAddr CService(const struct in6_addr& ipv6Addr, unsigned short port); CService(const struct sockaddr_in6& addr); - IMPLEMENT_SERIALIZE - ( - CService* pthis = const_cast<CService*>(this); - READWRITE(FLATDATA(ip)); - unsigned short portN = htons(port); - READWRITE(portN); - if (fRead) - pthis->port = ntohs(portN); - ) + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); + READWRITE(FLATDATA(ip)); + unsigned short portN = htons(port); + READWRITE(portN); + if (fRead) + port = ntohs(portN); + } }; typedef CService proxyType; diff --git a/src/protocol.h b/src/protocol.h index d7565584af..e4b0991774 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -35,13 +35,15 @@ class CMessageHeader std::string GetCommand() const; bool IsValid() const; - IMPLEMENT_SERIALIZE - ( - READWRITE(FLATDATA(pchMessageStart)); - READWRITE(FLATDATA(pchCommand)); - READWRITE(nMessageSize); - READWRITE(nChecksum); - ) + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + READWRITE(nChecksum); + } // TODO: make private (improves encapsulation) public: @@ -83,20 +85,23 @@ class CAddress : public CService void Init(); - IMPLEMENT_SERIALIZE - ( - CAddress* pthis = const_cast<CAddress*>(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); - ) + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); + + CAddress* pthis = const_cast<CAddress*>(this); + 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(*(CService*)this); + } // TODO: make private (improves encapsulation) public: @@ -117,11 +122,13 @@ class CInv CInv(int typeIn, const uint256& hashIn); CInv(const std::string& strType, const uint256& hashIn); - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(type); READWRITE(hash); - ) + } friend bool operator<(const CInv& a, const CInv& b); diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index 4f0b241259..a558aa4942 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -24,8 +24,12 @@ public: QDateTime date; SendCoinsRecipient recipient; - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); + RecentRequestEntry* pthis = const_cast<RecentRequestEntry*>(this); unsigned int nDate = date.toTime_t(); @@ -37,8 +41,8 @@ public: READWRITE(recipient); if (fRead) - pthis->date = QDateTime::fromTime_t(nDate); - ) + date = QDateTime::fromTime_t(nDate); + } }; class RecentRequestEntryLessThan diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index b3a401e4cc..2a9ac4650f 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -59,8 +59,12 @@ public: static const int CURRENT_VERSION = 1; int nVersion; - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); + SendCoinsRecipient* pthis = const_cast<SendCoinsRecipient*>(this); std::string sAddress = pthis->address.toStdString(); @@ -89,7 +93,7 @@ public: pthis->paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size())); pthis->authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant); } - ) + } }; /** Interface to Bitcoin wallet from Qt view code. */ 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; -}; - - - diff --git a/src/wallet.h b/src/wallet.h index 41b4b1917c..cea61afed3 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -64,13 +64,15 @@ public: CKeyPool(); CKeyPool(const CPubKey& vchPubKeyIn); - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { if (!(nType & SER_GETHASH)) READWRITE(nVersion); READWRITE(nTime); READWRITE(vchPubKey); - ) + } }; /** Address book data */ @@ -490,16 +492,16 @@ public: fMerkleVerified = false; } + IMPLEMENT_SERIALIZE; - IMPLEMENT_SERIALIZE - ( - nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(*(CTransaction*)this); nVersion = this->nVersion; READWRITE(hashBlock); READWRITE(vMerkleBranch); READWRITE(nIndex); - ) - + } int SetMerkleBranch(const CBlock* pblock=NULL); @@ -514,7 +516,6 @@ public: bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectInsaneFee=true); }; - /** A transaction with a bunch of additional info that only the owner cares about. * It includes any unrecorded transactions needed to link it back to the block chain. */ @@ -604,8 +605,12 @@ public: nOrderPos = -1; } - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); + CWalletTx* pthis = const_cast<CWalletTx*>(this); if (fRead) pthis->Init(NULL); @@ -621,7 +626,7 @@ public: pthis->mapValue["timesmart"] = strprintf("%u", nTimeSmart); } - nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action); + READWRITE(*(CMerkleTx*)this); std::vector<CMerkleTx> vUnused; // Used to be vtxPrev READWRITE(vUnused); READWRITE(mapValue); @@ -640,12 +645,12 @@ public: pthis->nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(pthis->mapValue["timesmart"]) : 0; } - pthis->mapValue.erase("fromaccount"); - pthis->mapValue.erase("version"); - pthis->mapValue.erase("spent"); - pthis->mapValue.erase("n"); - pthis->mapValue.erase("timesmart"); - ) + mapValue.erase("fromaccount"); + mapValue.erase("version"); + mapValue.erase("spent"); + mapValue.erase("n"); + mapValue.erase("timesmart"); + } // make sure balances are recalculated void MarkDirty() @@ -891,15 +896,17 @@ public: CWalletKey(int64_t nExpires=0); - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { if (!(nType & SER_GETHASH)) READWRITE(nVersion); READWRITE(vchPrivKey); READWRITE(nTimeCreated); READWRITE(nTimeExpires); READWRITE(LIMITED_STRING(strComment, 65536)); - ) + } }; @@ -925,12 +932,14 @@ public: vchPubKey = CPubKey(); } - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { if (!(nType & SER_GETHASH)) READWRITE(nVersion); READWRITE(vchPubKey); - ) + } }; @@ -966,8 +975,12 @@ public: nEntryNo = 0; } - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + bool fRead = ser_action.ForRead(); + CAccountingEntry& me = *const_cast<CAccountingEntry*>(this); if (!(nType & SER_GETHASH)) READWRITE(nVersion); @@ -1007,8 +1020,8 @@ public: if (std::string::npos != nSepPos) me.strComment.erase(nSepPos); - me.mapValue.erase("n"); - ) + mapValue.erase("n"); + } private: std::vector<char> _ssExtra; diff --git a/src/walletdb.h b/src/walletdb.h index 24096e13ea..cf1a66216e 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -55,12 +55,14 @@ public: nCreateTime = nCreateTime_; } - IMPLEMENT_SERIALIZE - ( + IMPLEMENT_SERIALIZE; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(this->nVersion); nVersion = this->nVersion; READWRITE(nCreateTime); - ) + } void SetNull() { |