File indexing completed on 2020-06-25 15:46:01
0001
0002
0003
0004
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
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
0050
0051 template<typename T>
0052 inline T& REF(const T& val)
0053 {
0054 return const_cast<T&>(val);
0055 }
0056
0057
0058
0059
0060
0061
0062
0063 enum
0064 {
0065
0066 SER_NETWORK = (1 << 0),
0067 SER_DISK = (1 << 1),
0068 SER_GETHASH = (1 << 2),
0069
0070
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); \
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); \
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); \
0110 {statements} \
0111 }
0112
0113 #define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
0114
0115
0116
0117
0118
0119
0120
0121
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
0179
0180
0181
0182
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
0261
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
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
0340
0341
0342
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
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
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
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