genesis 1
genesis 2
genesis 3
genesis 4
genesis 5 #ifndef BITCOIN_SERIALIZE_H
genesis 6 #define BITCOIN_SERIALIZE_H
genesis 7
genesis 8 #include <string>
genesis 9 #include <vector>
genesis 10 #include <map>
genesis 11 #include <set>
genesis 12 #include <cassert>
genesis 13 #include <climits>
genesis 14 #include <cstring>
genesis 15 #include <cstdio>
genesis 16
genesis 17 #include <boost/type_traits/is_fundamental.hpp>
genesis 18 #include <boost/tuple/tuple.hpp>
genesis 19 #include <boost/tuple/tuple_comparison.hpp>
genesis 20 #include <boost/tuple/tuple_io.hpp>
genesis 21
genesis 22 typedef long long int64;
genesis 23 typedef unsigned long long uint64;
genesis 24
genesis 25 #include <sys/mman.h>
genesis 26 #include <limits.h>
genesis 27
genesis 28 #ifndef PAGESIZE
genesis 29 #include <unistd.h>
genesis 30 #define PAGESIZE sysconf(_SC_PAGESIZE)
genesis 31 #endif
genesis 32 #define mlock(a,b) \
genesis 33 mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
genesis 34 (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
genesis 35 #define munlock(a,b) \
genesis 36 munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\
genesis 37 (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1))))
genesis 38
genesis 39 class CScript;
genesis 40 class CDataStream;
genesis 41 class CAutoFile;
genesis 42 static const unsigned int MAX_SIZE = 0x02000000;
genesis 43
genesis 44 static const int VERSION = 50300;
genesis 45 static const char* pszSubVer = "";
genesis 46 static const bool VERSION_IS_BETA = true;
genesis 47
genesis 48
genesis 49
genesis 50 template<typename T>
genesis 51 inline T& REF(const T& val)
genesis 52 {
genesis 53 return const_cast<T&>(val);
genesis 54 }
genesis 55
genesis 56
genesis 57
genesis 58
genesis 59
genesis 60
genesis 61
genesis 62 enum
genesis 63 {
genesis 64
genesis 65 SER_NETWORK = (1 << 0),
genesis 66 SER_DISK = (1 << 1),
genesis 67 SER_GETHASH = (1 << 2),
genesis 68
genesis 69
genesis 70 SER_SKIPSIG = (1 << 16),
genesis 71 SER_BLOCKHEADERONLY = (1 << 17),
genesis 72 };
genesis 73
genesis 74 #define IMPLEMENT_SERIALIZE(statements) \
genesis 75 unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const \
genesis 76 { \
genesis 77 CSerActionGetSerializeSize ser_action; \
genesis 78 const bool fGetSize = true; \
genesis 79 const bool fWrite = false; \
genesis 80 const bool fRead = false; \
genesis 81 unsigned int nSerSize = 0; \
genesis 82 ser_streamplaceholder s; \
genesis 83 assert(fGetSize||fWrite||fRead); \
genesis 84 s.nType = nType; \
genesis 85 s.nVersion = nVersion; \
genesis 86 {statements} \
genesis 87 return nSerSize; \
genesis 88 } \
genesis 89 template<typename Stream> \
genesis 90 void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \
genesis 91 { \
genesis 92 CSerActionSerialize ser_action; \
genesis 93 const bool fGetSize = false; \
genesis 94 const bool fWrite = true; \
genesis 95 const bool fRead = false; \
genesis 96 unsigned int nSerSize = 0; \
genesis 97 assert(fGetSize||fWrite||fRead); \
genesis 98 {statements} \
genesis 99 } \
genesis 100 template<typename Stream> \
genesis 101 void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \
genesis 102 { \
genesis 103 CSerActionUnserialize ser_action; \
genesis 104 const bool fGetSize = false; \
genesis 105 const bool fWrite = false; \
genesis 106 const bool fRead = true; \
genesis 107 unsigned int nSerSize = 0; \
genesis 108 assert(fGetSize||fWrite||fRead); \
genesis 109 {statements} \
genesis 110 }
genesis 111
genesis 112 #define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
genesis 113
genesis 114
genesis 115
genesis 116
genesis 117
genesis 118
genesis 119
genesis 120
genesis 121
genesis 122 #define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
genesis 123 #define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
genesis 124
genesis 125 inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); }
genesis 126 inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); }
genesis 127 inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); }
genesis 128 inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); }
genesis 129 inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
genesis 130 inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); }
genesis 131 inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); }
genesis 132 inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); }
genesis 133 inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); }
genesis 134 inline unsigned int GetSerializeSize(int64 a, int, int=0) { return sizeof(a); }
genesis 135 inline unsigned int GetSerializeSize(uint64 a, int, int=0) { return sizeof(a); }
genesis 136 inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); }
genesis 137 inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); }
genesis 138
genesis 139 template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); }
genesis 140 template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); }
genesis 141 template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); }
genesis 142 template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); }
genesis 143 template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
genesis 144 template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); }
genesis 145 template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); }
genesis 146 template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); }
genesis 147 template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); }
genesis 148 template<typename Stream> inline void Serialize(Stream& s, int64 a, int, int=0) { WRITEDATA(s, a); }
genesis 149 template<typename Stream> inline void Serialize(Stream& s, uint64 a, int, int=0) { WRITEDATA(s, a); }
genesis 150 template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); }
genesis 151 template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); }
genesis 152
genesis 153 template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); }
genesis 154 template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); }
genesis 155 template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); }
genesis 156 template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); }
genesis 157 template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
genesis 158 template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); }
genesis 159 template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); }
genesis 160 template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); }
genesis 161 template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); }
genesis 162 template<typename Stream> inline void Unserialize(Stream& s, int64& a, int, int=0) { READDATA(s, a); }
genesis 163 template<typename Stream> inline void Unserialize(Stream& s, uint64& a, int, int=0) { READDATA(s, a); }
genesis 164 template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); }
genesis 165 template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); }
genesis 166
genesis 167 inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
genesis 168 template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); }
genesis 169 template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
genesis 170
genesis 171
genesis 172
genesis 173
genesis 174
genesis 175
genesis 176
genesis 177
genesis 178
genesis 179
genesis 180
genesis 181
genesis 182
genesis 183 inline unsigned int GetSizeOfCompactSize(uint64 nSize)
genesis 184 {
genesis 185 if (nSize < 253) return sizeof(unsigned char);
genesis 186 else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short);
genesis 187 else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int);
genesis 188 else return sizeof(unsigned char) + sizeof(uint64);
genesis 189 }
genesis 190
genesis 191 template<typename Stream>
genesis 192 void WriteCompactSize(Stream& os, uint64 nSize)
genesis 193 {
genesis 194 if (nSize < 253)
genesis 195 {
genesis 196 unsigned char chSize = nSize;
genesis 197 WRITEDATA(os, chSize);
genesis 198 }
genesis 199 else if (nSize <= USHRT_MAX)
genesis 200 {
genesis 201 unsigned char chSize = 253;
genesis 202 unsigned short xSize = nSize;
genesis 203 WRITEDATA(os, chSize);
genesis 204 WRITEDATA(os, xSize);
genesis 205 }
genesis 206 else if (nSize <= UINT_MAX)
genesis 207 {
genesis 208 unsigned char chSize = 254;
genesis 209 unsigned int xSize = nSize;
genesis 210 WRITEDATA(os, chSize);
genesis 211 WRITEDATA(os, xSize);
genesis 212 }
genesis 213 else
genesis 214 {
genesis 215 unsigned char chSize = 255;
genesis 216 uint64 xSize = nSize;
genesis 217 WRITEDATA(os, chSize);
genesis 218 WRITEDATA(os, xSize);
genesis 219 }
genesis 220 return;
genesis 221 }
genesis 222
genesis 223 template<typename Stream>
genesis 224 uint64 ReadCompactSize(Stream& is)
genesis 225 {
genesis 226 unsigned char chSize;
genesis 227 READDATA(is, chSize);
genesis 228 uint64 nSizeRet = 0;
genesis 229 if (chSize < 253)
genesis 230 {
genesis 231 nSizeRet = chSize;
genesis 232 }
genesis 233 else if (chSize == 253)
genesis 234 {
genesis 235 unsigned short xSize;
genesis 236 READDATA(is, xSize);
genesis 237 nSizeRet = xSize;
genesis 238 }
genesis 239 else if (chSize == 254)
genesis 240 {
genesis 241 unsigned int xSize;
genesis 242 READDATA(is, xSize);
genesis 243 nSizeRet = xSize;
genesis 244 }
genesis 245 else
genesis 246 {
genesis 247 uint64 xSize;
genesis 248 READDATA(is, xSize);
genesis 249 nSizeRet = xSize;
genesis 250 }
genesis 251 if (nSizeRet > (uint64)MAX_SIZE)
genesis 252 throw std::ios_base::failure("ReadCompactSize() : size too large");
genesis 253 return nSizeRet;
genesis 254 }
genesis 255
genesis 256
genesis 257
genesis 258
genesis 259
genesis 260
genesis 261
genesis 262 #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
genesis 263 class CFlatData
genesis 264 {
genesis 265 protected:
genesis 266 char* pbegin;
genesis 267 char* pend;
genesis 268 public:
genesis 269 CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
genesis 270 char* begin() { return pbegin; }
genesis 271 const char* begin() const { return pbegin; }
genesis 272 char* end() { return pend; }
genesis 273 const char* end() const { return pend; }
genesis 274
genesis 275 unsigned int GetSerializeSize(int, int=0) const
genesis 276 {
genesis 277 return pend - pbegin;
genesis 278 }
genesis 279
genesis 280 template<typename Stream>
genesis 281 void Serialize(Stream& s, int, int=0) const
genesis 282 {
genesis 283 s.write(pbegin, pend - pbegin);
genesis 284 }
genesis 285
genesis 286 template<typename Stream>
genesis 287 void Unserialize(Stream& s, int, int=0)
genesis 288 {
genesis 289 s.read(pbegin, pend - pbegin);
genesis 290 }
genesis 291 };
genesis 292
genesis 293
genesis 294
genesis 295
genesis 296
genesis 297
genesis 298 template<std::size_t LEN>
genesis 299 class CFixedFieldString
genesis 300 {
genesis 301 protected:
genesis 302 const std::string* pcstr;
genesis 303 std::string* pstr;
genesis 304 public:
genesis 305 explicit CFixedFieldString(const std::string& str) : pcstr(&str), pstr(NULL) { }
genesis 306 explicit CFixedFieldString(std::string& str) : pcstr(&str), pstr(&str) { }
genesis 307
genesis 308 unsigned int GetSerializeSize(int, int=0) const
genesis 309 {
genesis 310 return LEN;
genesis 311 }
genesis 312
genesis 313 template<typename Stream>
genesis 314 void Serialize(Stream& s, int, int=0) const
genesis 315 {
genesis 316 char pszBuf[LEN];
genesis 317 strncpy(pszBuf, pcstr->c_str(), LEN);
genesis 318 s.write(pszBuf, LEN);
genesis 319 }
genesis 320
genesis 321 template<typename Stream>
genesis 322 void Unserialize(Stream& s, int, int=0)
genesis 323 {
genesis 324 if (pstr == NULL)
genesis 325 throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string");
genesis 326 char pszBuf[LEN+1];
genesis 327 s.read(pszBuf, LEN);
genesis 328 pszBuf[LEN] = '\0';
genesis 329 *pstr = pszBuf;
genesis 330 }
genesis 331 };
genesis 332
genesis 333
genesis 334
genesis 335
genesis 336
genesis 337
genesis 338
genesis 339
genesis 340
genesis 341
genesis 342 template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int=0);
genesis 343 template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0);
genesis 344 template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
genesis 345
genesis 346
genesis 347 template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
genesis 348 template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
genesis 349 template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion=VERSION);
genesis 350 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&);
genesis 351 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&);
genesis 352 template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion=VERSION);
genesis 353 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&);
genesis 354 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&);
genesis 355 template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion=VERSION);
genesis 356
genesis 357
genesis 358 extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION);
genesis 359 template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION);
genesis 360 template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION);
genesis 361
genesis 362
genesis 363 template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion=VERSION);
genesis 364 template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
genesis 365 template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION);
genesis 366
genesis 367
genesis 368 template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
genesis 369 template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
genesis 370 template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
genesis 371
genesis 372
genesis 373 template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
genesis 374 template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
genesis 375 template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
genesis 376
genesis 377
genesis 378 template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
genesis 379 template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
genesis 380 template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
genesis 381
genesis 382
genesis 383 template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
genesis 384 template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
genesis 385 template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion=VERSION);
genesis 386
genesis 387
genesis 388
genesis 389
genesis 390
genesis 391
genesis 392
genesis 393
genesis 394
genesis 395
genesis 396
genesis 397 template<typename T>
genesis 398 inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION)
genesis 399 {
genesis 400 return a.GetSerializeSize((int)nType, nVersion);
genesis 401 }
genesis 402
genesis 403 template<typename Stream, typename T>
genesis 404 inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION)
genesis 405 {
genesis 406 a.Serialize(os, (int)nType, nVersion);
genesis 407 }
genesis 408
genesis 409 template<typename Stream, typename T>
genesis 410 inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION)
genesis 411 {
genesis 412 a.Unserialize(is, (int)nType, nVersion);
genesis 413 }
genesis 414
genesis 415
genesis 416
genesis 417
genesis 418
genesis 419
genesis 420
genesis 421
genesis 422 template<typename C>
genesis 423 unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int)
genesis 424 {
genesis 425 return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);
genesis 426 }
genesis 427
genesis 428 template<typename Stream, typename C>
genesis 429 void Serialize(Stream& os, const std::basic_string<C>& str, int, int)
genesis 430 {
genesis 431 WriteCompactSize(os, str.size());
genesis 432 if (!str.empty())
genesis 433 os.write((char*)&str[0], str.size() * sizeof(str[0]));
genesis 434 }
genesis 435
genesis 436 template<typename Stream, typename C>
genesis 437 void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
genesis 438 {
genesis 439 unsigned int nSize = ReadCompactSize(is);
genesis 440 str.resize(nSize);
genesis 441 if (nSize != 0)
genesis 442 is.read((char*)&str[0], nSize * sizeof(str[0]));
genesis 443 }
genesis 444
genesis 445
genesis 446
genesis 447
genesis 448
genesis 449
genesis 450 template<typename T, typename A>
genesis 451 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
genesis 452 {
genesis 453 return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
genesis 454 }
genesis 455
genesis 456 template<typename T, typename A>
genesis 457 unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
genesis 458 {
genesis 459 unsigned int nSize = GetSizeOfCompactSize(v.size());
genesis 460 for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
genesis 461 nSize += GetSerializeSize((*vi), nType, nVersion);
genesis 462 return nSize;
genesis 463 }
genesis 464
genesis 465 template<typename T, typename A>
genesis 466 inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
genesis 467 {
genesis 468 return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>());
genesis 469 }
genesis 470
genesis 471
genesis 472 template<typename Stream, typename T, typename A>
genesis 473 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
genesis 474 {
genesis 475 WriteCompactSize(os, v.size());
genesis 476 if (!v.empty())
genesis 477 os.write((char*)&v[0], v.size() * sizeof(T));
genesis 478 }
genesis 479
genesis 480 template<typename Stream, typename T, typename A>
genesis 481 void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
genesis 482 {
genesis 483 WriteCompactSize(os, v.size());
genesis 484 for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
genesis 485 ::Serialize(os, (*vi), nType, nVersion);
genesis 486 }
genesis 487
genesis 488 template<typename Stream, typename T, typename A>
genesis 489 inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
genesis 490 {
genesis 491 Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>());
genesis 492 }
genesis 493
genesis 494
genesis 495 template<typename Stream, typename T, typename A>
genesis 496 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
genesis 497 {
genesis 498
genesis 499
genesis 500
genesis 501
genesis 502
genesis 503 v.clear();
genesis 504 unsigned int nSize = ReadCompactSize(is);
genesis 505 unsigned int i = 0;
genesis 506 while (i < nSize)
genesis 507 {
genesis 508 unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));
genesis 509 v.resize(i + blk);
genesis 510 is.read((char*)&v[i], blk * sizeof(T));
genesis 511 i += blk;
genesis 512 }
genesis 513 }
genesis 514
genesis 515 template<typename Stream, typename T, typename A>
genesis 516 void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
genesis 517 {
genesis 518
genesis 519
genesis 520
genesis 521
genesis 522
genesis 523 v.clear();
genesis 524 unsigned int nSize = ReadCompactSize(is);
genesis 525 unsigned int i = 0;
genesis 526 unsigned int nMid = 0;
genesis 527 while (nMid < nSize)
genesis 528 {
genesis 529 nMid += 5000000 / sizeof(T);
genesis 530 if (nMid > nSize)
genesis 531 nMid = nSize;
genesis 532 v.resize(nMid);
genesis 533 for (; i < nMid; i++)
genesis 534 Unserialize(is, v[i], nType, nVersion);
genesis 535 }
genesis 536 }
genesis 537
genesis 538 template<typename Stream, typename T, typename A>
genesis 539 inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
genesis 540 {
genesis 541 Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>());
genesis 542 }
genesis 543
genesis 544
genesis 545
genesis 546
genesis 547
genesis 548
genesis 549 inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion)
genesis 550 {
genesis 551 return GetSerializeSize((const std::vector<unsigned char>&)v, nType, nVersion);
genesis 552 }
genesis 553
genesis 554 template<typename Stream>
genesis 555 void Serialize(Stream& os, const CScript& v, int nType, int nVersion)
genesis 556 {
genesis 557 Serialize(os, (const std::vector<unsigned char>&)v, nType, nVersion);
genesis 558 }
genesis 559
genesis 560 template<typename Stream>
genesis 561 void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
genesis 562 {
genesis 563 Unserialize(is, (std::vector<unsigned char>&)v, nType, nVersion);
genesis 564 }
genesis 565
genesis 566
genesis 567
genesis 568
genesis 569
genesis 570
genesis 571 template<typename K, typename T>
genesis 572 unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion)
genesis 573 {
genesis 574 return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);
genesis 575 }
genesis 576
genesis 577 template<typename Stream, typename K, typename T>
genesis 578 void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion)
genesis 579 {
genesis 580 Serialize(os, item.first, nType, nVersion);
genesis 581 Serialize(os, item.second, nType, nVersion);
genesis 582 }
genesis 583
genesis 584 template<typename Stream, typename K, typename T>
genesis 585 void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
genesis 586 {
genesis 587 Unserialize(is, item.first, nType, nVersion);
genesis 588 Unserialize(is, item.second, nType, nVersion);
genesis 589 }
genesis 590
genesis 591
genesis 592
genesis 593
genesis 594
genesis 595
genesis 596 template<typename T0, typename T1, typename T2>
genesis 597 unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
genesis 598 {
genesis 599 unsigned int nSize = 0;
genesis 600 nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
genesis 601 nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
genesis 602 nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
genesis 603 return nSize;
genesis 604 }
genesis 605
genesis 606 template<typename Stream, typename T0, typename T1, typename T2>
genesis 607 void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
genesis 608 {
genesis 609 Serialize(os, boost::get<0>(item), nType, nVersion);
genesis 610 Serialize(os, boost::get<1>(item), nType, nVersion);
genesis 611 Serialize(os, boost::get<2>(item), nType, nVersion);
genesis 612 }
genesis 613
genesis 614 template<typename Stream, typename T0, typename T1, typename T2>
genesis 615 void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
genesis 616 {
genesis 617 Unserialize(is, boost::get<0>(item), nType, nVersion);
genesis 618 Unserialize(is, boost::get<1>(item), nType, nVersion);
genesis 619 Unserialize(is, boost::get<2>(item), nType, nVersion);
genesis 620 }
genesis 621
genesis 622
genesis 623
genesis 624
genesis 625
genesis 626
genesis 627 template<typename T0, typename T1, typename T2, typename T3>
genesis 628 unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
genesis 629 {
genesis 630 unsigned int nSize = 0;
genesis 631 nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion);
genesis 632 nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion);
genesis 633 nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion);
genesis 634 nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion);
genesis 635 return nSize;
genesis 636 }
genesis 637
genesis 638 template<typename Stream, typename T0, typename T1, typename T2, typename T3>
genesis 639 void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
genesis 640 {
genesis 641 Serialize(os, boost::get<0>(item), nType, nVersion);
genesis 642 Serialize(os, boost::get<1>(item), nType, nVersion);
genesis 643 Serialize(os, boost::get<2>(item), nType, nVersion);
genesis 644 Serialize(os, boost::get<3>(item), nType, nVersion);
genesis 645 }
genesis 646
genesis 647 template<typename Stream, typename T0, typename T1, typename T2, typename T3>
genesis 648 void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
genesis 649 {
genesis 650 Unserialize(is, boost::get<0>(item), nType, nVersion);
genesis 651 Unserialize(is, boost::get<1>(item), nType, nVersion);
genesis 652 Unserialize(is, boost::get<2>(item), nType, nVersion);
genesis 653 Unserialize(is, boost::get<3>(item), nType, nVersion);
genesis 654 }
genesis 655
genesis 656
genesis 657
genesis 658
genesis 659
genesis 660
genesis 661 template<typename K, typename T, typename Pred, typename A>
genesis 662 unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion)
genesis 663 {
genesis 664 unsigned int nSize = GetSizeOfCompactSize(m.size());
genesis 665 for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
genesis 666 nSize += GetSerializeSize((*mi), nType, nVersion);
genesis 667 return nSize;
genesis 668 }
genesis 669
genesis 670 template<typename Stream, typename K, typename T, typename Pred, typename A>
genesis 671 void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion)
genesis 672 {
genesis 673 WriteCompactSize(os, m.size());
genesis 674 for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
genesis 675 Serialize(os, (*mi), nType, nVersion);
genesis 676 }
genesis 677
genesis 678 template<typename Stream, typename K, typename T, typename Pred, typename A>
genesis 679 void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion)
genesis 680 {
genesis 681 m.clear();
genesis 682 unsigned int nSize = ReadCompactSize(is);
genesis 683 typename std::map<K, T, Pred, A>::iterator mi = m.begin();
genesis 684 for (unsigned int i = 0; i < nSize; i++)
genesis 685 {
genesis 686 std::pair<K, T> item;
genesis 687 Unserialize(is, item, nType, nVersion);
genesis 688 mi = m.insert(mi, item);
genesis 689 }
genesis 690 }
genesis 691
genesis 692
genesis 693
genesis 694
genesis 695
genesis 696
genesis 697 template<typename K, typename Pred, typename A>
genesis 698 unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion)
genesis 699 {
genesis 700 unsigned int nSize = GetSizeOfCompactSize(m.size());
genesis 701 for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
genesis 702 nSize += GetSerializeSize((*it), nType, nVersion);
genesis 703 return nSize;
genesis 704 }
genesis 705
genesis 706 template<typename Stream, typename K, typename Pred, typename A>
genesis 707 void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion)
genesis 708 {
genesis 709 WriteCompactSize(os, m.size());
genesis 710 for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)
genesis 711 Serialize(os, (*it), nType, nVersion);
genesis 712 }
genesis 713
genesis 714 template<typename Stream, typename K, typename Pred, typename A>
genesis 715 void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion)
genesis 716 {
genesis 717 m.clear();
genesis 718 unsigned int nSize = ReadCompactSize(is);
genesis 719 typename std::set<K, Pred, A>::iterator it = m.begin();
genesis 720 for (unsigned int i = 0; i < nSize; i++)
genesis 721 {
genesis 722 K key;
genesis 723 Unserialize(is, key, nType, nVersion);
genesis 724 it = m.insert(it, key);
genesis 725 }
genesis 726 }
genesis 727
genesis 728
genesis 729
genesis 730
genesis 731
genesis 732
genesis 733 class CSerActionGetSerializeSize { };
genesis 734 class CSerActionSerialize { };
genesis 735 class CSerActionUnserialize { };
genesis 736
genesis 737 template<typename Stream, typename T>
genesis 738 inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action)
genesis 739 {
genesis 740 return ::GetSerializeSize(obj, nType, nVersion);
genesis 741 }
genesis 742
genesis 743 template<typename Stream, typename T>
genesis 744 inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action)
genesis 745 {
genesis 746 ::Serialize(s, obj, nType, nVersion);
genesis 747 return 0;
genesis 748 }
genesis 749
genesis 750 template<typename Stream, typename T>
genesis 751 inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action)
genesis 752 {
genesis 753 ::Unserialize(s, obj, nType, nVersion);
genesis 754 return 0;
genesis 755 }
genesis 756
genesis 757 struct ser_streamplaceholder
genesis 758 {
genesis 759 int nType;
genesis 760 int nVersion;
genesis 761 };
genesis 762
genesis 763
genesis 764
genesis 765
genesis 766
genesis 767
genesis 768
genesis 769
genesis 770
genesis 771
genesis 772
genesis 773
genesis 774
genesis 775 template<typename T>
genesis 776 struct secure_allocator : public std::allocator<T>
genesis 777 {
genesis 778
genesis 779 typedef std::allocator<T> base;
genesis 780 typedef typename base::size_type size_type;
genesis 781 typedef typename base::difference_type difference_type;
genesis 782 typedef typename base::pointer pointer;
genesis 783 typedef typename base::const_pointer const_pointer;
genesis 784 typedef typename base::reference reference;
genesis 785 typedef typename base::const_reference const_reference;
genesis 786 typedef typename base::value_type value_type;
genesis 787 secure_allocator() throw() {}
genesis 788 secure_allocator(const secure_allocator& a) throw() : base(a) {}
genesis 789 template <typename U>
genesis 790 secure_allocator(const secure_allocator<U>& a) throw() : base(a) {}
genesis 791 ~secure_allocator() throw() {}
genesis 792 template<typename _Other> struct rebind
genesis 793 { typedef secure_allocator<_Other> other; };
genesis 794
genesis 795 T* allocate(std::size_t n, const void *hint = 0)
genesis 796 {
genesis 797 T *p;
genesis 798 p = std::allocator<T>::allocate(n, hint);
genesis 799 if (p != NULL)
genesis 800 mlock(p, sizeof(T) * n);
genesis 801 return p;
genesis 802 }
genesis 803
genesis 804 void deallocate(T* p, std::size_t n)
genesis 805 {
genesis 806 if (p != NULL)
genesis 807 {
genesis 808 memset(p, 0, sizeof(T) * n);
genesis 809 munlock(p, sizeof(T) * n);
genesis 810 }
genesis 811 std::allocator<T>::deallocate(p, n);
genesis 812 }
genesis 813 };
genesis 814
genesis 815
genesis 816
genesis 817
genesis 818
genesis 819 template<typename T>
genesis 820 struct zero_after_free_allocator : public std::allocator<T>
genesis 821 {
genesis 822
genesis 823 typedef std::allocator<T> base;
genesis 824 typedef typename base::size_type size_type;
genesis 825 typedef typename base::difference_type difference_type;
genesis 826 typedef typename base::pointer pointer;
genesis 827 typedef typename base::const_pointer const_pointer;
genesis 828 typedef typename base::reference reference;
genesis 829 typedef typename base::const_reference const_reference;
genesis 830 typedef typename base::value_type value_type;
genesis 831 zero_after_free_allocator() throw() {}
genesis 832 zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
genesis 833 template <typename U>
genesis 834 zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {}
genesis 835 ~zero_after_free_allocator() throw() {}
genesis 836 template<typename _Other> struct rebind
genesis 837 { typedef zero_after_free_allocator<_Other> other; };
genesis 838
genesis 839 void deallocate(T* p, std::size_t n)
genesis 840 {
genesis 841 if (p != NULL)
genesis 842 memset(p, 0, sizeof(T) * n);
genesis 843 std::allocator<T>::deallocate(p, n);
genesis 844 }
genesis 845 };
genesis 846
genesis 847
genesis 848
genesis 849
genesis 850
genesis 851
genesis 852
genesis 853
genesis 854 class CDataStream
genesis 855 {
genesis 856 protected:
genesis 857 typedef std::vector<char, zero_after_free_allocator<char> > vector_type;
genesis 858 vector_type vch;
genesis 859 unsigned int nReadPos;
genesis 860 short state;
genesis 861 short exceptmask;
genesis 862 public:
genesis 863 int nType;
genesis 864 int nVersion;
genesis 865
genesis 866 typedef vector_type::allocator_type allocator_type;
genesis 867 typedef vector_type::size_type size_type;
genesis 868 typedef vector_type::difference_type difference_type;
genesis 869 typedef vector_type::reference reference;
genesis 870 typedef vector_type::const_reference const_reference;
genesis 871 typedef vector_type::value_type value_type;
genesis 872 typedef vector_type::iterator iterator;
genesis 873 typedef vector_type::const_iterator const_iterator;
genesis 874 typedef vector_type::reverse_iterator reverse_iterator;
genesis 875
genesis 876 explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
genesis 877 {
genesis 878 Init(nTypeIn, nVersionIn);
genesis 879 }
genesis 880
genesis 881 CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
genesis 882 {
genesis 883 Init(nTypeIn, nVersionIn);
genesis 884 }
genesis 885
genesis 886 CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
genesis 887 {
genesis 888 Init(nTypeIn, nVersionIn);
genesis 889 }
genesis 890
genesis 891 CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
genesis 892 {
genesis 893 Init(nTypeIn, nVersionIn);
genesis 894 }
genesis 895
genesis 896 CDataStream(const std::vector<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
genesis 897 {
genesis 898 Init(nTypeIn, nVersionIn);
genesis 899 }
genesis 900
genesis 901 CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
genesis 902 {
genesis 903 Init(nTypeIn, nVersionIn);
genesis 904 }
genesis 905
genesis 906 void Init(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
genesis 907 {
genesis 908 nReadPos = 0;
genesis 909 nType = nTypeIn;
genesis 910 nVersion = nVersionIn;
genesis 911 state = 0;
genesis 912 exceptmask = std::ios::badbit | std::ios::failbit;
genesis 913 }
genesis 914
genesis 915 CDataStream& operator+=(const CDataStream& b)
genesis 916 {
genesis 917 vch.insert(vch.end(), b.begin(), b.end());
genesis 918 return *this;
genesis 919 }
genesis 920
genesis 921 friend CDataStream operator+(const CDataStream& a, const CDataStream& b)
genesis 922 {
genesis 923 CDataStream ret = a;
genesis 924 ret += b;
genesis 925 return (ret);
genesis 926 }
genesis 927
genesis 928 std::string str() const
genesis 929 {
genesis 930 return (std::string(begin(), end()));
genesis 931 }
genesis 932
genesis 933
genesis 934
genesis 935
genesis 936
genesis 937 const_iterator begin() const { return vch.begin() + nReadPos; }
genesis 938 iterator begin() { return vch.begin() + nReadPos; }
genesis 939 const_iterator end() const { return vch.end(); }
genesis 940 iterator end() { return vch.end(); }
genesis 941 size_type size() const { return vch.size() - nReadPos; }
genesis 942 bool empty() const { return vch.size() == nReadPos; }
genesis 943 void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); }
genesis 944 void reserve(size_type n) { vch.reserve(n + nReadPos); }
genesis 945 const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; }
genesis 946 reference operator[](size_type pos) { return vch[pos + nReadPos]; }
genesis 947 void clear() { vch.clear(); nReadPos = 0; }
genesis 948 iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); }
genesis 949 void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); }
genesis 950
genesis 951 void insert(iterator it, const_iterator first, const_iterator last)
genesis 952 {
genesis 953 if (it == vch.begin() + nReadPos && last - first <= nReadPos)
genesis 954 {
genesis 955
genesis 956 nReadPos -= (last - first);
genesis 957 memcpy(&vch[nReadPos], &first[0], last - first);
genesis 958 }
genesis 959 else
genesis 960 vch.insert(it, first, last);
genesis 961 }
genesis 962
genesis 963 void insert(iterator it, std::vector<char>::const_iterator first, std::vector<char>::const_iterator last)
genesis 964 {
genesis 965 if (it == vch.begin() + nReadPos && last - first <= nReadPos)
genesis 966 {
genesis 967
genesis 968 nReadPos -= (last - first);
genesis 969 memcpy(&vch[nReadPos], &first[0], last - first);
genesis 970 }
genesis 971 else
genesis 972 vch.insert(it, first, last);
genesis 973 }
genesis 974
genesis 975 void insert(iterator it, const char* first, const char* last)
genesis 976 {
genesis 977 if (it == vch.begin() + nReadPos && last - first <= nReadPos)
genesis 978 {
genesis 979
genesis 980 nReadPos -= (last - first);
genesis 981 memcpy(&vch[nReadPos], &first[0], last - first);
genesis 982 }
genesis 983 else
genesis 984 vch.insert(it, first, last);
genesis 985 }
genesis 986
genesis 987 iterator erase(iterator it)
genesis 988 {
genesis 989 if (it == vch.begin() + nReadPos)
genesis 990 {
genesis 991
genesis 992 if (++nReadPos >= vch.size())
genesis 993 {
genesis 994
genesis 995 nReadPos = 0;
genesis 996 return vch.erase(vch.begin(), vch.end());
genesis 997 }
genesis 998 return vch.begin() + nReadPos;
genesis 999 }
genesis 1000 else
genesis 1001 return vch.erase(it);
genesis 1002 }
genesis 1003
genesis 1004 iterator erase(iterator first, iterator last)
genesis 1005 {
genesis 1006 if (first == vch.begin() + nReadPos)
genesis 1007 {
genesis 1008
genesis 1009 if (last == vch.end())
genesis 1010 {
genesis 1011 nReadPos = 0;
genesis 1012 return vch.erase(vch.begin(), vch.end());
genesis 1013 }
genesis 1014 else
genesis 1015 {
genesis 1016 nReadPos = (last - vch.begin());
genesis 1017 return last;
genesis 1018 }
genesis 1019 }
genesis 1020 else
genesis 1021 return vch.erase(first, last);
genesis 1022 }
genesis 1023
genesis 1024 inline void Compact()
genesis 1025 {
genesis 1026 vch.erase(vch.begin(), vch.begin() + nReadPos);
genesis 1027 nReadPos = 0;
genesis 1028 }
genesis 1029
genesis 1030 bool Rewind(size_type n)
genesis 1031 {
genesis 1032
genesis 1033 if (n > nReadPos)
genesis 1034 return false;
genesis 1035 nReadPos -= n;
genesis 1036 return true;
genesis 1037 }
genesis 1038
genesis 1039
genesis 1040
genesis 1041
genesis 1042
genesis 1043 void setstate(short bits, const char* psz)
genesis 1044 {
genesis 1045 state |= bits;
genesis 1046 if (state & exceptmask)
genesis 1047 throw std::ios_base::failure(psz);
genesis 1048 }
genesis 1049
genesis 1050 bool eof() const { return size() == 0; }
genesis 1051 bool fail() const { return state & (std::ios::badbit | std::ios::failbit); }
genesis 1052 bool good() const { return !eof() && (state == 0); }
genesis 1053 void clear(short n) { state = n; }
genesis 1054 short exceptions() { return exceptmask; }
genesis 1055 short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; }
genesis 1056 CDataStream* rdbuf() { return this; }
genesis 1057 int in_avail() { return size(); }
genesis 1058
genesis 1059 void SetType(int n) { nType = n; }
genesis 1060 int GetType() { return nType; }
genesis 1061 void SetVersion(int n) { nVersion = n; }
genesis 1062 int GetVersion() { return nVersion; }
genesis 1063 void ReadVersion() { *this >> nVersion; }
genesis 1064 void WriteVersion() { *this << nVersion; }
genesis 1065
genesis 1066 CDataStream& read(char* pch, int nSize)
genesis 1067 {
genesis 1068
genesis 1069 assert(nSize >= 0);
genesis 1070 unsigned int nReadPosNext = nReadPos + nSize;
genesis 1071 if (nReadPosNext >= vch.size())
genesis 1072 {
genesis 1073 if (nReadPosNext > vch.size())
genesis 1074 {
genesis 1075 setstate(std::ios::failbit, "CDataStream::read() : end of data");
genesis 1076 memset(pch, 0, nSize);
genesis 1077 nSize = vch.size() - nReadPos;
genesis 1078 }
genesis 1079 memcpy(pch, &vch[nReadPos], nSize);
genesis 1080 nReadPos = 0;
genesis 1081 vch.clear();
genesis 1082 return (*this);
genesis 1083 }
genesis 1084 memcpy(pch, &vch[nReadPos], nSize);
genesis 1085 nReadPos = nReadPosNext;
genesis 1086 return (*this);
genesis 1087 }
genesis 1088
genesis 1089 CDataStream& ignore(int nSize)
genesis 1090 {
genesis 1091
genesis 1092 assert(nSize >= 0);
genesis 1093 unsigned int nReadPosNext = nReadPos + nSize;
genesis 1094 if (nReadPosNext >= vch.size())
genesis 1095 {
genesis 1096 if (nReadPosNext > vch.size())
genesis 1097 {
genesis 1098 setstate(std::ios::failbit, "CDataStream::ignore() : end of data");
genesis 1099 nSize = vch.size() - nReadPos;
genesis 1100 }
genesis 1101 nReadPos = 0;
genesis 1102 vch.clear();
genesis 1103 return (*this);
genesis 1104 }
genesis 1105 nReadPos = nReadPosNext;
genesis 1106 return (*this);
genesis 1107 }
genesis 1108
genesis 1109 CDataStream& write(const char* pch, int nSize)
genesis 1110 {
genesis 1111
genesis 1112 assert(nSize >= 0);
genesis 1113 vch.insert(vch.end(), pch, pch + nSize);
genesis 1114 return (*this);
genesis 1115 }
genesis 1116
genesis 1117 template<typename Stream>
genesis 1118 void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const
genesis 1119 {
genesis 1120
genesis 1121 if (!vch.empty())
genesis 1122 s.write((char*)&vch[0], vch.size() * sizeof(vch[0]));
genesis 1123 }
genesis 1124
genesis 1125 template<typename T>
genesis 1126 unsigned int GetSerializeSize(const T& obj)
genesis 1127 {
genesis 1128
genesis 1129 return ::GetSerializeSize(obj, nType, nVersion);
genesis 1130 }
genesis 1131
genesis 1132 template<typename T>
genesis 1133 CDataStream& operator<<(const T& obj)
genesis 1134 {
genesis 1135
genesis 1136 ::Serialize(*this, obj, nType, nVersion);
genesis 1137 return (*this);
genesis 1138 }
genesis 1139
genesis 1140 template<typename T>
genesis 1141 CDataStream& operator>>(T& obj)
genesis 1142 {
genesis 1143
genesis 1144 ::Unserialize(*this, obj, nType, nVersion);
genesis 1145 return (*this);
genesis 1146 }
genesis 1147 };
genesis 1148
genesis 1149 #ifdef TESTCDATASTREAM
genesis 1150
genesis 1151
genesis 1152
genesis 1153
genesis 1154
genesis 1155
genesis 1156
genesis 1157
genesis 1158
genesis 1159
genesis 1160
genesis 1161
genesis 1162
genesis 1163
genesis 1164
genesis 1165
genesis 1166
genesis 1167
genesis 1168
genesis 1169
genesis 1170
genesis 1171
genesis 1172
genesis 1173
genesis 1174
genesis 1175 #include <iostream>
genesis 1176 int main(int argc, char *argv[])
genesis 1177 {
genesis 1178 vector<unsigned char> vch(0xcc, 250);
genesis 1179 printf("CDataStream:\n");
genesis 1180 for (int n = 1000; n <= 4500000; n *= 2)
genesis 1181 {
genesis 1182 CDataStream ss;
genesis 1183 time_t nStart = time(NULL);
genesis 1184 for (int i = 0; i < n; i++)
genesis 1185 ss.write((char*)&vch[0], vch.size());
genesis 1186 printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
genesis 1187 }
genesis 1188 printf("stringstream:\n");
genesis 1189 for (int n = 1000; n <= 4500000; n *= 2)
genesis 1190 {
genesis 1191 stringstream ss;
genesis 1192 time_t nStart = time(NULL);
genesis 1193 for (int i = 0; i < n; i++)
genesis 1194 ss.write((char*)&vch[0], vch.size());
genesis 1195 printf("n=%-10d %d seconds\n", n, time(NULL) - nStart);
genesis 1196 }
genesis 1197 }
genesis 1198 #endif
genesis 1199
genesis 1200
genesis 1201
genesis 1202
genesis 1203
genesis 1204
genesis 1205
genesis 1206
genesis 1207
genesis 1208
genesis 1209
genesis 1210
genesis 1211
genesis 1212
genesis 1213
genesis 1214
genesis 1215 class CAutoFile
genesis 1216 {
genesis 1217 protected:
genesis 1218 FILE* file;
genesis 1219 short state;
genesis 1220 short exceptmask;
genesis 1221 public:
genesis 1222 int nType;
genesis 1223 int nVersion;
genesis 1224
genesis 1225 typedef FILE element_type;
genesis 1226
genesis 1227 CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION)
genesis 1228 {
genesis 1229 file = filenew;
genesis 1230 nType = nTypeIn;
genesis 1231 nVersion = nVersionIn;
genesis 1232 state = 0;
genesis 1233 exceptmask = std::ios::badbit | std::ios::failbit;
genesis 1234 }
genesis 1235
genesis 1236 ~CAutoFile()
genesis 1237 {
genesis 1238 fclose();
genesis 1239 }
genesis 1240
genesis 1241 void fclose()
genesis 1242 {
genesis 1243 if (file != NULL && file != stdin && file != stdout && file != stderr)
genesis 1244 ::fclose(file);
genesis 1245 file = NULL;
genesis 1246 }
genesis 1247
genesis 1248 FILE* release() { FILE* ret = file; file = NULL; return ret; }
genesis 1249 operator FILE*() { return file; }
genesis 1250 FILE* operator->() { return file; }
genesis 1251 FILE& operator*() { return *file; }
genesis 1252 FILE** operator&() { return &file; }
genesis 1253 FILE* operator=(FILE* pnew) { return file = pnew; }
genesis 1254 bool operator!() { return (file == NULL); }
genesis 1255
genesis 1256
genesis 1257
genesis 1258
genesis 1259
genesis 1260 void setstate(short bits, const char* psz)
genesis 1261 {
genesis 1262 state |= bits;
genesis 1263 if (state & exceptmask)
genesis 1264 throw std::ios_base::failure(psz);
genesis 1265 }
genesis 1266
genesis 1267 bool fail() const { return state & (std::ios::badbit | std::ios::failbit); }
genesis 1268 bool good() const { return state == 0; }
genesis 1269 void clear(short n = 0) { state = n; }
genesis 1270 short exceptions() { return exceptmask; }
genesis 1271 short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; }
genesis 1272
genesis 1273 void SetType(int n) { nType = n; }
genesis 1274 int GetType() { return nType; }
genesis 1275 void SetVersion(int n) { nVersion = n; }
genesis 1276 int GetVersion() { return nVersion; }
genesis 1277 void ReadVersion() { *this >> nVersion; }
genesis 1278 void WriteVersion() { *this << nVersion; }
genesis 1279
genesis 1280 CAutoFile& read(char* pch, int nSize)
genesis 1281 {
genesis 1282 if (!file)
genesis 1283 throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
genesis 1284 if (fread(pch, 1, nSize, file) != nSize)
genesis 1285 setstate(std::ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
genesis 1286 return (*this);
genesis 1287 }
genesis 1288
genesis 1289 CAutoFile& write(const char* pch, int nSize)
genesis 1290 {
genesis 1291 if (!file)
genesis 1292 throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
genesis 1293 if (fwrite(pch, 1, nSize, file) != nSize)
genesis 1294 setstate(std::ios::failbit, "CAutoFile::write : write failed");
genesis 1295 return (*this);
genesis 1296 }
genesis 1297
genesis 1298 template<typename T>
genesis 1299 unsigned int GetSerializeSize(const T& obj)
genesis 1300 {
genesis 1301
genesis 1302 return ::GetSerializeSize(obj, nType, nVersion);
genesis 1303 }
genesis 1304
genesis 1305 template<typename T>
genesis 1306 CAutoFile& operator<<(const T& obj)
genesis 1307 {
genesis 1308
genesis 1309 if (!file)
genesis 1310 throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL");
genesis 1311 ::Serialize(*this, obj, nType, nVersion);
genesis 1312 return (*this);
genesis 1313 }
genesis 1314
genesis 1315 template<typename T>
genesis 1316 CAutoFile& operator>>(T& obj)
genesis 1317 {
genesis 1318
genesis 1319 if (!file)
genesis 1320 throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL");
genesis 1321 ::Unserialize(*this, obj, nType, nVersion);
genesis 1322 return (*this);
genesis 1323 }
genesis 1324 };
genesis 1325
genesis 1326 #endif