diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2012-07-07 22:57:42 +0200 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2012-07-07 23:09:14 +0200 |
commit | 6ece1d747eed764f727ef60961ebdac66ab249c7 (patch) | |
tree | 4a673f1b81d5e98919fcb8069d3ab949d2d0d757 | |
parent | abbb9a829c6a381c7df1041ccfd2adebce86eafe (diff) |
CHashWriter that does SHA256 in-place during serialization
-rw-r--r-- | src/util.h | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/src/util.h b/src/util.h index 7b2c678916..7fe204c0df 100644 --- a/src/util.h +++ b/src/util.h @@ -391,6 +391,46 @@ inline uint256 Hash(const T1 pbegin, const T1 pend) return hash2; } +class CHashWriter +{ +private: + SHA256_CTX ctx; + +public: + int nType; + int nVersion; + + void Init() { + SHA256_Init(&ctx); + } + + CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) { + Init(); + } + + CHashWriter& write(const char *pch, size_t size) { + SHA256_Update(&ctx, pch, size); + return (*this); + } + + // invalidates the object + uint256 GetHash() { + uint256 hash1; + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; + } + + template<typename T> + CHashWriter& operator<<(const T& obj) { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } +}; + + template<typename T1, typename T2> inline uint256 Hash(const T1 p1begin, const T1 p1end, const T2 p2begin, const T2 p2end) @@ -428,13 +468,9 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end, template<typename T> uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) { - // Most of the time is spent allocating and deallocating CDataStream's - // buffer. If this ever needs to be optimized further, make a CStaticStream - // class with its buffer on the stack. - CDataStream ss(nType, nVersion); - ss.reserve(10000); + CHashWriter ss(nType, nVersion); ss << obj; - return Hash(ss.begin(), ss.end()); + return ss.GetHash(); } inline uint160 Hash160(const std::vector<unsigned char>& vch) |