330 lines
		
	
	
		
			5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			330 lines
		
	
	
		
			5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#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() { }
							 |