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