121308Sache 221308Sache#include "zfstream.h" 321308Sache 421308Sachegzfilebuf::gzfilebuf() : 521308Sache file(NULL), 621308Sache mode(0), 7119610Sache own_file_descriptor(0) 821308Sache{ } 921308Sache 1021308Sachegzfilebuf::~gzfilebuf() { 1121308Sache 1221308Sache sync(); 1321308Sache if ( own_file_descriptor ) 1421308Sache close(); 1558310Sache 1621308Sache} 1721308Sache 1821308Sachegzfilebuf *gzfilebuf::open( const char *name, 1921308Sache int io_mode ) { 2021308Sache 2121308Sache if ( is_open() ) 2221308Sache return NULL; 2321308Sache 2421308Sache char char_mode[10]; 2521308Sache char *p = char_mode; 2658310Sache 2721308Sache if ( io_mode & ios::in ) { 2821308Sache mode = ios::in; 2921308Sache *p++ = 'r'; 3021308Sache } else if ( io_mode & ios::app ) { 3121308Sache mode = ios::app; 3221308Sache *p++ = 'a'; 3326497Sache } else { 3426497Sache mode = ios::out; 3521308Sache *p++ = 'w'; 3621308Sache } 3721308Sache 3821308Sache if ( io_mode & ios::binary ) { 3921308Sache mode |= ios::binary; 4021308Sache *p++ = 'b'; 4126497Sache } 4226497Sache 4326497Sache // Hard code the compression level 4426497Sache if ( io_mode & (ios::out|ios::app )) { 4526497Sache *p++ = '9'; 4621308Sache } 4721308Sache 48119610Sache // Put the end-of-string indicator 49119610Sache *p = '\0'; 5021308Sache 5121308Sache if ( (file = gzopen(name, char_mode)) == NULL ) 5221308Sache return NULL; 5358310Sache 5458310Sache own_file_descriptor = 1; 5558310Sache 5647558Sache return this; 57119610Sache 5847558Sache} 5921308Sache 6075406Sachegzfilebuf *gzfilebuf::attach( int file_descriptor, 6121308Sache int io_mode ) { 6258310Sache 63119610Sache if ( is_open() ) 6421308Sache return NULL; 6521308Sache 6621308Sache char char_mode[10]; 6721308Sache char *p = char_mode; 6821308Sache 69119610Sache if ( io_mode & ios::in ) { 70119610Sache mode = ios::in; 71119610Sache *p++ = 'r'; 7275406Sache } else if ( io_mode & ios::app ) { 73119610Sache mode = ios::app; 74119610Sache *p++ = 'a'; 7521308Sache } else { 7621308Sache mode = ios::out; 7721308Sache *p++ = 'w'; 7821308Sache } 7921308Sache 8021308Sache if ( io_mode & ios::binary ) { 8121308Sache mode |= ios::binary; 8221308Sache *p++ = 'b'; 8321308Sache } 8421308Sache 8521308Sache // Hard code the compression level 8621308Sache if ( io_mode & (ios::out|ios::app )) { 8721308Sache *p++ = '9'; 8821308Sache } 8921308Sache 9021308Sache // Put the end-of-string indicator 9121308Sache *p = '\0'; 9221308Sache 9321308Sache if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) 9421308Sache return NULL; 9521308Sache 9621308Sache own_file_descriptor = 0; 9721308Sache 9821308Sache return this; 9921308Sache 10021308Sache} 10121308Sache 10221308Sachegzfilebuf *gzfilebuf::close() { 10321308Sache 10421308Sache if ( is_open() ) { 10521308Sache 10621308Sache sync(); 10721308Sache gzclose( file ); 108119610Sache file = NULL; 10921308Sache 11021308Sache } 11121308Sache 11221308Sache return this; 11321308Sache 11421308Sache} 11521308Sache 11621308Sacheint gzfilebuf::setcompressionlevel( int comp_level ) { 11721308Sache 11821308Sache return gzsetparams(file, comp_level, -2); 11921308Sache 12021308Sache} 12121308Sache 12221308Sacheint gzfilebuf::setcompressionstrategy( int comp_strategy ) { 12321308Sache 12421308Sache return gzsetparams(file, -2, comp_strategy); 12521308Sache 12621308Sache} 12721308Sache 12821308Sache 12921308Sachestreampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { 13021308Sache 13121308Sache return streampos(EOF); 13221308Sache 13321308Sache} 13421308Sache 13521308Sacheint gzfilebuf::underflow() { 13621308Sache 13721308Sache // If the file hasn't been opened for reading, error. 138119610Sache if ( !is_open() || !(mode & ios::in) ) 13921308Sache return EOF; 14021308Sache 14121308Sache // if a buffer doesn't exists, allocate one. 14221308Sache if ( !base() ) { 14321308Sache 14421308Sache if ( (allocate()) == EOF ) 14521308Sache return EOF; 14621308Sache setp(0,0); 14721308Sache 14821308Sache } else { 14921308Sache 15021308Sache if ( in_avail() ) 15121308Sache return (unsigned char) *gptr(); 15221308Sache 15321308Sache if ( out_waiting() ) { 15421308Sache if ( flushbuf() == EOF ) 15521308Sache return EOF; 15621308Sache } 15721308Sache 15821308Sache } 15921308Sache 16021308Sache // Attempt to fill the buffer. 16121308Sache 16221308Sache int result = fillbuf(); 16321308Sache if ( result == EOF ) { 16421308Sache // disable get area 16521308Sache setg(0,0,0); 16621308Sache return EOF; 16721308Sache } 16821308Sache 16921308Sache return (unsigned char) *gptr(); 170119610Sache 17121308Sache} 172119610Sache 173119610Sacheint gzfilebuf::overflow( int c ) { 174119610Sache 175119610Sache if ( !is_open() || !(mode & ios::out) ) 17621308Sache return EOF; 17721308Sache 17821308Sache if ( !base() ) { 17921308Sache if ( allocate() == EOF ) 18021308Sache return EOF; 18121308Sache setg(0,0,0); 18221308Sache } else { 18321308Sache if (in_avail()) { 18421308Sache return EOF; 18521308Sache } 18647558Sache if (out_waiting()) { 18747558Sache if (flushbuf() == EOF) 18847558Sache return EOF; 189119610Sache } 19047558Sache } 19175406Sache 19221308Sache int bl = blen(); 193119610Sache setp( base(), base() + bl); 19421308Sache 19521308Sache if ( c != EOF ) { 19621308Sache 19721308Sache *pptr() = c; 19821308Sache pbump(1); 19947558Sache 20075406Sache } 20147558Sache 20221308Sache return 0; 20375406Sache 20421308Sache} 20521308Sache 20621308Sacheint gzfilebuf::sync() { 20721308Sache 20821308Sache if ( !is_open() ) 20921308Sache return EOF; 21021308Sache 21121308Sache if ( out_waiting() ) 21221308Sache return flushbuf(); 21321308Sache 21475406Sache return 0; 21575406Sache 21621308Sache} 21721308Sache 21821308Sacheint gzfilebuf::flushbuf() { 219119610Sache 22021308Sache int n; 22121308Sache char *q; 22221308Sache 22321308Sache q = pbase(); 22421308Sache n = pptr() - q; 22521308Sache 22621308Sache if ( gzwrite( file, q, n) < n ) 22721308Sache return EOF; 22821308Sache 22947558Sache setp(0,0); 23021308Sache 23121308Sache return 0; 232119610Sache 23321308Sache} 23421308Sache 23521308Sacheint gzfilebuf::fillbuf() { 23621308Sache 23721308Sache int required; 23821308Sache char *p; 23921308Sache 24021308Sache p = base(); 24121308Sache 24221308Sache required = blen(); 24321308Sache 24421308Sache int t = gzread( file, p, required ); 24521308Sache 24621308Sache if ( t <= 0) return EOF; 24721308Sache 24821308Sache setg( base(), base(), base()+t); 24975406Sache 25021308Sache return t; 25121308Sache 25275406Sache} 25321308Sache 25475406Sachegzfilestream_common::gzfilestream_common() : 25521308Sache ios( gzfilestream_common::rdbuf() ) 256119610Sache{ } 257119610Sache 258119610Sachegzfilestream_common::~gzfilestream_common() 259119610Sache{ } 260119610Sache 261119610Sachevoid gzfilestream_common::attach( int fd, int io_mode ) { 262119610Sache 26321308Sache if ( !buffer.attach( fd, io_mode) ) 26421308Sache clear( ios::failbit | ios::badbit ); 26521308Sache else 26621308Sache clear(); 26721308Sache 26821308Sache} 26921308Sache 270119610Sachevoid gzfilestream_common::open( const char *name, int io_mode ) { 271119610Sache 272119610Sache if ( !buffer.open( name, io_mode ) ) 273119610Sache clear( ios::failbit | ios::badbit ); 274119610Sache else 275119610Sache clear(); 276119610Sache 277119610Sache} 27821308Sache 27921308Sachevoid gzfilestream_common::close() { 28047558Sache 28147558Sache if ( !buffer.close() ) 28247558Sache clear( ios::failbit | ios::badbit ); 28347558Sache 28447558Sache} 28521308Sache 28621308Sachegzfilebuf *gzfilestream_common::rdbuf() 28721308Sache{ 28821308Sache return &buffer; 28921308Sache} 29021308Sache 291119610Sachegzifstream::gzifstream() : 292119610Sache ios( gzfilestream_common::rdbuf() ) 293119610Sache{ 294119610Sache clear( ios::badbit ); 295119610Sache} 29621308Sache 29721308Sachegzifstream::gzifstream( const char *name, int io_mode ) : 29821308Sache ios( gzfilestream_common::rdbuf() ) 29921308Sache{ 300119610Sache gzfilestream_common::open( name, io_mode ); 301119610Sache} 302119610Sache 303119610Sachegzifstream::gzifstream( int fd, int io_mode ) : 304119610Sache ios( gzfilestream_common::rdbuf() ) 30521308Sache{ 306119610Sache gzfilestream_common::attach( fd, io_mode ); 307119610Sache} 308119610Sache 309119610Sachegzifstream::~gzifstream() { } 310119610Sache 311119610Sachegzofstream::gzofstream() : 312119610Sache ios( gzfilestream_common::rdbuf() ) 313119610Sache{ 314119610Sache clear( ios::badbit ); 315119610Sache} 316119610Sache 317119610Sachegzofstream::gzofstream( const char *name, int io_mode ) : 31875406Sache ios( gzfilestream_common::rdbuf() ) 31975406Sache{ 32021308Sache gzfilestream_common::open( name, io_mode ); 32121308Sache} 32221308Sache 32321308Sachegzofstream::gzofstream( int fd, int io_mode ) : 32421308Sache ios( gzfilestream_common::rdbuf() ) 32521308Sache{ 32621308Sache gzfilestream_common::attach( fd, io_mode ); 32721308Sache} 328119610Sache 329119610Sachegzofstream::~gzofstream() { } 330119610Sache