X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fserialize.h;h=44eb4f580341a95fc1a00639899732511cebccd1;hb=265dcc7e227581180487d4a34aaca2c9a82d0db0;hp=d24624ebee02a4cac307796eb8e0d767479d9448;hpb=e873dc654c81810272e71af8b52a3836d2c8bf0a;p=novacoin.git diff --git a/src/serialize.h b/src/serialize.h index d24624e..44eb4f5 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SERIALIZE_H #define BITCOIN_SERIALIZE_H @@ -57,7 +57,7 @@ enum }; #define IMPLEMENT_SERIALIZE(statements) \ - unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const \ + unsigned int GetSerializeSize(int nType, int nVersion) const \ { \ CSerActionGetSerializeSize ser_action; \ const bool fGetSize = true; \ @@ -72,7 +72,7 @@ enum return nSerSize; \ } \ template \ - void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const \ + void Serialize(Stream& s, int nType, int nVersion) const \ { \ CSerActionSerialize ser_action; \ const bool fGetSize = false; \ @@ -83,7 +83,7 @@ enum {statements} \ } \ template \ - void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) \ + void Unserialize(Stream& s, int nType, int nVersion) \ { \ CSerActionUnserialize ser_action; \ const bool fGetSize = false; \ @@ -154,9 +154,14 @@ template inline void Serialize(Stream& s, bool a, int, int=0) template inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; } - - - +#ifndef THROW_WITH_STACKTRACE +#define THROW_WITH_STACKTRACE(exception) \ +{ \ + LogStackTrace(); \ + throw (exception); \ +} +void LogStackTrace(); +#endif // // Compact size @@ -234,7 +239,7 @@ uint64 ReadCompactSize(Stream& is) nSizeRet = xSize; } if (nSizeRet > (uint64)MAX_SIZE) - throw std::ios_base::failure("ReadCompactSize() : size too large"); + THROW_WITH_STACKTRACE(std::ios_base::failure("ReadCompactSize() : size too large")); return nSizeRet; } @@ -243,7 +248,6 @@ uint64 ReadCompactSize(Stream& is) #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) /** Wrapper for serializing arrays and POD. - * There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it. */ class CFlatData { @@ -287,43 +291,43 @@ template void Unserialize(Stream& is, std::basic_st // vector template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&); template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&); -template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion=PROTOCOL_VERSION); +template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion); template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&); template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&); -template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion=PROTOCOL_VERSION); +template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion); template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&); template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&); -template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion=PROTOCOL_VERSION); +template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion); // others derived from vector -extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const CScript& v, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, CScript& v, int nType, int nVersion=PROTOCOL_VERSION); +extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion); +template void Serialize(Stream& os, const CScript& v, int nType, int nVersion); +template void Unserialize(Stream& is, CScript& v, int nType, int nVersion); // pair -template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion=PROTOCOL_VERSION); +template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion); +template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion); +template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion); // 3 tuple -template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion); // 4 tuple -template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion=PROTOCOL_VERSION); +template unsigned int GetSerializeSize(const boost::tuple& item, int nType, int nVersion); +template void Serialize(Stream& os, const boost::tuple& item, int nType, int nVersion); +template void Unserialize(Stream& is, boost::tuple& item, int nType, int nVersion); // map -template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const std::map& m, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, std::map& m, int nType, int nVersion=PROTOCOL_VERSION); +template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion); +template void Serialize(Stream& os, const std::map& m, int nType, int nVersion); +template void Unserialize(Stream& is, std::map& m, int nType, int nVersion); // set -template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion=PROTOCOL_VERSION); -template void Serialize(Stream& os, const std::set& m, int nType, int nVersion=PROTOCOL_VERSION); -template void Unserialize(Stream& is, std::set& m, int nType, int nVersion=PROTOCOL_VERSION); +template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion); +template void Serialize(Stream& os, const std::set& m, int nType, int nVersion); +template void Unserialize(Stream& is, std::set& m, int nType, int nVersion); @@ -336,19 +340,19 @@ template void Unserializ // Thanks to Boost serialization for this idea. // template -inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=PROTOCOL_VERSION) +inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion) { return a.GetSerializeSize((int)nType, nVersion); } template -inline void Serialize(Stream& os, const T& a, long nType, int nVersion=PROTOCOL_VERSION) +inline void Serialize(Stream& os, const T& a, long nType, int nVersion) { a.Serialize(os, (int)nType, nVersion); } template -inline void Unserialize(Stream& is, T& a, long nType, int nVersion=PROTOCOL_VERSION) +inline void Unserialize(Stream& is, T& a, long nType, int nVersion) { a.Unserialize(is, (int)nType, nVersion); } @@ -730,39 +734,39 @@ public: typedef vector_type::const_iterator const_iterator; typedef vector_type::reverse_iterator reverse_iterator; - explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) + explicit CDataStream(int nTypeIn, int nVersionIn) { Init(nTypeIn, nVersionIn); } - CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend) + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) { Init(nTypeIn, nVersionIn); } #if !defined(_MSC_VER) || _MSC_VER >= 1300 - CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(pbegin, pend) + CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) { Init(nTypeIn, nVersionIn); } #endif - CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end()) + CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) { Init(nTypeIn, nVersionIn); } - CDataStream(const std::vector& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch(vchIn.begin(), vchIn.end()) + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) { Init(nTypeIn, nVersionIn); } - CDataStream(const std::vector& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) { Init(nTypeIn, nVersionIn); } - void Init(int nTypeIn=SER_NETWORK, int nVersionIn=PROTOCOL_VERSION) + void Init(int nTypeIn, int nVersionIn) { nReadPos = 0; nType = nTypeIn; @@ -809,7 +813,8 @@ public: void insert(iterator it, const_iterator first, const_iterator last) { - if (it == vch.begin() + nReadPos && last - first <= nReadPos) + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) { // special case for inserting at the front when there's room nReadPos -= (last - first); @@ -819,22 +824,12 @@ public: vch.insert(it, first, last); } - void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) - { - if (it == vch.begin() + nReadPos && last - first <= nReadPos) - { - // special case for inserting at the front when there's room - nReadPos -= (last - first); - memcpy(&vch[nReadPos], &first[0], last - first); - } - else - vch.insert(it, first, last); - } #if !defined(_MSC_VER) || _MSC_VER >= 1300 void insert(iterator it, const char* first, const char* last) { - if (it == vch.begin() + nReadPos && last - first <= nReadPos) + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) { // special case for inserting at the front when there's room nReadPos -= (last - first); @@ -905,7 +900,7 @@ public: { state |= bits; if (state & exceptmask) - throw std::ios_base::failure(psz); + THROW_WITH_STACKTRACE(std::ios_base::failure(psz)); } bool eof() const { return size() == 0; } @@ -976,7 +971,7 @@ public: } template - void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const + void Serialize(Stream& s, int nType, int nVersion) const { // Special case: stream << stream concatenates like stream += stream if (!vch.empty()) @@ -1007,57 +1002,6 @@ public: } }; -#ifdef TESTCDATASTREAM -// VC6sp6 -// CDataStream: -// n=1000 0 seconds -// n=2000 0 seconds -// n=4000 0 seconds -// n=8000 0 seconds -// n=16000 0 seconds -// n=32000 0 seconds -// n=64000 1 seconds -// n=128000 1 seconds -// n=256000 2 seconds -// n=512000 4 seconds -// n=1024000 8 seconds -// n=2048000 16 seconds -// n=4096000 32 seconds -// stringstream: -// n=1000 1 seconds -// n=2000 1 seconds -// n=4000 13 seconds -// n=8000 87 seconds -// n=16000 400 seconds -// n=32000 1660 seconds -// n=64000 6749 seconds -// n=128000 27241 seconds -// n=256000 109804 seconds -#include -int main(int argc, char *argv[]) -{ - vector vch(0xcc, 250); - printf("CDataStream:\n"); - for (int n = 1000; n <= 4500000; n *= 2) - { - CDataStream ss; - time_t nStart = time(NULL); - for (int i = 0; i < n; i++) - ss.write((char*)&vch[0], vch.size()); - printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); - } - printf("stringstream:\n"); - for (int n = 1000; n <= 4500000; n *= 2) - { - stringstream ss; - time_t nStart = time(NULL); - for (int i = 0; i < n; i++) - ss.write((char*)&vch[0], vch.size()); - printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); - } -} -#endif - @@ -1083,9 +1027,7 @@ public: int nType; int nVersion; - typedef FILE element_type; - - CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=PROTOCOL_VERSION) + CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) { file = filenew; nType = nTypeIn; @@ -1122,7 +1064,7 @@ public: { state |= bits; if (state & exceptmask) - throw std::ios_base::failure(psz); + THROW_WITH_STACKTRACE(std::ios_base::failure(psz)); } bool fail() const { return state & (std::ios::badbit | std::ios::failbit); } @@ -1138,7 +1080,7 @@ public: void ReadVersion() { *this >> nVersion; } void WriteVersion() { *this << nVersion; } - CAutoFile& read(char* pch, int nSize) + CAutoFile& read(char* pch, size_t nSize) { if (!file) throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); @@ -1147,7 +1089,7 @@ public: return (*this); } - CAutoFile& write(const char* pch, int nSize) + CAutoFile& write(const char* pch, size_t nSize) { if (!file) throw std::ios_base::failure("CAutoFile::write : file handle is NULL");