Changeset 11551 for trunk/Mars/mbase/izstream.h
- Timestamp:
- 07/24/11 10:51:54 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Mars/mbase/izstream.h
r11549 r11551 1 #ifndef MARS_ MZlib2 #define MARS_ MZlib1 #ifndef MARS_izstream 2 #define MARS_izstream 3 3 4 #include <istream> 5 #include <streambuf> 6 7 #ifdef __MARS__ 4 8 #ifndef ROOT_TObject 5 9 #include <TObject.h> // Needed for ClassDef 10 #endif 6 11 #endif 7 12 … … 12 17 #endif 13 18 14 #include <istream> // base classes for MLog 15 16 class MZlib : public std::streambuf, public std::istream 19 class izstream : public std::streambuf, public std::istream 17 20 { 18 21 private: … … 22 25 char fBuffer[fgBufferSize]; // data buffer 23 26 24 int underflow(); 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 25 54 26 55 public: 27 MZlib() :istream(this), fFile(0)56 izstream() : std::istream(this), fFile(0) 28 57 { 29 58 setg(fBuffer+4, fBuffer+4, fBuffer+4); 30 59 } 31 MZlib(const char *name) :istream(this), fFile(0)60 izstream(const char *name) : std::istream(this), fFile(0) 32 61 { 33 62 setg(fBuffer+4, fBuffer+4, fBuffer+4); 34 63 open(name); 35 64 } 36 ~ MZlib() { MZlib::close(); }65 ~izstream() { izstream::close(); } 37 66 38 67 int is_open() { return fFile!=0; } 39 68 40 void open(const char* name); 41 void close(); 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 } 42 81 43 # if (__GNUC__>2) 44 std::streambuf::pos_type seekoff(std::streambuf::off_type, std::ios_base::seekdir, 45 std::ios_base::openmode = std::ios_base::in); 46 std::streambuf::pos_type seekpos(std::streambuf::pos_type, 47 std::ios_base::openmode = std::ios_base::in); 48 # else 49 std::streampos seekoff(std::streamoff, int, int = std::ios::in); 50 // std::streampos seekpos(std::streampos, int = std::ios::in); 51 # endif 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; 52 97 53 ClassDef(MZlib, 0) // A C++ wrapper to istream zlib files 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 54 174 }; 55 175
Note:
See TracChangeset
for help on using the changeset viewer.