1 2 #include "zfstream.h" 3 4 gzfilebuf::gzfilebuf() : 5 file(NULL), 6 mode(0), 7 own_file_descriptor(0) 8 { } 9 10 gzfilebuf::~gzfilebuf() { 11 12 sync(); 13 if ( own_file_descriptor ) 14 close(); 15 16 } 17 18 gzfilebuf *gzfilebuf::open( const char *name, 19 int io_mode ) { 20 21 if ( is_open() ) 22 return NULL; 23 24 char char_mode[10]; 25 char *p = char_mode; 26 27 if ( io_mode & ios::in ) { 28 mode = ios::in; 29 *p++ = 'r'; 30 } else if ( io_mode & ios::app ) { 31 mode = ios::app; 32 *p++ = 'a'; 33 } else { 34 mode = ios::out; 35 *p++ = 'w'; 36 } 37 38 if ( io_mode & ios::binary ) { 39 mode |= ios::binary; 40 *p++ = 'b'; 41 } 42 43 // Hard code the compression level 44 if ( io_mode & (ios::out|ios::app )) { 45 *p++ = '9'; 46 } 47 48 // Put the end-of-string indicator 49 *p = '\0'; 50 51 if ( (file = gzopen(name, char_mode)) == NULL ) 52 return NULL; 53 54 own_file_descriptor = 1; 55 56 return this; 57 58 } 59 60 gzfilebuf *gzfilebuf::attach( int file_descriptor, 61 int io_mode ) { 62 63 if ( is_open() ) 64 return NULL; 65 66 char char_mode[10]; 67 char *p = char_mode; 68 69 if ( io_mode & ios::in ) { 70 mode = ios::in; 71 *p++ = 'r'; 72 } else if ( io_mode & ios::app ) { 73 mode = ios::app; 74 *p++ = 'a'; 75 } else { 76 mode = ios::out; 77 *p++ = 'w'; 78 } 79 80 if ( io_mode & ios::binary ) { 81 mode |= ios::binary; 82 *p++ = 'b'; 83 } 84 85 // Hard code the compression level 86 if ( io_mode & (ios::out|ios::app )) { 87 *p++ = '9'; 88 } 89 90 // Put the end-of-string indicator 91 *p = '\0'; 92 93 if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) 94 return NULL; 95 96 own_file_descriptor = 0; 97 98 return this; 99 100 } 101 102 gzfilebuf *gzfilebuf::close() { 103 104 if ( is_open() ) { 105 106 sync(); 107 gzclose( file ); 108 file = NULL; 109 110 } 111 112 return this; 113 114 } 115 116 int gzfilebuf::setcompressionlevel( int comp_level ) { 117 118 return gzsetparams(file, comp_level, -2); 119 120 } 121 122 int gzfilebuf::setcompressionstrategy( int comp_strategy ) { 123 124 return gzsetparams(file, -2, comp_strategy); 125 126 } 127 128 129 streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { 130 131 return streampos(EOF); 132 133 } 134 135 int gzfilebuf::underflow() { 136 137 // If the file hasn't been opened for reading, error. 138 if ( !is_open() || !(mode & ios::in) ) 139 return EOF; 140 141 // if a buffer doesn't exists, allocate one. 142 if ( !base() ) { 143 144 if ( (allocate()) == EOF ) 145 return EOF; 146 setp(0,0); 147 148 } else { 149 150 if ( in_avail() ) 151 return (unsigned char) *gptr(); 152 153 if ( out_waiting() ) { 154 if ( flushbuf() == EOF ) 155 return EOF; 156 } 157 158 } 159 160 // Attempt to fill the buffer. 161 162 int result = fillbuf(); 163 if ( result == EOF ) { 164 // disable get area 165 setg(0,0,0); 166 return EOF; 167 } 168 169 return (unsigned char) *gptr(); 170 171 } 172 173 int gzfilebuf::overflow( int c ) { 174 175 if ( !is_open() || !(mode & ios::out) ) 176 return EOF; 177 178 if ( !base() ) { 179 if ( allocate() == EOF ) 180 return EOF; 181 setg(0,0,0); 182 } else { 183 if (in_avail()) { 184 return EOF; 185 } 186 if (out_waiting()) { 187 if (flushbuf() == EOF) 188 return EOF; 189 } 190 } 191 192 int bl = blen(); 193 setp( base(), base() + bl); 194 195 if ( c != EOF ) { 196 197 *pptr() = c; 198 pbump(1); 199 200 } 201 202 return 0; 203 204 } 205 206 int gzfilebuf::sync() { 207 208 if ( !is_open() ) 209 return EOF; 210 211 if ( out_waiting() ) 212 return flushbuf(); 213 214 return 0; 215 216 } 217 218 int gzfilebuf::flushbuf() { 219 220 int n; 221 char *q; 222 223 q = pbase(); 224 n = pptr() - q; 225 226 if ( gzwrite( file, q, n) < n ) 227 return EOF; 228 229 setp(0,0); 230 231 return 0; 232 233 } 234 235 int gzfilebuf::fillbuf() { 236 237 int required; 238 char *p; 239 240 p = base(); 241 242 required = blen(); 243 244 int t = gzread( file, p, required ); 245 246 if ( t <= 0) return EOF; 247 248 setg( base(), base(), base()+t); 249 250 return t; 251 252 } 253 254 gzfilestream_common::gzfilestream_common() : 255 ios( gzfilestream_common::rdbuf() ) 256 { } 257 258 gzfilestream_common::~gzfilestream_common() 259 { } 260 261 void gzfilestream_common::attach( int fd, int io_mode ) { 262 263 if ( !buffer.attach( fd, io_mode) ) 264 clear( ios::failbit | ios::badbit ); 265 else 266 clear(); 267 268 } 269 270 void gzfilestream_common::open( const char *name, int io_mode ) { 271 272 if ( !buffer.open( name, io_mode ) ) 273 clear( ios::failbit | ios::badbit ); 274 else 275 clear(); 276 277 } 278 279 void gzfilestream_common::close() { 280 281 if ( !buffer.close() ) 282 clear( ios::failbit | ios::badbit ); 283 284 } 285 286 gzfilebuf *gzfilestream_common::rdbuf() 287 { 288 return &buffer; 289 } 290 291 gzifstream::gzifstream() : 292 ios( gzfilestream_common::rdbuf() ) 293 { 294 clear( ios::badbit ); 295 } 296 297 gzifstream::gzifstream( const char *name, int io_mode ) : 298 ios( gzfilestream_common::rdbuf() ) 299 { 300 gzfilestream_common::open( name, io_mode ); 301 } 302 303 gzifstream::gzifstream( int fd, int io_mode ) : 304 ios( gzfilestream_common::rdbuf() ) 305 { 306 gzfilestream_common::attach( fd, io_mode ); 307 } 308 309 gzifstream::~gzifstream() { } 310 311 gzofstream::gzofstream() : 312 ios( gzfilestream_common::rdbuf() ) 313 { 314 clear( ios::badbit ); 315 } 316 317 gzofstream::gzofstream( const char *name, int io_mode ) : 318 ios( gzfilestream_common::rdbuf() ) 319 { 320 gzfilestream_common::open( name, io_mode ); 321 } 322 323 gzofstream::gzofstream( int fd, int io_mode ) : 324 ios( gzfilestream_common::rdbuf() ) 325 { 326 gzfilestream_common::attach( fd, io_mode ); 327 } 328 329 gzofstream::~gzofstream() { } 330