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