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