More portability improvements by Bernie Bright.

This commit is contained in:
curt 1998-11-06 14:05:12 +00:00
parent 3e63d6ca5d
commit 6766825159
4 changed files with 433 additions and 459 deletions

View File

@ -22,24 +22,31 @@
// (Log is kept at end of this file)
#include <ctype.h> // isspace()
#include "fgstream.hxx"
#include <Misc/fgstream.hxx>
fg_gzifstream::fg_gzifstream()
: istream(&gzbuf)
{
}
//-----------------------------------------------------------------------------
//
// Open a possibly gzipped file for reading.
//
fg_gzifstream::fg_gzifstream( const string& name, int io_mode )
fg_gzifstream::fg_gzifstream( const string& name, ios_openmode io_mode )
: istream(&gzbuf)
{
open( name, io_mode );
this->open( name, io_mode );
}
//-----------------------------------------------------------------------------
//
// Attach a stream to an already opened file descriptor.
//
fg_gzifstream::fg_gzifstream( int fd, int io_mode )
: gzstream( fd, io_mode )
fg_gzifstream::fg_gzifstream( int fd, ios_openmode io_mode )
: istream(&gzbuf)
{
gzbuf.attach( fd, io_mode );
}
//-----------------------------------------------------------------------------
@ -51,10 +58,10 @@ fg_gzifstream::fg_gzifstream( int fd, int io_mode )
// then append ".gz" and try again.
//
void
fg_gzifstream::open( const string& name, int io_mode )
fg_gzifstream::open( const string& name, ios_openmode io_mode )
{
gzstream.open( name.c_str(), io_mode );
if ( gzstream.fail() )
gzbuf.open( name.c_str(), io_mode );
if ( ! gzbuf.is_open() )
{
string s = name;
if ( s.substr( s.length() - 3, 3 ) == ".gz" )
@ -70,56 +77,14 @@ fg_gzifstream::open( const string& name, int io_mode )
}
// Try again.
gzstream.open( s.c_str(), io_mode );
gzbuf.open( s.c_str(), io_mode );
}
}
//-----------------------------------------------------------------------------
//
// Remove whitespace characters from the stream.
//
istream&
fg_gzifstream::eat_whitespace()
void
fg_gzifstream::attach( int fd, ios_openmode io_mode )
{
char c;
while ( gzstream.get(c) )
{
if ( ! isspace( c ) )
{
// put pack the non-space character
gzstream.putback(c);
break;
}
}
return gzstream;
}
//-----------------------------------------------------------------------------
//
// Remove whitspace chatacters and comment lines from a stream.
//
istream&
fg_gzifstream::eat_comments()
{
for (;;)
{
// skip whitespace
eat_whitespace();
char c;
gzstream.get( c );
if ( c != '#' )
{
// not a comment
gzstream.putback(c);
break;
}
// skip to end of line.
while ( gzstream.get(c) && (c != '\n' && c != '\r') )
;
}
return gzstream;
gzbuf.attach( fd, io_mode );
}
//
@ -175,6 +140,9 @@ skipcomment( istream& in )
}
// $Log$
// Revision 1.3 1998/11/06 14:05:12 curt
// More portability improvements by Bernie Bright.
//
// Revision 1.2 1998/09/24 15:22:17 curt
// Additional enhancements.
//

View File

@ -29,21 +29,31 @@
#endif
#ifdef HAVE_CONFIG_H
# include "config.h"
# include "Include/config.h"
#endif
#include <string>
#include "Include/fg_stl_config.h"
FG_USING_NAMESPACE(std);
#include "Include/compiler.h"
FG_USING_STD(string);
// #ifdef FG_HAVE_STD_INCLUDES
// #include <istream>
// #else
// #include <istream.h>
// #endif
#include "zfstream.hxx"
// Input stream manipulator function type.
class fg_gzifstream;
typedef fg_gzifstream& (*IManipFunc)( fg_gzifstream& );
//-----------------------------------------------------------------------------
//
// Envelope class for gzifstream.
//
class fg_gzifstream
class fg_gzifstream : private gzifstream_base, public istream
{
public:
//
@ -51,45 +61,21 @@ public:
// Attempt to open a file with and without ".gz" extension.
fg_gzifstream( const string& name,
int io_mode = ios::in|ios::binary );
ios_openmode io_mode = ios_in | ios_binary );
//
fg_gzifstream( int fd, int io_mode = ios::in|ios::binary );
fg_gzifstream( int fd, ios_openmode io_mode = ios_in|ios_binary );
// Attempt to open a file with and without ".gz" extension.
void open( const string& name,
int io_mode = ios::in|ios::binary );
ios_openmode io_mode = ios_in|ios_binary );
// Return the underlying stream.
istream& stream() { return gzstream; }
// Check stream state.
bool operator ! () const { return !gzstream; }
// Check for end of file.
bool eof() const { return gzstream.eof(); }
// Remove whitespace from stream.
// Whitespace is as defined by isspace().
istream& eat_whitespace();
// Removes comments and whitespace from stream.
// A comment is any line starting with '#'.
istream& eat_comments();
// Read one character from stream.
istream& get( char& c ) { return gzstream.get(c); }
// Put a character back into the input buffer.
istream& putback( char c ) { return gzstream.putback(c); }
private:
// The underlying compressed data stream.
gzifstream gzstream;
void attach( int fd, ios_openmode io_mode = ios_in|ios_binary );
private:
// Not defined!
fg_gzifstream( const fg_gzifstream& );
void operator= ( const fg_gzifstream& );
};
// istream manipulator that skips to end of line.
@ -102,9 +88,13 @@ istream& skipws( istream& in );
// A comment starts with '#'.
istream& skipcomment( istream& in );
#endif /* _FGSTREAM_HXX */
// $Log$
// Revision 1.5 1998/11/06 14:05:13 curt
// More portability improvements by Bernie Bright.
//
// Revision 1.4 1998/10/16 00:50:56 curt
// Remove leading _ from a couple defines.
//

View File

@ -1,329 +1,316 @@
// 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"
#include "zfstream.hxx"
gzfilebuf::gzfilebuf() :
file(NULL),
mode(0),
own_file_descriptor(0)
{ }
const int gzfilebuf::page_size;
gzfilebuf::~gzfilebuf() {
sync();
if ( own_file_descriptor )
close();
//
// 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::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;
}
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 ) {
void
gzfilebuf::cvt_iomode( char* p, ios_openmode io_mode )
{
// memset( char_mode, '\0', 10 );
// char* p = char_mode;
return gzsetparams(file, comp_level, -2);
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';
}
*p = '\0';
}
int gzfilebuf::setcompressionstrategy( short comp_strategy ) {
gzfilebuf*
gzfilebuf::open( const char *name, ios_openmode io_mode )
{
if ( is_open() )
return NULL;
return gzsetparams(file, -2, comp_strategy);
char char_mode[10];
cvt_iomode( char_mode, io_mode );
if ( (file = gzopen(name, char_mode)) == NULL )
return NULL;
own_file_descriptor = true;
return this;
}
gzfilebuf*
gzfilebuf::attach( int file_descriptor, 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 = gzdopen(file_descriptor, char_mode)) == NULL )
return NULL;
return streampos(EOF);
own_file_descriptor = false;
return this;
}
int gzfilebuf::underflow() {
gzfilebuf*
gzfilebuf::close()
{
if ( is_open() )
{
sync();
gzclose( file );
file = NULL;
}
// If the file hasn't been opened for reading, error.
if ( !is_open() || !(mode & ios::in) )
return EOF;
return this;
}
// if a buffer doesn't exists, allocate one.
if ( !base() ) {
// 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, ios_seekdir, int )
{
return streampos(EOF);
}
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);
}
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);
}
#endif
return 0;
}
int
gzfilebuf::sync()
{
if ( !is_open() )
return EOF;
if ( pptr() != 0 && pptr() > pbase() )
return flushbuf();
return 0;
}
gzfilebuf::int_type
gzfilebuf::flushbuf()
{
char* q = pbase();
int n = pptr() - q;
if ( gzwrite( file, q, n) < n )
return traits_type::eof();
if ( (allocate()) == EOF )
return EOF;
setp(0,0);
} else {
return 0;
}
if ( in_avail() )
return (unsigned char) *gptr();
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 ( out_waiting() ) {
if ( flushbuf() == 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());
}
}
//
// 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;
}
}
// Set the input (get) pointers
setg( ibuffer, ibuffer, ibuffer+t );
// Attempt to fill the buffer.
int result = fillbuf();
if ( result == EOF ) {
// disable get area
setg(0,0,0);
return EOF;
}
return (unsigned char) *gptr();
// cerr << "gzfilebuf::fillbuf():"
// << " t=" << t
// << ", ibuffer=" << (void*)ibuffer
// << ", ibuffer+t=" << (void*)(ibuffer+t) << endl;
return t;
}
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() )
#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.
//

View File

@ -1,130 +1,159 @@
// 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)
#ifndef _zfstream_hxx
#define _zfstream_hxx
#include <fstream.h>
#include "zlib/zlib.h"
#include "Include/fg_stl_config.h"
#include "Include/compiler.h"
class gzfilebuf : public streambuf {
#ifdef FG_HAVE_STD_INCLUDES
# include <streambuf>
# include <istream>
# define ios_openmode ios_base::openmode
# define ios_in ios_base::in
# define ios_out ios_base::out
# define ios_app ios_base::app
# define ios_binary ios_base::binary
# define ios_seekdir ios_base::seekdir
# define ios_badbit ios_base::badbit
# define ios_failbit ios_base::failbit
#else
# ifdef FG_HAVE_STREAMBUF
# include <streambuf.h>
# include <istream.h>
# else
# include <iostream.h>
# endif
//# define ios_openmode ios::open_mode
# define ios_openmode int
# define ios_in ios::in
# define ios_out ios::out
# define ios_app ios::app
# define ios_binary ios::binary
# define ios_seekdir ios::seek_dir
# define ios_badbit ios::badbit
# define ios_failbit ios::failbit
// Dummy up some char traits for now.
template<class charT> struct char_traits{};
FG_TEMPLATE_NULL
struct char_traits<char>
{
typedef char char_type;
typedef int int_type;
typedef streampos pos_type;
typedef streamoff off_type;
static int_type eof() { return EOF; }
};
#endif // FG_HAVE_STD_INCLUDES
//-----------------------------------------------------------------------------
//
//
//
class gzfilebuf : public streambuf
{
public:
gzfilebuf( );
virtual ~gzfilebuf();
#ifndef FG_HAVE_STD_INCLUDES
typedef char_traits<char> traits_type;
typedef char_traits<char>::int_type int_type;
typedef char_traits<char>::pos_type pos_type;
typedef char_traits<char>::off_type off_type;
#endif
gzfilebuf *open( const char *name, int io_mode );
gzfilebuf *attach( int file_descriptor, int io_mode );
gzfilebuf *close();
gzfilebuf();
virtual ~gzfilebuf();
int setcompressionlevel( short comp_level );
int setcompressionstrategy( short comp_strategy );
gzfilebuf* open( const char* name, ios_openmode io_mode );
gzfilebuf* attach( int file_descriptor, ios_openmode io_mode );
gzfilebuf* close();
inline int is_open() const { return (file !=NULL); }
virtual streampos seekoff( streamoff, ios::seek_dir, int );
virtual int sync();
// int setcompressionlevel( int comp_level );
// int setcompressionstrategy( int comp_strategy );
bool is_open() const { return (file != NULL); }
virtual streampos seekoff( streamoff off, ios_seekdir way, int which );
virtual int sync();
protected:
virtual int underflow();
virtual int overflow( int = EOF );
virtual int_type underflow();
virtual int_type overflow( int_type c = traits_type::eof() );
private:
gzFile file;
short mode;
short own_file_descriptor;
int_type flushbuf();
int fillbuf();
int flushbuf();
int fillbuf();
};
class gzfilestream_common : virtual public ios {
// friend class gzifstream;
friend class gzofstream;
friend gzofstream &setcompressionlevel( gzofstream &, int );
friend gzofstream &setcompressionstrategy( gzofstream &, int );
public:
virtual ~gzfilestream_common();
void attach( int fd, int io_mode );
void open( const char *name, int io_mode );
void close();
protected:
gzfilestream_common();
gzfilebuf *rdbuf();
// Convert io_mode to "rwab" string.
void cvt_iomode( char* mode_str, ios_openmode io_mode );
private:
gzfilebuf buffer;
gzFile file;
ios_openmode mode;
bool own_file_descriptor;
};
// Get (input) buffer.
int ibuf_size;
char* ibuffer;
class gzifstream : public gzfilestream_common, public istream {
static const int page_size = 4096;
public:
gzifstream();
gzifstream( const char *name, int io_mode = ios::in );
gzifstream( int fd, int io_mode = ios::in );
virtual ~gzifstream();
};
class gzofstream : public gzfilestream_common, public ostream {
public:
gzofstream();
gzofstream( const char *name, int io_mode = ios::out );
gzofstream( int fd, int io_mode = ios::out );
virtual ~gzofstream();
};
template<class T> class gzomanip {
friend gzofstream &operator << FG_NULL_TMPL_ARGS (gzofstream &, const gzomanip<T> &);
public:
gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { }
private:
gzofstream &(*func)(gzofstream &, T);
T val;
// Not defined
gzfilebuf( const gzfilebuf& );
void operator= ( const gzfilebuf& );
};
template<class T> gzofstream &operator<<(gzofstream &s,
const gzomanip<T> &m) {
return (*m.func)(s, m.val);
}
inline gzofstream &setcompressionlevel( gzofstream &s, int l ) {
(s.rdbuf())->setcompressionlevel(l);
return s;
}
inline gzofstream &setcompressionstrategy( gzofstream &s, int l ) {
(s.rdbuf())->setcompressionstrategy(l);
return s;
}
inline gzomanip<int> setcompressionlevel(int l)
//-----------------------------------------------------------------------------
//
//
//
struct gzifstream_base
{
return gzomanip<int>( /* & */ setcompressionlevel,l); // & superfluous
}
gzifstream_base() {}
inline gzomanip<int> setcompressionstrategy(int l)
{
return gzomanip<int>( /* & */ setcompressionstrategy,l); // & superfluous
}
gzfilebuf gzbuf;
};
#endif // _zfstream_hxx
// $Log$
// Revision 1.4 1998/11/06 14:05:16 curt
// More portability improvements by Bernie Bright.
//