Changeset 12255
- Timestamp:
- 10/25/11 13:49:11 (13 years ago)
- Location:
- fact/tools/rootmacros
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/tools/rootmacros/fits.h
r12200 r12255 1 #error Please replace fits.h with https://fact.isdc.unige.ch/svn/trunk/Mars/mcore/fits.h 1 #ifndef MARS_fits 2 #define MARS_fits 3 4 #include <stdint.h> 5 6 #include <map> 7 #include <string> 8 #include <sstream> 9 #include <algorithm> 10 11 #ifdef __EXCEPTIONS 12 #include <stdexcept> 13 #endif 14 15 #ifdef __CINT__ 16 #define off_t size_t 17 #endif 18 19 #ifndef __MARS__ 20 #include <vector> 21 #include <iomanip> 22 #include <iostream> 23 #define gLog cerr 24 #define err "" 25 #define all "" 26 #else 27 #include "MLog.h" 28 #include "MLogManip.h" 29 #endif 30 31 #ifdef HAVE_ZLIB 32 #include "izstream.h" 33 #else 34 #include <fstream> 35 #define izstream ifstream 36 #warning Support for zipped FITS files disabled. 37 #endif 38 39 namespace std 40 { 41 42 class fits : public izstream 43 { 44 public: 45 struct Entry 46 { 47 char type; 48 string value; 49 string comment; 50 51 template<typename T> 52 T Get() const 53 { 54 T t; 55 56 istringstream str(value); 57 str >> t; 58 59 return t; 60 } 61 }; 62 63 struct Table 64 { 65 off_t offset; 66 67 string name; 68 size_t bytes_per_row; 69 size_t num_rows; 70 size_t num_cols; 71 72 struct Column 73 { 74 size_t offset; 75 size_t num; 76 size_t size; 77 char type; 78 string unit; 79 }; 80 81 typedef map<string, Entry> Keys; 82 typedef map<string, Column> Columns; 83 84 Columns cols; 85 Keys keys; 86 87 string Trim(const string &str, char c=' ') const 88 { 89 // Trim Both leading and trailing spaces 90 const size_t pstart = str.find_first_not_of(c); // Find the first character position after excluding leading blank spaces 91 const size_t pend = str.find_last_not_of(c); // Find the first character position from reverse af 92 93 // if all spaces or empty return an empty string 94 if (string::npos==pstart || string::npos==pend) 95 return string(); 96 97 return str.substr(pstart, pend-pstart+1); 98 } 99 100 bool Check(const string &key, char type, const string &value="") const 101 { 102 const Keys::const_iterator it = keys.find(key); 103 if (it==keys.end()) 104 { 105 ostringstream str; 106 str << "Key '" << key << "' not found."; 107 #ifdef __EXCEPTIONS 108 throw runtime_error(str.str()); 109 #else 110 gLog << err << "ERROR - " << str.str() << endl; 111 return false; 112 #endif 113 } 114 115 if (it->second.type!=type) 116 { 117 ostringstream str; 118 str << "Wrong type for key '" << key << "': expected " << type << ", found " << it->second.type << "."; 119 #ifdef __EXCEPTIONS 120 throw runtime_error(str.str()); 121 #else 122 gLog << err << "ERROR - " << str.str() << endl; 123 return false; 124 #endif 125 } 126 127 if (!value.empty() && it->second.value!=value) 128 { 129 ostringstream str; 130 str << "Wrong value for key '" << key << "': expected " << value << ", found " << it->second.value << "."; 131 #ifdef __EXCEPTIONS 132 throw runtime_error(str.str()); 133 #else 134 gLog << err << "ERROR - " << str.str() << endl; 135 return false; 136 #endif 137 } 138 139 return true; 140 } 141 142 Keys ParseBlock(const vector<string> &vec) const 143 { 144 map<string,Entry> rc; 145 146 for (unsigned int i=0; i<vec.size(); i++) 147 { 148 const string key = Trim(vec[i].substr(0,8)); 149 // Keywords without a value, like COMMENT / HISTORY 150 if (vec[i].substr(8,2)!="= ") 151 continue; 152 153 char type = 0; 154 155 string com; 156 string val = Trim(vec[i].substr(10)); 157 if (val[0]=='\'') 158 { 159 // First skip all '' in the string 160 size_t p = 1; 161 while (1) 162 { 163 const size_t pp = val.find_first_of('\'', p); 164 if (pp==string::npos) 165 break; 166 167 p = val[pp+1]=='\'' ? pp+2 : pp+1; 168 } 169 170 // Now find the comment 171 const size_t ppp = val.find_first_of('/', p); 172 173 // Set value, comment and type 174 com = ppp==string::npos ? "" : Trim(val.substr(ppp+1)); 175 val = Trim(val.substr(1, p-2)); 176 type = 'T'; 177 } 178 else 179 { 180 const size_t p = val.find_first_of('/'); 181 182 com = Trim(val.substr(p+2)); 183 val = Trim(val.substr(0, p)); 184 185 if (val.empty() || val.find_first_of('T')!=string::npos || val.find_first_of('F')!=string::npos) 186 type = 'B'; 187 else 188 type = val.find_last_of('.')==string::npos ? 'I' : 'F'; 189 } 190 191 const Entry e = { type, val, com }; 192 rc[key] = e; 193 } 194 195 return rc; 196 } 197 198 Table() : offset(0) { } 199 Table(const vector<string> &vec, off_t off) : 200 offset(off), keys(ParseBlock(vec)) 201 { 202 if (!Check("XTENSION", 'T', "BINTABLE") || 203 !Check("NAXIS", 'I', "2") || 204 !Check("BITPIX", 'I', "8") || 205 !Check("PCOUNT", 'I', "0") || 206 !Check("GCOUNT", 'I', "1") || 207 !Check("EXTNAME", 'T') || 208 !Check("NAXIS1", 'I') || 209 !Check("NAXIS2", 'I') || 210 !Check("TFIELDS", 'I')) 211 return; 212 213 bytes_per_row = Get<size_t>("NAXIS1"); 214 num_rows = Get<size_t>("NAXIS2"); 215 num_cols = Get<size_t>("TFIELDS"); 216 217 size_t bytes = 0; 218 for (size_t i=1; i<=num_cols; i++) 219 { 220 ostringstream num; 221 num << i; 222 223 if (!Check("TTYPE"+num.str(), 'T') || 224 !Check("TFORM"+num.str(), 'T')) 225 return; 226 227 const string id = Get<string>("TTYPE"+num.str()); 228 const string fmt = Get<string>("TFORM"+num.str()); 229 const string unit = Get<string>("TUNIT"+num.str(), ""); 230 231 istringstream sin(fmt); 232 int n = 0; 233 sin >> n; 234 if (!sin) 235 n = 1; 236 237 const char type = fmt[fmt.length()-1]; 238 239 size_t size = 0; 240 switch (type) 241 { 242 // We could use negative values to mark floats 243 // otheriwse we could just cast them to int64_t? 244 case 'L': size = 1; break; // logical 245 // case 'X': size = n; break; // bits (n=number of bytes needed to contain all bits) 246 case 'B': size = 1; break; // byte 247 case 'I': size = 2; break; // short 248 case 'J': size = 4; break; // int 249 case 'K': size = 8; break; // long long 250 case 'E': size = 4; break; // float 251 case 'D': size = 8; break; // double 252 // case 'C': size = 8; break; // complex float 253 // case 'M': size = 16; break; // complex double 254 // case 'P': size = 8; break; // array descriptor (32bit) 255 // case 'Q': size = 16; break; // array descriptor (64bit) 256 default: 257 { 258 ostringstream str; 259 str << "FITS format TFORM='" << fmt << "' not yet supported."; 260 #ifdef __EXCEPTIONS 261 throw runtime_error(str.str()); 262 #else 263 gLog << err << "ERROR - " << str.str() << endl; 264 return; 265 #endif 266 } 267 } 268 269 const Table::Column col = { bytes, n, size, type, unit }; 270 271 cols[id] = col; 272 bytes += n*size; 273 } 274 275 if (bytes!=bytes_per_row) 276 { 277 #ifdef __EXCEPTIONS 278 throw runtime_error("Column size mismatch"); 279 #else 280 gLog << err << "ERROR - Column size mismatch" << endl; 281 return; 282 #endif 283 } 284 285 name = Get<string>("EXTNAME"); 286 } 287 288 void PrintKeys(bool display_all=false) const 289 { 290 for (Keys::const_iterator it=keys.begin(); it!=keys.end(); it++) 291 { 292 if (!display_all && 293 (it->first.substr(0, 6)!="TTYPE" || 294 it->first.substr(0, 6)!="TFORM" || 295 it->first.substr(0, 6)!="TUNIT" || 296 it->first!="TFIELDS" || 297 it->first!="XTENSION" || 298 it->first!="NAXIS" || 299 it->first!="BITPIX" || 300 it->first!="PCOUNT" || 301 it->first!="GCOUNT") 302 ) 303 continue; 304 305 gLog << all << setw(2) << it->second.type << '|' << it->first << '=' << it->second.value << '/' << it->second.comment << '|' << endl; 306 }} 307 308 void PrintColumns() const 309 { 310 typedef map<pair<size_t, string>, Column> Sorted; 311 312 Sorted sorted; 313 314 for (Columns::const_iterator it=cols.begin(); it!=cols.end(); it++) 315 sorted[make_pair(it->second.offset, it->first)] = it->second; 316 317 for (Sorted::const_iterator it=sorted.begin(); it!=sorted.end(); it++) 318 { 319 gLog << all << setw(6) << it->second.offset << "| "; 320 gLog << it->second.num << 'x'; 321 switch (it->second.type) 322 { 323 case 'L': gLog << "bool(8)"; break; 324 case 'B': gLog << "byte(8)"; break; 325 case 'I': gLog << "short(16)"; break; 326 case 'J': gLog << "int(32)"; break; 327 case 'K': gLog << "int(64)"; break; 328 case 'E': gLog << "float(32)"; break; 329 case 'D': gLog << "double(64)"; break; 330 } 331 gLog << ": " << it->first.second << " [" << it->second.unit << "]" << endl; 332 } 333 } 334 335 operator bool() const { return !name.empty(); } 336 337 bool HasKey(const string &key) const 338 { 339 return keys.find(key)!=keys.end(); 340 } 341 342 // Values of keys are always signed 343 template<typename T> 344 T Get(const string &key) const 345 { 346 const map<string,Entry>::const_iterator it = keys.find(key); 347 if (it==keys.end()) 348 { 349 ostringstream str; 350 str << "Key '" << key << "' not found." << endl; 351 #ifdef __EXCEPTIONS 352 throw runtime_error(str.str()); 353 #else 354 gLog << err << "ERROR - " << str.str() << endl; 355 return 0; 356 #endif 357 } 358 return it->second.Get<T>(); 359 } 360 361 // Values of keys are always signed 362 template<typename T> 363 T Get(const string &key, const string &deflt) const 364 { 365 const map<string,Entry>::const_iterator it = keys.find(key); 366 return it==keys.end() ? deflt :it->second.Get<T>(); 367 } 368 369 size_t GetN(const string &key) const 370 { 371 const Columns::const_iterator it = cols.find(key); 372 return it==cols.end() ? 0 : it->second.num; 373 } 374 }; 375 376 private: 377 Table fTable; 378 379 typedef pair<void*, Table::Column> Address; 380 typedef vector<Address> Addresses; 381 //map<void*, Table::Column> fAddresses; 382 Addresses fAddresses; 383 384 vector<char> fBufferRow; 385 vector<char> fBufferDat; 386 387 size_t fRow; 388 389 vector<string> ReadBlock(vector<string> &vec) 390 { 391 bool endtag = false; 392 for (int i=0; i<36; i++) 393 { 394 char c[81]; 395 c[80] = 0; 396 read(c, 80); 397 if (!good()) 398 break; 399 400 if (c[0]==0) 401 return vector<string>(); 402 403 string str(c); 404 405 // if (!str.empty()) 406 // cout << setw(2) << i << "|" << str << "|" << (endtag?'-':'+') << endl; 407 408 if (str=="END ") 409 { 410 endtag = true; 411 412 // Make sure that no empty vector is returned 413 if (vec.size()%36==0) 414 vec.push_back(string("END = '' / ")); 415 } 416 417 if (endtag) 418 continue; 419 420 vec.push_back(str); 421 } 422 423 return vec; 424 } 425 426 string Compile(const string &key, int16_t i=-1) 427 { 428 if (i<0) 429 return key; 430 431 ostringstream str; 432 str << key << i; 433 return str.str(); 434 } 435 436 public: 437 fits(const string &fname) : izstream(fname.c_str()) 438 { 439 char simple[10]; 440 read(simple, 10); 441 if (!good()) 442 return; 443 444 if (memcmp(simple, "SIMPLE = ", 10)) 445 { 446 clear(rdstate()|ios::badbit); 447 #ifdef __EXCEPTIONS 448 throw runtime_error("File is not a FITS file."); 449 #else 450 gLog << err << "ERROR - File is not a FITS file." << endl; 451 return; 452 #endif 453 } 454 455 seekg(0); 456 457 while (good()) 458 { 459 vector<string> block; 460 while (1) 461 { 462 // FIXME: Set limit on memory consumption 463 ReadBlock(block); 464 if (!good()) 465 { 466 clear(rdstate()|ios::badbit); 467 #ifdef __EXCEPTIONS 468 throw runtime_error("FITS file corrupted."); 469 #else 470 gLog << err << "ERROR - FITS file corrupted." << endl; 471 return; 472 #endif 473 } 474 475 if (block.size()%36) 476 break; 477 } 478 479 if (block.size()==0) 480 break; 481 482 if (block[0].substr(0, 9)=="SIMPLE =") 483 continue; 484 485 if (block[0].substr(0, 9)=="XTENSION=") 486 { 487 // FIXME: Check for table name 488 489 fTable = Table(block, tellg()); 490 fRow = (size_t)-1; 491 492 //fTable.PrintKeys(); 493 494 if (!fTable) 495 { 496 clear(rdstate()|ios::badbit); 497 return; 498 } 499 500 fBufferRow.resize(fTable.bytes_per_row); 501 fBufferDat.resize(fTable.bytes_per_row); 502 503 /* 504 // Next table should start at: 505 const size_t size = fTable.bytes_per_row*fTable.num_rows; 506 const size_t blks = size/(36*80); 507 const size_t rest = size%(36*80); 508 509 seekg((blks+(rest>0?1:0))*(36*80), ios::cur); 510 if (!good()) 511 gLog << err << "File seems to be incomplete (less data than expected from header)." << endl; 512 513 fRow = fTable.num_rows; 514 */ 515 516 break; 517 } 518 } 519 } 520 521 void ReadRow(size_t row) 522 { 523 // if (row!=fRow+1) // Fast seeking is ensured by izstream 524 seekg(fTable.offset+row*fTable.bytes_per_row); 525 526 fRow = row; 527 528 read(fBufferRow.data(), fBufferRow.size()); 529 //fin.clear(fin.rdstate()&~ios::eofbit); 530 } 531 532 template<size_t N> 533 void revcpy(char *dest, const char *src, int num) 534 { 535 const char *pend = src + num*N; 536 for (const char *ptr = src; ptr<pend; ptr+=N, dest+=N) 537 reverse_copy(ptr, ptr+N, dest); 538 } 539 540 bool GetRow(size_t row) 541 { 542 ReadRow(row); 543 if (!good()) 544 return good(); 545 546 for (Addresses::const_iterator it=fAddresses.begin(); it!=fAddresses.end(); it++) 547 { 548 const Table::Column &c = it->second; 549 550 const char *src = fBufferRow.data() + c.offset; 551 char *dest = reinterpret_cast<char*>(it->first); 552 553 // Let the compiler do some optimization by 554 // knowing the we only have 1, 2, 4 and 8 555 switch (c.size) 556 { 557 case 1: memcpy (dest, src, c.num*c.size); break; 558 case 2: revcpy<2>(dest, src, c.num); break; 559 case 4: revcpy<4>(dest, src, c.num); break; 560 case 8: revcpy<8>(dest, src, c.num); break; 561 } 562 } 563 564 return good(); 565 } 566 567 bool GetNextRow() 568 { 569 return GetRow(fRow+1); 570 } 571 572 bool SkipNextRow() 573 { 574 seekg(fTable.offset+(++fRow)*fTable.bytes_per_row); 575 return good(); 576 } 577 578 static bool Compare(const Address &p1, const Address &p2) 579 { 580 return p1.first>p2.first; 581 } 582 583 template<typename T> 584 bool SetPtrAddress(const string &name, T *ptr, size_t cnt) 585 { 586 if (fTable.cols.count(name)==0) 587 { 588 ostringstream str; 589 str <<"SetPtrAddress('" << name << "') - Column not found." << endl; 590 #ifdef __EXCEPTIONS 591 throw runtime_error(str.str()); 592 #else 593 gLog << err << "ERROR - " << str.str() << endl; 594 return false; 595 #endif 596 } 597 598 if (sizeof(T)!=fTable.cols[name].size) 599 { 600 ostringstream str; 601 str << "SetPtrAddress('" << name << "') - Element size mismatch: expected " 602 << fTable.cols[name].size << " from header, got " << sizeof(T) << endl; 603 #ifdef __EXCEPTIONS 604 throw runtime_error(str.str()); 605 #else 606 gLog << err << "ERROR - " << str.str() << endl; 607 return false; 608 #endif 609 } 610 611 if (cnt!=fTable.cols[name].num) 612 { 613 ostringstream str; 614 str << "SetPtrAddress('" << name << "') - Element count mismatch: expected " 615 << fTable.cols[name].num << " from header, got " << cnt << endl; 616 #ifdef __EXCEPTIONS 617 throw runtime_error(str.str()); 618 #else 619 gLog << err << "ERROR - " << str.str() << endl; 620 return false; 621 #endif 622 } 623 624 // if (fAddresses.count(ptr)>0) 625 // gLog << warn << "SetPtrAddress('" << name << "') - Pointer " << ptr << " already assigned." << endl; 626 627 //fAddresses[ptr] = fTable.cols[name]; 628 fAddresses.push_back(make_pair(ptr, fTable.cols[name])); 629 sort(fAddresses.begin(), fAddresses.end(), Compare); 630 return true; 631 } 632 633 template<class T> 634 bool SetRefAddress(const string &name, T &ptr) 635 { 636 return SetPtrAddress(name, &ptr, sizeof(ptr)/sizeof(T)); 637 } 638 639 template<typename T> 640 bool SetVecAddress(const string &name, vector<T> &vec) 641 { 642 return SetPtrAddress(name, vec.data(), vec.size()); 643 } 644 645 template<typename T> 646 T Get(const string &key) const 647 { 648 return fTable.Get<T>(key); 649 } 650 651 template<typename T> 652 T Get(const string &key, const string &deflt) const 653 { 654 return fTable.Get<T>(key, deflt); 655 } 656 657 bool SetPtrAddress(const string &name, void *ptr) 658 { 659 if (fTable.cols.count(name)==0) 660 { 661 ostringstream str; 662 str <<"SetPtrAddress('" << name << "') - Column not found." << endl; 663 #ifdef __EXCEPTIONS 664 throw runtime_error(str.str()); 665 #else 666 gLog << err << "ERROR - " << str.str() << endl; 667 return false; 668 #endif 669 } 670 671 // if (fAddresses.count(ptr)>0) 672 // gLog << warn << "SetPtrAddress('" << name << "') - Pointer " << ptr << " already assigned." << endl; 673 674 //fAddresses[ptr] = fTable.cols[name]; 675 fAddresses.push_back(make_pair(ptr, fTable.cols[name])); 676 sort(fAddresses.begin(), fAddresses.end(), Compare); 677 return true; 678 } 679 680 bool HasKey(const string &key) const { return fTable.HasKey(key); } 681 int64_t GetInt(const string &key) const { return fTable.Get<int64_t>(key); } 682 uint64_t GetUInt(const string &key) const { return fTable.Get<uint64_t>(key); } 683 double GetFloat(const string &key) const { return fTable.Get<double>(key); } 684 string GetStr(const string &key) const { return fTable.Get<string>(key); } 685 686 size_t GetN(const string &key) const 687 { 688 return fTable.GetN(key); 689 } 690 691 size_t GetNumRows() const { return fTable.num_rows; } 692 size_t GetRow() const { return fRow; } 693 694 operator bool() const { return fTable && fTable.offset!=0; } 695 696 void PrintKeys() const { fTable.PrintKeys(); } 697 void PrintColumns() const { fTable.PrintColumns(); } 698 }; 699 700 }; 701 #endif -
fact/tools/rootmacros/izstream.h
r12199 r12255 1 #error Please replace izstream.h with https://fact.isdc.unige.ch/svn/trunk/Mars/mcore/izstream.h 1 #ifndef MARS_izstream 2 #define MARS_izstream 3 4 #include <istream> 5 #include <streambuf> 6 7 #ifdef __MARS__ 8 #ifndef ROOT_TObject 9 #include <TObject.h> // Needed for ClassDef 10 #endif 11 #endif 12 13 #ifdef __CINT__ 14 typedef void *gzFile; 15 #else 16 #include <zlib.h> 17 #endif 18 19 class izstream : public std::streambuf, public std::istream 20 { 21 private: 22 static const int fgBufferSize = 3276804; // maximum size of a fact event + 4 23 24 gzFile fFile; // file handle for compressed file 25 char fBuffer[fgBufferSize]; // data buffer 26 27 int underflow() 28 { 29 if (gptr() && gptr()<egptr()) 30 return * reinterpret_cast<unsigned char *>(gptr()); 31 32 if (!is_open()) 33 return EOF; 34 35 // gptr()-eback(): if more than four bytes are already flushed 36 const int iputback = gptr()-eback()>4 ? 4 : gptr()-eback(); 37 38 // Copy the last four bytes flushed into the putback area 39 memcpy(fBuffer+(4-iputback), gptr()-iputback, iputback); 40 41 // Fill the buffer starting at the current file position and reset buffer 42 // pointers by calling setg 43 const int num = gzread(fFile, fBuffer+4, fgBufferSize-4); 44 if (num <= 0) // ERROR or EOF 45 return EOF; 46 47 // reset buffer pointers 48 setg(fBuffer+(4-iputback), fBuffer+4, fBuffer+4+num); 49 50 // return next character 51 return *reinterpret_cast<unsigned char *>(gptr()); 52 } 53 54 55 public: 56 izstream() : std::istream(this), fFile(0) 57 { 58 setg(fBuffer+4, fBuffer+4, fBuffer+4); 59 } 60 izstream(const char *name) : std::istream(this), fFile(0) 61 { 62 setg(fBuffer+4, fBuffer+4, fBuffer+4); 63 open(name); 64 } 65 ~izstream() { izstream::close(); } 66 67 int is_open() { return fFile!=0; } 68 69 // -------------------------------------------------------------------------- 70 // 71 // Open a file by name. Test if it is open like for an ifstream 72 // It doesn't matter whether the file is gzip compressed or not. 73 // 74 void open(const char* name) 75 { 76 if (is_open()) 77 { 78 clear(rdstate()|std::ios::failbit); 79 return; 80 } 81 82 fFile = gzopen(name, "rb"); 83 if (fFile == 0) 84 { 85 clear(rdstate()|std::ios::failbit); 86 return; 87 } 88 } 89 // -------------------------------------------------------------------------- 90 // 91 // Close an open file. 92 // 93 void close() 94 { 95 if (!is_open()) 96 return; 97 98 if (gzclose(fFile) != Z_OK) 99 clear(rdstate()|std::ios::failbit); 100 101 fFile = 0; 102 } 103 104 std::streambuf::pos_type seekoff(std::streambuf::off_type offset, std::ios_base::seekdir dir, 105 std::ios_base::openmode = std::ios_base::in) 106 { 107 // Using a switch instead results in: 108 // In member function `virtual std::streampos izstream::seekoff(long int, std::_Ios_Seekdir, std::_Ios_Openmode)': 109 // warning: enumeration value `_M_ios_seekdir_end' not handled in switch 110 // warning: case value `0' not in enumerated type `_Ios_Seekdir' 111 // warning: case value `1' not in enumerated type `_Ios_Seekdir' 112 // warning: case value `2' not in enumerated type `_Ios_Seekdir' 113 114 if (dir==std::ios::end) 115 { 116 clear(rdstate()|std::ios::failbit); 117 return EOF; 118 } 119 120 // We only do relative seeking to avoid unnecessary decompression 121 // of the whole file 122 if (dir==std::ios::beg) 123 offset -= tellg(); 124 125 // Calculate future position in streambuffer 126 const char *ptr = gptr()+offset; 127 128 // This is the number of bytes still available in the buffer 129 const size_t sbuf = egptr()-gptr(); 130 131 // Check if the new position will still be in the buffer 132 // In this case the target data was already decompressed. 133 if (ptr>=eback() && ptr<egptr()) 134 { 135 // Absolute position in z-stream 136 const z_off_t zpos = gztell(fFile)-sbuf; //gzseek(fFile, 0, SEEK_CUR); 137 138 gbump(offset); 139 140 return zpos+offset; 141 } 142 143 const streampos pos = gzseek(fFile, offset-sbuf, SEEK_CUR); 144 145 // Buffer is empty - force refilling 146 setg(fBuffer+4, fBuffer+4, fBuffer+4); 147 148 return pos<0 ? streampos(EOF) : pos; 149 150 /* 151 // SEEK_END not supported by zlib 152 if (dir==ios::end) 153 { 154 // Position in z-stream 155 const z_off_t zpos = gzseek(fFile, offset, SEEK_END); 156 if (zpos<0) 157 return EOF; 158 159 return fill_buffer()==EOF ? EOF : zpos; 160 } 161 */ 162 return EOF; 163 } 164 165 std::streambuf::pos_type seekpos(std::streambuf::pos_type pos, 166 std::ios_base::openmode = std::ios_base::in) 167 { 168 return seekoff(pos, std::ios::beg); 169 } 170 171 #ifdef __MARS__ 172 ClassDef(izstream, 0) // A C++ wrapper to istream zlib files 173 #endif 174 }; 175 176 #endif
Note:
See TracChangeset
for help on using the changeset viewer.