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