Chris@4: Chris@4: #include "zfstream.h" Chris@4: Chris@4: gzfilebuf::gzfilebuf() : Chris@4: file(NULL), Chris@4: mode(0), Chris@4: own_file_descriptor(0) Chris@4: { } Chris@4: Chris@4: gzfilebuf::~gzfilebuf() { Chris@4: Chris@4: sync(); Chris@4: if ( own_file_descriptor ) Chris@4: close(); Chris@4: Chris@4: } Chris@4: Chris@4: gzfilebuf *gzfilebuf::open( const char *name, Chris@4: int io_mode ) { Chris@4: Chris@4: if ( is_open() ) Chris@4: return NULL; Chris@4: Chris@4: char char_mode[10]; Chris@4: char *p = char_mode; Chris@4: Chris@4: if ( io_mode & ios::in ) { Chris@4: mode = ios::in; Chris@4: *p++ = 'r'; Chris@4: } else if ( io_mode & ios::app ) { Chris@4: mode = ios::app; Chris@4: *p++ = 'a'; Chris@4: } else { Chris@4: mode = ios::out; Chris@4: *p++ = 'w'; Chris@4: } Chris@4: Chris@4: if ( io_mode & ios::binary ) { Chris@4: mode |= ios::binary; Chris@4: *p++ = 'b'; Chris@4: } Chris@4: Chris@4: // Hard code the compression level Chris@4: if ( io_mode & (ios::out|ios::app )) { Chris@4: *p++ = '9'; Chris@4: } Chris@4: Chris@4: // Put the end-of-string indicator Chris@4: *p = '\0'; Chris@4: Chris@4: if ( (file = gzopen(name, char_mode)) == NULL ) Chris@4: return NULL; Chris@4: Chris@4: own_file_descriptor = 1; Chris@4: Chris@4: return this; Chris@4: Chris@4: } Chris@4: Chris@4: gzfilebuf *gzfilebuf::attach( int file_descriptor, Chris@4: int io_mode ) { Chris@4: Chris@4: if ( is_open() ) Chris@4: return NULL; Chris@4: Chris@4: char char_mode[10]; Chris@4: char *p = char_mode; Chris@4: Chris@4: if ( io_mode & ios::in ) { Chris@4: mode = ios::in; Chris@4: *p++ = 'r'; Chris@4: } else if ( io_mode & ios::app ) { Chris@4: mode = ios::app; Chris@4: *p++ = 'a'; Chris@4: } else { Chris@4: mode = ios::out; Chris@4: *p++ = 'w'; Chris@4: } Chris@4: Chris@4: if ( io_mode & ios::binary ) { Chris@4: mode |= ios::binary; Chris@4: *p++ = 'b'; Chris@4: } Chris@4: Chris@4: // Hard code the compression level Chris@4: if ( io_mode & (ios::out|ios::app )) { Chris@4: *p++ = '9'; Chris@4: } Chris@4: Chris@4: // Put the end-of-string indicator Chris@4: *p = '\0'; Chris@4: Chris@4: if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) Chris@4: return NULL; Chris@4: Chris@4: own_file_descriptor = 0; Chris@4: Chris@4: return this; Chris@4: Chris@4: } Chris@4: Chris@4: gzfilebuf *gzfilebuf::close() { Chris@4: Chris@4: if ( is_open() ) { Chris@4: Chris@4: sync(); Chris@4: gzclose( file ); Chris@4: file = NULL; Chris@4: Chris@4: } Chris@4: Chris@4: return this; Chris@4: Chris@4: } Chris@4: Chris@4: int gzfilebuf::setcompressionlevel( int comp_level ) { Chris@4: Chris@4: return gzsetparams(file, comp_level, -2); Chris@4: Chris@4: } Chris@4: Chris@4: int gzfilebuf::setcompressionstrategy( int comp_strategy ) { Chris@4: Chris@4: return gzsetparams(file, -2, comp_strategy); Chris@4: Chris@4: } Chris@4: Chris@4: Chris@4: streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { Chris@4: Chris@4: return streampos(EOF); Chris@4: Chris@4: } Chris@4: Chris@4: int gzfilebuf::underflow() { Chris@4: Chris@4: // If the file hasn't been opened for reading, error. Chris@4: if ( !is_open() || !(mode & ios::in) ) Chris@4: return EOF; Chris@4: Chris@4: // if a buffer doesn't exists, allocate one. Chris@4: if ( !base() ) { Chris@4: Chris@4: if ( (allocate()) == EOF ) Chris@4: return EOF; Chris@4: setp(0,0); Chris@4: Chris@4: } else { Chris@4: Chris@4: if ( in_avail() ) Chris@4: return (unsigned char) *gptr(); Chris@4: Chris@4: if ( out_waiting() ) { Chris@4: if ( flushbuf() == EOF ) Chris@4: return EOF; Chris@4: } Chris@4: Chris@4: } Chris@4: Chris@4: // Attempt to fill the buffer. Chris@4: Chris@4: int result = fillbuf(); Chris@4: if ( result == EOF ) { Chris@4: // disable get area Chris@4: setg(0,0,0); Chris@4: return EOF; Chris@4: } Chris@4: Chris@4: return (unsigned char) *gptr(); Chris@4: Chris@4: } Chris@4: Chris@4: int gzfilebuf::overflow( int c ) { Chris@4: Chris@4: if ( !is_open() || !(mode & ios::out) ) Chris@4: return EOF; Chris@4: Chris@4: if ( !base() ) { Chris@4: if ( allocate() == EOF ) Chris@4: return EOF; Chris@4: setg(0,0,0); Chris@4: } else { Chris@4: if (in_avail()) { Chris@4: return EOF; Chris@4: } Chris@4: if (out_waiting()) { Chris@4: if (flushbuf() == EOF) Chris@4: return EOF; Chris@4: } Chris@4: } Chris@4: Chris@4: int bl = blen(); Chris@4: setp( base(), base() + bl); Chris@4: Chris@4: if ( c != EOF ) { Chris@4: Chris@4: *pptr() = c; Chris@4: pbump(1); Chris@4: Chris@4: } Chris@4: Chris@4: return 0; Chris@4: Chris@4: } Chris@4: Chris@4: int gzfilebuf::sync() { Chris@4: Chris@4: if ( !is_open() ) Chris@4: return EOF; Chris@4: Chris@4: if ( out_waiting() ) Chris@4: return flushbuf(); Chris@4: Chris@4: return 0; Chris@4: Chris@4: } Chris@4: Chris@4: int gzfilebuf::flushbuf() { Chris@4: Chris@4: int n; Chris@4: char *q; Chris@4: Chris@4: q = pbase(); Chris@4: n = pptr() - q; Chris@4: Chris@4: if ( gzwrite( file, q, n) < n ) Chris@4: return EOF; Chris@4: Chris@4: setp(0,0); Chris@4: Chris@4: return 0; Chris@4: Chris@4: } Chris@4: Chris@4: int gzfilebuf::fillbuf() { Chris@4: Chris@4: int required; Chris@4: char *p; Chris@4: Chris@4: p = base(); Chris@4: Chris@4: required = blen(); Chris@4: Chris@4: int t = gzread( file, p, required ); Chris@4: Chris@4: if ( t <= 0) return EOF; Chris@4: Chris@4: setg( base(), base(), base()+t); Chris@4: Chris@4: return t; Chris@4: Chris@4: } Chris@4: Chris@4: gzfilestream_common::gzfilestream_common() : Chris@4: ios( gzfilestream_common::rdbuf() ) Chris@4: { } Chris@4: Chris@4: gzfilestream_common::~gzfilestream_common() Chris@4: { } Chris@4: Chris@4: void gzfilestream_common::attach( int fd, int io_mode ) { Chris@4: Chris@4: if ( !buffer.attach( fd, io_mode) ) Chris@4: clear( ios::failbit | ios::badbit ); Chris@4: else Chris@4: clear(); Chris@4: Chris@4: } Chris@4: Chris@4: void gzfilestream_common::open( const char *name, int io_mode ) { Chris@4: Chris@4: if ( !buffer.open( name, io_mode ) ) Chris@4: clear( ios::failbit | ios::badbit ); Chris@4: else Chris@4: clear(); Chris@4: Chris@4: } Chris@4: Chris@4: void gzfilestream_common::close() { Chris@4: Chris@4: if ( !buffer.close() ) Chris@4: clear( ios::failbit | ios::badbit ); Chris@4: Chris@4: } Chris@4: Chris@4: gzfilebuf *gzfilestream_common::rdbuf() Chris@4: { Chris@4: return &buffer; Chris@4: } Chris@4: Chris@4: gzifstream::gzifstream() : Chris@4: ios( gzfilestream_common::rdbuf() ) Chris@4: { Chris@4: clear( ios::badbit ); Chris@4: } Chris@4: Chris@4: gzifstream::gzifstream( const char *name, int io_mode ) : Chris@4: ios( gzfilestream_common::rdbuf() ) Chris@4: { Chris@4: gzfilestream_common::open( name, io_mode ); Chris@4: } Chris@4: Chris@4: gzifstream::gzifstream( int fd, int io_mode ) : Chris@4: ios( gzfilestream_common::rdbuf() ) Chris@4: { Chris@4: gzfilestream_common::attach( fd, io_mode ); Chris@4: } Chris@4: Chris@4: gzifstream::~gzifstream() { } Chris@4: Chris@4: gzofstream::gzofstream() : Chris@4: ios( gzfilestream_common::rdbuf() ) Chris@4: { Chris@4: clear( ios::badbit ); Chris@4: } Chris@4: Chris@4: gzofstream::gzofstream( const char *name, int io_mode ) : Chris@4: ios( gzfilestream_common::rdbuf() ) Chris@4: { Chris@4: gzfilestream_common::open( name, io_mode ); Chris@4: } Chris@4: Chris@4: gzofstream::gzofstream( int fd, int io_mode ) : Chris@4: ios( gzfilestream_common::rdbuf() ) Chris@4: { Chris@4: gzfilestream_common::attach( fd, io_mode ); Chris@4: } Chris@4: Chris@4: gzofstream::~gzofstream() { }