117209Swollman 217209Swollman#include "zfstream.h" 3192625Sedwin 417209Swollmangzfilebuf::gzfilebuf() : 515923Sscrappy file(NULL), 6192625Sedwin mode(0), 7192625Sedwin own_file_descriptor(0) 8192625Sedwin{ } 9192625Sedwin 10192625Sedwingzfilebuf::~gzfilebuf() { 11192625Sedwin 12111010Snectar sync(); 132708Swollman if ( own_file_descriptor ) 142708Swollman close(); 15214411Sedwin 162708Swollman} 172708Swollman 1892986Sobriengzfilebuf *gzfilebuf::open( const char *name, 192708Swollman int io_mode ) { 202708Swollman 212708Swollman if ( is_open() ) 2271579Sdeischen return NULL; 232708Swollman 2471579Sdeischen char char_mode[10]; 252708Swollman char *p = char_mode; 262708Swollman 272708Swollman if ( io_mode & ios::in ) { 28192625Sedwin mode = ios::in; 29192625Sedwin *p++ = 'r'; 30192625Sedwin } else if ( io_mode & ios::app ) { 31192625Sedwin mode = ios::app; 322708Swollman *p++ = 'a'; 33192625Sedwin } else { 34192625Sedwin mode = ios::out; 35192625Sedwin *p++ = 'w'; 36192625Sedwin } 37192625Sedwin 38192625Sedwin if ( io_mode & ios::binary ) { 39192625Sedwin mode |= ios::binary; 40192625Sedwin *p++ = 'b'; 41192625Sedwin } 42192625Sedwin 43192625Sedwin // Hard code the compression level 44192625Sedwin if ( io_mode & (ios::out|ios::app )) { 45192625Sedwin *p++ = '9'; 46192625Sedwin } 47192625Sedwin 48192625Sedwin // Put the end-of-string indicator 49192625Sedwin *p = '\0'; 50192625Sedwin 51192625Sedwin if ( (file = gzopen(name, char_mode)) == NULL ) 52192625Sedwin return NULL; 53192625Sedwin 54192625Sedwin own_file_descriptor = 1; 55192625Sedwin 56192625Sedwin return this; 57192625Sedwin 58192625Sedwin} 59192625Sedwin 60192625Sedwingzfilebuf *gzfilebuf::attach( int file_descriptor, 612708Swollman int io_mode ) { 62192625Sedwin 63192625Sedwin if ( is_open() ) 64192625Sedwin return NULL; 65192625Sedwin 66192625Sedwin char char_mode[10]; 67192625Sedwin char *p = char_mode; 68192625Sedwin 69192625Sedwin if ( io_mode & ios::in ) { 70192625Sedwin mode = ios::in; 71192625Sedwin *p++ = 'r'; 72192625Sedwin } else if ( io_mode & ios::app ) { 73192625Sedwin mode = ios::app; 74192625Sedwin *p++ = 'a'; 75192625Sedwin } else { 76192625Sedwin mode = ios::out; 77192625Sedwin *p++ = 'w'; 78192625Sedwin } 79192625Sedwin 80192625Sedwin if ( io_mode & ios::binary ) { 812708Swollman mode |= ios::binary; 82130461Sstefanf *p++ = 'b'; 8335285Sphk } 84130461Sstefanf 852708Swollman // Hard code the compression level 862708Swollman if ( io_mode & (ios::out|ios::app )) { 872708Swollman *p++ = '9'; 882708Swollman } 892708Swollman 902708Swollman // Put the end-of-string indicator 912708Swollman *p = '\0'; 922708Swollman 9392889Sobrien if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) 9492889Sobrien return NULL; 95192625Sedwin 96192625Sedwin own_file_descriptor = 0; 972708Swollman 98214411Sedwin return this; 99214411Sedwin 100214411Sedwin} 101214411Sedwin 1022708Swollmangzfilebuf *gzfilebuf::close() { 1032708Swollman 1042708Swollman if ( is_open() ) { 1052708Swollman 1062708Swollman sync(); 1072708Swollman gzclose( file ); 1082708Swollman file = NULL; 109192625Sedwin 110192625Sedwin } 111192625Sedwin 112192625Sedwin return this; 1132708Swollman 114192625Sedwin} 115192625Sedwin 116192625Sedwinint gzfilebuf::setcompressionlevel( int comp_level ) { 117192625Sedwin 118192625Sedwin return gzsetparams(file, comp_level, -2); 119192625Sedwin 1202708Swollman} 1212708Swollman 1222708Swollmanint gzfilebuf::setcompressionstrategy( int comp_strategy ) { 123192625Sedwin 124214411Sedwin return gzsetparams(file, -2, comp_strategy); 125214411Sedwin 126214411Sedwin} 127192625Sedwin 128192625Sedwin 129192625Sedwinstreampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { 130192625Sedwin 131192625Sedwin return streampos(EOF); 132192625Sedwin 133192625Sedwin} 1342708Swollman 135130461Sstefanfint gzfilebuf::underflow() { 136130461Sstefanf 137192625Sedwin // If the file hasn't been opened for reading, error. 138130461Sstefanf if ( !is_open() || !(mode & ios::in) ) 139130461Sstefanf return EOF; 140130461Sstefanf 141130461Sstefanf // if a buffer doesn't exists, allocate one. 142130461Sstefanf if ( !base() ) { 143130461Sstefanf 144192625Sedwin if ( (allocate()) == EOF ) 145130461Sstefanf 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 173int 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 206int 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 218int 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 235int 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 254gzfilestream_common::gzfilestream_common() : 255 ios( gzfilestream_common::rdbuf() ) 256{ } 257 258gzfilestream_common::~gzfilestream_common() 259{ } 260 261void 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 270void 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 279void gzfilestream_common::close() { 280 281 if ( !buffer.close() ) 282 clear( ios::failbit | ios::badbit ); 283 284} 285 286gzfilebuf *gzfilestream_common::rdbuf() 287{ 288 return &buffer; 289} 290 291gzifstream::gzifstream() : 292 ios( gzfilestream_common::rdbuf() ) 293{ 294 clear( ios::badbit ); 295} 296 297gzifstream::gzifstream( const char *name, int io_mode ) : 298 ios( gzfilestream_common::rdbuf() ) 299{ 300 gzfilestream_common::open( name, io_mode ); 301} 302 303gzifstream::gzifstream( int fd, int io_mode ) : 304 ios( gzfilestream_common::rdbuf() ) 305{ 306 gzfilestream_common::attach( fd, io_mode ); 307} 308 309gzifstream::~gzifstream() { } 310 311gzofstream::gzofstream() : 312 ios( gzfilestream_common::rdbuf() ) 313{ 314 clear( ios::badbit ); 315} 316 317gzofstream::gzofstream( const char *name, int io_mode ) : 318 ios( gzfilestream_common::rdbuf() ) 319{ 320 gzfilestream_common::open( name, io_mode ); 321} 322 323gzofstream::gzofstream( int fd, int io_mode ) : 324 ios( gzfilestream_common::rdbuf() ) 325{ 326 gzfilestream_common::attach( fd, io_mode ); 327} 328 329gzofstream::~gzofstream() { } 330