Back to home page

Bitcoin sources

 
 

    


File indexing completed on 2020-06-25 15:46:01

0001 // Copyright (c) 2009-2010 Satoshi Nakamoto
0002 // Copyright (c) 2009-2012 The Bitcoin developers
0003 // Distributed under the MIT/X11 software license, see the accompanying
0004 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
0005 #ifndef BITCOIN_SERIALIZE_H
0006 #define BITCOIN_SERIALIZE_H
0007 
0008 #include <string>
0009 #include <vector>
0010 #include <map>
0011 #include <set>
0012 #include <cassert>
0013 #include <climits>
0014 #include <cstring>
0015 #include <cstdio>
0016 
0017 #include <boost/type_traits/is_fundamental.hpp>
0018 #include <boost/tuple/tuple.hpp>
0019 #include <boost/tuple/tuple_comparison.hpp>
0020 #include <boost/tuple/tuple_io.hpp>
0021 
0022 typedef long long  int64;
0023 typedef unsigned long long  uint64;
0024 
0025 #include <sys/mman.h>
0026 #include <limits.h>
0027 
0028 #include "knobs.h"
0029 
0030 /* This comes from limits.h if it's not defined there set a sane default */
0031 #ifndef PAGESIZE
0032 #include <unistd.h>
0033 #define PAGESIZE sysconf(_SC_PAGESIZE)
0034 #endif
0035 #define mlock(a,b) \
0036   mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
0037   (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
0038 #define munlock(a,b) \
0039   munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
0040   (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
0041 
0042 class CScript;
0043 class CDataStream;
0044 class CAutoFile;
0045 static const unsigned int MAX_SIZE = 0x02000000;
0046 
0047 extern int VERSION;
0048 
0049 // Used to bypass the rule against non-const reference to temporary
0050 // where it makes sense with wrappers such as CFlatData or CTxDB
0051 template<typename T>
0052 inline T& REF(const T& val)
0053 {
0054     return const_cast<T&>(val);
0055 }
0056 
0057 /////////////////////////////////////////////////////////////////
0058 //
0059 // Templates for serializing to anything that looks like a stream,
0060 // i.e. anything that supports .read(char*, int) and .write(char*, int)
0061 //
0062 
0063 enum
0064 {
0065     // primary actions
0066     SER_NETWORK         = (1 << 0),
0067     SER_DISK            = (1 << 1),
0068     SER_GETHASH         = (1 << 2),
0069 
0070     // modifiers
0071     SER_SKIPSIG         = (1 << 16),
0072     SER_BLOCKHEADERONLY = (1 << 17),
0073 };
0074 
0075 #define IMPLEMENT_SERIALIZE(statements)    \
0076     unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const  \
0077     {                                           \
0078         CSerActionGetSerializeSize ser_action;  \
0079         const bool fGetSize = true;             \
0080         const bool fWrite = false;              \
0081         const bool fRead = false;               \
0082         unsigned int nSerSize = 0;              \
0083         ser_streamplaceholder s;                \
0084         assert(fGetSize||fWrite||fRead); /* suppress warning */ \
0085         s.nType = nType;                        \
0086         s.nVersion = nVersion;                  \
0087         {statements}                            \
0088         return nSerSize;                        \
0089     }                                           \
0090     template<typename Stream>                   \
0091     void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const  \
0092     {                                           \
0093         CSerActionSerialize ser_action;         \
0094         const bool fGetSize = false;            \
0095         const bool fWrite = true;               \
0096         const bool fRead = false;               \
0097         unsigned int nSerSize = 0;              \
0098         assert(fGetSize||fWrite||fRead); /* suppress warning */ \
0099         {statements}                            \
0100     }                                           \
0101     template<typename Stream>                   \
0102     void Unserialize(Stream& s, int nType=0, int nVersion=VERSION)  \
0103     {                                           \
0104         CSerActionUnserialize ser_action;       \
0105         const bool fGetSize = false;            \
0106         const bool fWrite = false;              \
0107         const bool fRead = true;                \
0108         unsigned int nSerSize = 0;              \
0109         assert(fGetSize||fWrite||fRead); /* suppress warning */ \
0110         {statements}                            \
0111     }
0112 
0113 #define READWRITE(obj)      (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
0114 
0115 
0116 
0117 
0118 
0119 
0120 //
0121 // Basic types
0122 //
0123 #define WRITEDATA(s, obj)   s.write((char*)&(obj), sizeof(obj))
0124 #define READDATA(s, obj)    s.read((char*)&(obj), sizeof(obj))
0125 
0126 inline unsigned int GetSerializeSize(char a,           int, int=0) { return sizeof(a); }
0127 inline unsigned int GetSerializeSize(signed char a,    int, int=0) { return sizeof(a); }
0128 inline unsigned int GetSerializeSize(unsigned char a,  int, int=0) { return sizeof(a); }
0129 inline unsigned int GetSerializeSize(signed short a,   int, int=0) { return sizeof(a); }
0130 inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
0131 inline unsigned int GetSerializeSize(signed int a,     int, int=0) { return sizeof(a); }
0132 inline unsigned int GetSerializeSize(unsigned int a,   int, int=0) { return sizeof(a); }
0133 inline unsigned int GetSerializeSize(signed long a,    int, int=0) { return sizeof(a); }
0134 inline unsigned int GetSerializeSize(unsigned long a,  int, int=0) { return sizeof(a); }
0135 inline unsigned int GetSerializeSize(int64 a,          int, int=0) { return sizeof(a); }
0136 inline unsigned int GetSerializeSize(uint64 a,         int, int=0) { return sizeof(a); }
0137 inline unsigned int GetSerializeSize(float a,          int, int=0) { return sizeof(a); }
0138 inline unsigned int GetSerializeSize(double a,         int, int=0) { return sizeof(a); }
0139 
0140 template<typename Stream> inline void Serialize(Stream& s, char a,           int, int=0) { WRITEDATA(s, a); }
0141 template<typename Stream> inline void Serialize(Stream& s, signed char a,    int, int=0) { WRITEDATA(s, a); }
0142 template<typename Stream> inline void Serialize(Stream& s, unsigned char a,  int, int=0) { WRITEDATA(s, a); }
0143 template<typename Stream> inline void Serialize(Stream& s, signed short a,   int, int=0) { WRITEDATA(s, a); }
0144 template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
0145 template<typename Stream> inline void Serialize(Stream& s, signed int a,     int, int=0) { WRITEDATA(s, a); }
0146 template<typename Stream> inline void Serialize(Stream& s, unsigned int a,   int, int=0) { WRITEDATA(s, a); }
0147 template<typename Stream> inline void Serialize(Stream& s, signed long a,    int, int=0) { WRITEDATA(s, a); }
0148 template<typename Stream> inline void Serialize(Stream& s, unsigned long a,  int, int=0) { WRITEDATA(s, a); }
0149 template<typename Stream> inline void Serialize(Stream& s, int64 a,          int, int=0) { WRITEDATA(s, a); }
0150 template<typename Stream> inline void Serialize(Stream& s, uint64 a,         int, int=0) { WRITEDATA(s, a); }
0151 template<typename Stream> inline void Serialize(Stream& s, float a,          int, int=0) { WRITEDATA(s, a); }
0152 template<typename Stream> inline void Serialize(Stream& s, double a,         int, int=0) { WRITEDATA(s, a); }
0153 
0154 template<typename Stream> inline void Unserialize(Stream& s, char& a,           int, int=0) { READDATA(s, a); }
0155 template<typename Stream> inline void Unserialize(Stream& s, signed char& a,    int, int=0) { READDATA(s, a); }
0156 template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a,  int, int=0) { READDATA(s, a); }
0157 template<typename Stream> inline void Unserialize(Stream& s, signed short& a,   int, int=0) { READDATA(s, a); }
0158 template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
0159 template<typename Stream> inline void Unserialize(Stream& s, signed int& a,     int, int=0) { READDATA(s, a); }
0160 template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a,   int, int=0) { READDATA(s, a); }
0161 template<typename Stream> inline void Unserialize(Stream& s, signed long& a,    int, int=0) { READDATA(s, a); }
0162 template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a,  int, int=0) { READDATA(s, a); }
0163 template<typename Stream> inline void Unserialize(Stream& s, int64& a,          int, int=0) { READDATA(s, a); }
0164 template<typename Stream> inline void Unserialize(Stream& s, uint64& a,         int, int=0) { READDATA(s, a); }
0165 template<typename Stream> inline void Unserialize(Stream& s, float& a,          int, int=0) { READDATA(s, a); }
0166 template<typename Stream> inline void Unserialize(Stream& s, double& a,         int, int=0) { READDATA(s, a); }
0167 
0168 inline unsigned int GetSerializeSize(bool a, int, int=0)                          { return sizeof(char); }
0169 template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0)    { char f=a; WRITEDATA(s, f); }
0170 template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
0171 
0172 
0173 
0174 
0175 
0176 
0177 //
0178 // Compact size
0179 //  size <  253        -- 1 byte
0180 //  size <= USHRT_MAX  -- 3 bytes  (253 + 2 bytes)
0181 //  size <= UINT_MAX   -- 5 bytes  (254 + 4 bytes)
0182 //  size >  UINT_MAX   -- 9 bytes  (255 + 8 bytes)
0183 //
0184 inline unsigned int GetSizeOfCompactSize(uint64 nSize)
0185 {
0186     if (nSize < 253)             return sizeof(unsigned char);
0187     else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short);
0188     else if (nSize <= UINT_MAX)  return sizeof(unsigned char) + sizeof(unsigned int);
0189     else                         return sizeof(unsigned char) + sizeof(uint64);
0190 }
0191 
0192 template<typename Stream>
0193 void WriteCompactSize(Stream& os, uint64 nSize)
0194 {
0195     if (nSize < 253)
0196     {
0197         unsigned char chSize = nSize;
0198         WRITEDATA(os, chSize);
0199     }
0200     else if (nSize <= USHRT_MAX)
0201     {
0202         unsigned char chSize = 253;
0203         unsigned short xSize = nSize;
0204         WRITEDATA(os, chSize);
0205         WRITEDATA(os, xSize);
0206     }
0207     else if (nSize <= UINT_MAX)
0208     {
0209         unsigned char chSize = 254;
0210         unsigned int xSize = nSize;
0211         WRITEDATA(os, chSize);
0212         WRITEDATA(os, xSize);
0213     }
0214     else
0215     {
0216         unsigned char chSize = 255;
0217         uint64 xSize = nSize;
0218         WRITEDATA(os, chSize);
0219         WRITEDATA(os, xSize);
0220     }
0221     return;
0222 }
0223 
0224 template<typename Stream>
0225 uint64 ReadCompactSize(Stream& is)
0226 {
0227     unsigned char chSize;
0228     READDATA(is, chSize);
0229     uint64 nSizeRet = 0;
0230     if (chSize < 253)
0231     {
0232         nSizeRet = chSize;
0233     }
0234     else if (chSize == 253)
0235     {
0236         unsigned short xSize;
0237         READDATA(is, xSize);
0238         nSizeRet = xSize;
0239     }
0240     else if (chSize == 254)
0241     {
0242         unsigned int xSize;
0243         READDATA(is, xSize);
0244         nSizeRet = xSize;
0245     }
0246     else
0247     {
0248         uint64 xSize;
0249         READDATA(is, xSize);
0250         nSizeRet = xSize;
0251     }
0252     if (nSizeRet > (uint64)MAX_SIZE)
0253         throw std::ios_base::failure("ReadCompactSize() : size too large");
0254     return nSizeRet;
0255 }
0256 
0257 
0258 
0259 //
0260 // Wrapper for serializing arrays and POD
0261 // There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it
0262 //
0263 #define FLATDATA(obj)   REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
0264 class CFlatData
0265 {
0266 protected:
0267     char* pbegin;
0268     char* pend;
0269 public:
0270     CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
0271     char* begin() { return pbegin; }
0272     const char* begin() const { return pbegin; }
0273     char* end() { return pend; }
0274     const char* end() const { return pend; }
0275 
0276     unsigned int GetSerializeSize(int, int=0) const
0277     {
0278         return pend - pbegin;
0279     }
0280 
0281     template<typename Stream>
0282     void Serialize(Stream& s, int, int=0) const
0283     {
0284         s.write(pbegin, pend - pbegin);
0285     }
0286 
0287     template<typename Stream>
0288     void Unserialize(Stream& s, int, int=0)
0289     {
0290         s.read(pbegin, pend - pbegin);
0291     }
0292 };
0293 
0294 
0295 
0296 //
0297 // string stored as a fixed length field
0298 //
0299 template<std::size_t LEN>
0300 class CFixedFieldString
0301 {
0302 protected:
0303     const std::string* pcstr;
0304     std::string* pstr;
0305 public:
0306     explicit CFixedFieldString(const std::string& str) : pcstr(&str), pstr(NULL) { }
0307     explicit CFixedFieldString(std::string& str) : pcstr(&str), pstr(&str) { }
0308 
0309     unsigned int GetSerializeSize(int, int=0) const
0310     {
0311         return LEN;
0312     }
0313 
0314     template<typename Stream>
0315     void Serialize(Stream& s, int, int=0) const
0316     {
0317         char pszBuf[LEN];
0318         strncpy(pszBuf, pcstr->c_str(), LEN);
0319         s.write(pszBuf, LEN);
0320     }
0321 
0322     template<typename Stream>
0323     void Unserialize(Stream& s, int, int=0)
0324     {
0325         if (pstr == NULL)
0326             throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string");
0327         char pszBuf[LEN+1];
0328         s.read(pszBuf, LEN);
0329         pszBuf[LEN] = '\0';
0330         *pstr = pszBuf;
0331     }
0332 };
0333 
0334 
0335 
0336 
0337 
0338 //
0339 // Forward declarations
0340 //
0341 
0342 // string
0343 template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int=0);
0344 template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0);
0345 template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
0346 
0347 // vector
0348 template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
0349 template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
0350 template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION);
0351 template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
0352 template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
0353 template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION);
0354 template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
0355 template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
0356 template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION);
0357 
0358 // others derived from vector
0359 extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION);
0360 template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION);
0361 template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION);
0362 
0363 // pair
0364 template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION);
0365 template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
0366 template<typename Stream, typename K, typename T> void