zfstream.cxx

00001 //  A C++ I/O streams interface to the zlib gz* functions
00002 //
00003 // Written by Bernie Bright, 1998
00004 // Based on zlib/contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
00005 //
00006 // Copyright (C) 1998  Bernie Bright - bbright@c031.aone.net.au
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the Free Software
00020 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00021 //
00022 // $Id: zfstream_8cxx-source.html,v 1.15 2007-12-17 15:37:17 curt Exp $
00023 
00024 #include <simgear/compiler.h>
00025 
00026 #ifdef SG_HAVE_STD_INCLUDES
00027 # include <cerrno>
00028 #else
00029 # include <errno.h>
00030 #endif
00031 #include <memory.h>
00032 #include <stdio.h>
00033 
00034 #include "zfstream.hxx"
00035 
00036 //
00037 // Construct a gzfilebuf object.
00038 // Allocate memory for 'get' buffer and zero all buffer pointers.
00039 //
00040 gzfilebuf::gzfilebuf()
00041     : streambuf(),
00042       file(NULL),
00043 #if defined( __MWERKS__ ) || __GNUC__ > 2
00044       mode(ios_openmode(0)),
00045 #else
00046       mode(0),
00047 #endif
00048       own_file_descriptor(false),
00049       ibuf_size(0),
00050       ibuffer(0)
00051 {
00052 //     try {
00053     ibuf_size = page_size / sizeof(char);
00054     ibuffer = new char [ibuf_size];
00055 //     } catch (...) {
00056 //      delete [] ibuffer;
00057 //     }
00058 
00059     // Null get and set pointers.
00060     this->setg(0,0,0);
00061     this->setp(0,0);
00062 }
00063 
00064 gzfilebuf::~gzfilebuf()
00065 {
00066     sync();
00067     if ( own_file_descriptor )
00068         this->close();
00069     delete [] ibuffer;
00070 }
00071 
00072 void
00073 gzfilebuf::cvt_iomode( char* p, ios_openmode io_mode )
00074 {
00075 //     memset( char_mode, '\0', 10 );
00076 //     char* p = char_mode;
00077 
00078     if ( io_mode & ios_in )
00079     {
00080         mode = ios_in;
00081         *p++ = 'r';
00082     }
00083     else if ( io_mode & ios_app )
00084     {
00085         mode = ios_app;
00086         *p++ = 'a';
00087     }
00088     else
00089     {
00090         mode = ios_out;
00091         *p++ = 'w';
00092     }
00093 
00094     if ( io_mode & ios_binary )
00095     {
00096         mode |= ios_binary;
00097         *p++ = 'b';
00098     }
00099 
00100     // Hard code the compression level
00101     if ( io_mode & (ios_out | ios_app) )
00102     {
00103         *p++ = '9';
00104     }
00105 
00106     *p = '\0';
00107 }
00108 
00109 gzfilebuf*
00110 gzfilebuf::open( const char *name, ios_openmode io_mode )
00111 {
00112     if ( is_open() )
00113         return NULL;
00114 
00115     char char_mode[10];
00116     cvt_iomode( char_mode, io_mode );
00117     if ( (file = gzopen(name, char_mode)) == NULL ) {
00118         // perror( "gzfilebuf::open(): " );
00119         errno = 0;
00120         return NULL;
00121     }
00122 
00123     own_file_descriptor = true;
00124 
00125     return this;
00126 }
00127 
00128 gzfilebuf*
00129 gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
00130 {
00131     if ( is_open() )
00132         return NULL;
00133 
00134     char char_mode[10];
00135     cvt_iomode( char_mode, io_mode );
00136     if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) {
00137         perror( "gzfilebuf::attach(): " );
00138         errno = 0;
00139         return NULL;
00140     }
00141 
00142     own_file_descriptor = false;
00143 
00144     return this;
00145 }
00146 
00147 gzfilebuf*
00148 gzfilebuf::close()
00149 {
00150     // cout << "closing ..." ;
00151     if ( is_open() )
00152     {
00153         sync();
00154         gzclose( file );
00155         file = NULL;
00156         // cout << "done" << endl;
00157     } else {
00158         // cout << "error" << endl;
00159     }
00160 
00161     return this;
00162 }
00163 
00164 // int
00165 // gzfilebuf::setcompressionlevel( int comp_level )
00166 // {
00167 //     return gzsetparams(file, comp_level, -2);
00168 // }
00169 
00170 // int
00171 // gzfilebuf::setcompressionstrategy( int comp_strategy )
00172 // {
00173 //     return gzsetparams(file, -2, comp_strategy);
00174 // }
00175 
00176 
00177 streampos
00178 gzfilebuf::seekoff( streamoff, ios_seekdir, int )
00179 {
00180     return streampos(EOF);
00181 }
00182 
00183 gzfilebuf::int_type
00184 gzfilebuf::overflow( int_type )
00185 {
00186 #if 0
00187     if ( !is_open() || !(mode & ios::out) )
00188         return EOF;
00189 
00190     if ( !base() )
00191     {
00192         if ( allocate() == EOF )
00193             return EOF;
00194         setg(0,0,0);
00195     }
00196     else
00197     {
00198         if (in_avail())
00199         {
00200             return EOF;
00201         }
00202 
00203         if (out_waiting())
00204         {
00205             if (flushbuf() == EOF)
00206                 return EOF;
00207         }
00208     }
00209 
00210     int bl = blen();
00211     setp( base(), base() + bl);
00212 
00213     if ( c != EOF )
00214     {
00215         *pptr() = c;
00216         pbump(1);
00217     }
00218 #endif
00219     return 0;
00220 }
00221 
00222 int
00223 gzfilebuf::sync()
00224 {
00225     if ( !is_open() )
00226         return EOF;
00227 
00228     if ( pptr() != 0 && pptr() > pbase() )
00229         return flushbuf();
00230 
00231     return 0;
00232 }
00233 
00234 gzfilebuf::int_type
00235 gzfilebuf::flushbuf()
00236 {
00237     char* q = pbase();
00238     int n = pptr() - q;
00239 
00240     if ( gzwrite( file, q, n) < n )
00241         return traits_type::eof();
00242 
00243     setp(0,0);
00244 
00245     return 0;
00246 }
00247 
00248 gzfilebuf::int_type
00249 gzfilebuf::underflow()
00250 {
00251 //     cerr << "gzfilebuf::underflow(): gptr()=" << (void*)gptr() << endl;
00252     // Error if the file not open for reading.
00253     if ( !is_open() || !(mode & ios_in) )
00254         return traits_type::eof();
00255 
00256     // If the input buffer is empty then try to fill it.
00257     if ( gptr() != 0 && gptr() < egptr() )
00258     {
00259         return int_type(*gptr());
00260     }
00261     else
00262     {
00263         return fillbuf() == EOF ? traits_type::eof() : int_type(*gptr());
00264     }
00265 }
00266 
00267 //
00268 // Load the input buffer from the underlying gz file.
00269 // Returns number of characters read, or EOF.
00270 //
00271 int
00272 gzfilebuf::fillbuf()
00273 {
00274     int t = gzread( file, ibuffer, ibuf_size );
00275     if ( t <= 0)
00276     {
00277         // disable get area
00278         setg(0,0,0);
00279         return EOF;
00280     }
00281 
00282     // Set the input (get) pointers
00283     setg( ibuffer, ibuffer, ibuffer+t );
00284 
00285 //     cerr << "gzfilebuf::fillbuf():"
00286 //       << " t=" << t
00287 //       << ", ibuffer=" << (void*)ibuffer
00288 //       << ", ibuffer+t=" << (void*)(ibuffer+t) << endl;
00289 
00290     return t;
00291 }
00292 
00293 #if 0
00294 gzifstream::gzifstream()
00295     : istream(&buffer), buffer()
00296 {
00297     clear( ios_badbit );
00298 }
00299 
00300 gzifstream::gzifstream( const char *name, ios_openmode io_mode )
00301     : istream(&buffer), buffer()
00302 {
00303     this->open( name, io_mode );
00304 }
00305 
00306 gzifstream::gzifstream( int fd, ios_openmode io_mode )
00307     : istream(&buffer), buffer()
00308 {
00309     buffer.attach( fd, io_mode );
00310 }
00311 
00312 gzifstream::~gzifstream()
00313 {
00314 }
00315 
00316 void
00317 gzifstream::open( const char *name, ios_openmode io_mode )
00318 {
00319     if ( !buffer.open( name, io_mode ) )
00320         clear( ios_failbit | ios_badbit );
00321     else
00322         clear();
00323 }
00324 
00325 void
00326 gzifstream::close()
00327 {
00328     if ( !buffer.close() )
00329         clear( ios_failbit | ios_badbit );
00330 }
00331 #endif
00332 

Generated on Mon Dec 17 09:30:56 2007 for SimGear by  doxygen 1.5.1