]> git.mxchange.org Git - simgear.git/blobdiff - Misc/zfstream.cxx
Tweak for SGI portability.
[simgear.git] / Misc / zfstream.cxx
index 3a52ea31d3ab89405005b7d42f359d366a3df200..759df91d87140a86a2e0f3f00766f7aab1b2c2a1 100644 (file)
+//  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.
+//