+// A C++ I/O streams interface to the zlib gz* functions
+//
+// Written by Bernie Bright, 1998
+// Based on zlib/contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+//
+// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+// (Log is kept at end of this file)
#include <memory.h>
-#include "Misc/zfstream.hxx"
-
-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;
- memset(char_mode,'\0',10);
- 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';
- }
-
- 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;
- memset(char_mode,'\0',10);
- 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';
- }
-
- if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
- return NULL;
-
- own_file_descriptor = 0;
-
- return this;
-
+#include "zfstream.hxx"
+
+const int gzfilebuf::page_size;
+
+//
+// Construct a gzfilebuf object.
+// Allocate memory for 'get' buffer and zero all buffer pointers.
+//
+gzfilebuf::gzfilebuf()
+ : streambuf(),
+ file(NULL),
+ mode(0),
+ own_file_descriptor(false),
+ ibuf_size(0),
+ ibuffer(0)
+{
+// try {
+ ibuf_size = page_size / sizeof(char);
+ ibuffer = new char [ibuf_size];
+// } catch (...) {
+// delete [] ibuffer;
+// }
+
+ // Null get and set pointers.
+ this->setg(0,0,0);
+ this->setp(0,0);
}
-gzfilebuf *gzfilebuf::close() {
-
- if ( is_open() ) {
-
+gzfilebuf::~gzfilebuf()
+{
sync();
- gzclose( file );
- file = NULL;
-
- }
-
- return this;
-
+ if ( own_file_descriptor )
+ this->close();
+ delete [] ibuffer;
}
-int gzfilebuf::setcompressionlevel( short comp_level ) {
-
- return gzsetparams(file, comp_level, -2);
+void
+gzfilebuf::cvt_iomode( char* p, ios_openmode io_mode )
+{
+// memset( char_mode, '\0', 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';
+ }
-int gzfilebuf::setcompressionstrategy( short comp_strategy ) {
+ if ( io_mode & ios_binary )
+ {
+ mode |= ios_binary;
+ *p++ = 'b';
+ }
- return gzsetparams(file, -2, comp_strategy);
+ // Hard code the compression level
+ if ( io_mode & (ios_out | ios_app) )
+ {
+ *p++ = '9';
+ }
+ *p = '\0';
}
+gzfilebuf*
+gzfilebuf::open( const char *name, ios_openmode io_mode )
+{
+ if ( is_open() )
+ return NULL;
-streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
+ char char_mode[10];
+ cvt_iomode( char_mode, io_mode );
+ if ( (file = gzopen(name, char_mode)) == NULL )
+ return NULL;
- return streampos(EOF);
+ own_file_descriptor = true;
+ return this;
}
-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() ) {
+gzfilebuf*
+gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
+{
+ if ( is_open() )
+ return NULL;
- if ( (allocate()) == EOF )
- return EOF;
- setp(0,0);
+ char char_mode[10];
+ cvt_iomode( char_mode, io_mode );
+ if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
+ return NULL;
- } else {
+ own_file_descriptor = false;
- if ( in_avail() )
- return (unsigned char) *gptr();
+ return this;
+}
- if ( out_waiting() ) {
- if ( flushbuf() == EOF )
- return EOF;
+gzfilebuf*
+gzfilebuf::close()
+{
+ if ( is_open() )
+ {
+ sync();
+ gzclose( file );
+ file = NULL;
}
- }
+ return this;
+}
- // Attempt to fill the buffer.
+// int
+// gzfilebuf::setcompressionlevel( int comp_level )
+// {
+// return gzsetparams(file, comp_level, -2);
+// }
- int result = fillbuf();
- if ( result == EOF ) {
- // disable get area
- setg(0,0,0);
- return EOF;
- }
+// int
+// gzfilebuf::setcompressionstrategy( int comp_strategy )
+// {
+// return gzsetparams(file, -2, comp_strategy);
+// }
- return (unsigned char) *gptr();
+streampos
+gzfilebuf::seekoff( streamoff, ios_seekdir, int )
+{
+ return streampos(EOF);
}
-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()) {
+gzfilebuf::int_type
+gzfilebuf::overflow( int_type )
+{
+#if 0
+ if ( !is_open() || !(mode & ios::out) )
return EOF;
+
+ if ( !base() )
+ {
+ if ( allocate() == EOF )
+ return EOF;
+ setg(0,0,0);
}
- if (out_waiting()) {
- if (flushbuf() == EOF)
- return EOF;
+ 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 bl = blen();
+ setp( base(), base() + bl);
+ if ( c != EOF )
+ {
+ *pptr() = c;
+ pbump(1);
+ }
+#endif
+ 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);
+int
+gzfilebuf::sync()
+{
+ if ( !is_open() )
+ return EOF;
- return 0;
+ if ( pptr() != 0 && pptr() > pbase() )
+ return flushbuf();
+ return 0;
}
-int gzfilebuf::fillbuf() {
-
- int required;
- char *p;
-
- p = base();
-
- required = blen();
-
- int t = gzread( file, p, required );
-
- if ( t <= 0) return EOF;
+gzfilebuf::int_type
+gzfilebuf::flushbuf()
+{
+ char* q = pbase();
+ int n = pptr() - q;
- setg( base(), base(), base()+t);
+ if ( gzwrite( file, q, n) < n )
+ return traits_type::eof();
- return t;
+ setp(0,0);
+ return 0;
}
-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();
-
+gzfilebuf::int_type
+gzfilebuf::underflow()
+{
+// cerr << "gzfilebuf::underflow(): gptr()=" << (void*)gptr() << endl;
+ // Error if the file not open for reading.
+ if ( !is_open() || !(mode & ios_in) )
+ return traits_type::eof();
+
+ // If the input buffer is empty then try to fill it.
+ if ( gptr() != 0 && gptr() < egptr() )
+ {
+ return int_type(*gptr());
+ }
+ else
+ {
+ return fillbuf() == EOF ? traits_type::eof() : int_type(*gptr());
+ }
}
-void gzfilestream_common::open( const char *name, int io_mode ) {
-
- if ( !buffer.open( name, io_mode ) )
- clear( ios::failbit | ios::badbit );
- else
- clear();
-
-}
+//
+// Load the input buffer from the underlying gz file.
+// Returns number of characters read, or EOF.
+//
+int
+gzfilebuf::fillbuf()
+{
+ int t = gzread( file, ibuffer, ibuf_size );
+ if ( t <= 0)
+ {
+ // disable get area
+ setg(0,0,0);
+ return EOF;
+ }
-void gzfilestream_common::close() {
+ // Set the input (get) pointers
+ setg( ibuffer, ibuffer, ibuffer+t );
- if ( !buffer.close() )
- clear( ios::failbit | ios::badbit );
+// cerr << "gzfilebuf::fillbuf():"
+// << " t=" << t
+// << ", ibuffer=" << (void*)ibuffer
+// << ", ibuffer+t=" << (void*)(ibuffer+t) << endl;
+ return t;
}
-gzfilebuf *gzfilestream_common::rdbuf() {
-
- return &buffer;
-
-}
-
-gzifstream::gzifstream() :
- ios( gzfilestream_common::rdbuf() )
+#if 0
+gzifstream::gzifstream()
+ : istream(&buffer), buffer()
{
- clear( ios::badbit );
+ clear( ios_badbit );
}
-gzifstream::gzifstream( const char *name, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
+gzifstream::gzifstream( const char *name, ios_openmode io_mode )
+ : istream(&buffer), buffer()
{
- gzfilestream_common::open( name, io_mode );
+ this->open( name, io_mode );
}
-gzifstream::gzifstream( int fd, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
+gzifstream::gzifstream( int fd, ios_openmode io_mode )
+ : istream(&buffer), buffer()
{
- gzfilestream_common::attach( fd, io_mode );
+ buffer.attach( fd, io_mode );
}
-gzifstream::~gzifstream() { }
-
-gzofstream::gzofstream() :
- ios( gzfilestream_common::rdbuf() )
+gzifstream::~gzifstream()
{
- clear( ios::badbit );
}
-gzofstream::gzofstream( const char *name, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
+void
+gzifstream::open( const char *name, ios_openmode io_mode )
{
- gzfilestream_common::open( name, io_mode );
+ if ( !buffer.open( name, io_mode ) )
+ clear( ios_failbit | ios_badbit );
+ else
+ clear();
}
-gzofstream::gzofstream( int fd, int io_mode ) :
- ios( gzfilestream_common::rdbuf() )
+void
+gzifstream::close()
{
- gzfilestream_common::attach( fd, io_mode );
+ if ( !buffer.close() )
+ clear( ios_failbit | ios_badbit );
}
+#endif
-gzofstream::~gzofstream() { }
+// $Log$
+// Revision 1.2 1998/11/06 14:05:14 curt
+// More portability improvements by Bernie Bright.
+//