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