1 // A C++ I/O streams interface to the zlib gz* functions
3 // Written by Bernie Bright, 1998
4 // Based on zlib/contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
6 // Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include <simgear/compiler.h>
30 #include "zfstream.hxx"
33 // Construct a gzfilebuf object.
34 // Allocate memory for 'get' buffer and zero all buffer pointers.
36 gzfilebuf::gzfilebuf()
39 mode(ios_openmode(0)),
40 own_file_descriptor(false),
47 ibuf_size = page_size / sizeof(char);
48 ibuffer = new char [ibuf_size];
53 // Null get and set pointers.
58 gzfilebuf::~gzfilebuf()
61 if ( own_file_descriptor )
69 gzfilebuf::cvt_iomode( char* p, ios_openmode io_mode )
71 // memset( char_mode, '\0', 10 );
72 // char* p = char_mode;
74 if ( io_mode & ios_in )
79 else if ( io_mode & ios_app )
90 if ( io_mode & ios_binary )
96 // Hard code the compression level
97 if ( io_mode & (ios_out | ios_app) )
106 gzfilebuf::open( const char *name, ios_openmode io_mode )
112 cvt_iomode( char_mode, io_mode );
113 if ( (file = gzopen(name, char_mode)) == NULL ) {
114 // perror( "gzfilebuf::open(): " );
119 own_file_descriptor = true;
125 gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
131 cvt_iomode( char_mode, io_mode );
132 if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) {
133 perror( "gzfilebuf::attach(): " );
138 own_file_descriptor = false;
146 // cout << "closing ..." ;
152 // cout << "done" << endl;
154 // cout << "error" << endl;
161 gzfilebuf::setcompressionlevel( int comp_level )
163 return gzsetparams(file, comp_level, -2);
167 gzfilebuf::setcompressionstrategy( int comp_strategy )
169 return gzsetparams(file, -2, comp_strategy);
174 gzfilebuf::seekoff( std::streamoff, ios_seekdir, ios_openmode )
176 return std::streampos(EOF);
180 gzfilebuf::overflow( int_type c )
182 if ( !is_open() || !(mode & ios_out) )
187 if ( allocate() == EOF )
200 if (flushbuf() == EOF)
206 setp( base(), base() + bl);
222 if ( pptr() != 0 && pptr() > pbase() )
229 gzfilebuf::out_waiting()
237 gzfilebuf::allocate()
239 obuf_size = page_size / sizeof(char);
240 obuffer = new char [obuf_size];
245 gzfilebuf::flushbuf()
250 if ( gzwrite( file, q, n) < n )
251 return traits_type::eof();
259 gzfilebuf::underflow()
261 // cerr << "gzfilebuf::underflow(): gptr()=" << (void*)gptr() << endl;
262 // Error if the file not open for reading.
263 if ( !is_open() || !(mode & ios_in) )
264 return traits_type::eof();
266 // If the input buffer is empty then try to fill it.
267 if ( gptr() != 0 && gptr() < egptr() )
269 return int_type(*gptr());
273 return fillbuf() == EOF ? traits_type::eof() : (unsigned char) (*gptr());
278 // Load the input buffer from the underlying gz file.
279 // Returns number of characters read, or EOF.
284 int t = gzread( file, ibuffer, ibuf_size );
292 // Set the input (get) pointers
293 setg( ibuffer, ibuffer, ibuffer+t );
295 // cerr << "gzfilebuf::fillbuf():"
297 // << ", ibuffer=" << (void*)ibuffer
298 // << ", ibuffer+t=" << (void*)(ibuffer+t) << endl;
304 gzifstream::gzifstream()
305 : istream(&buffer), buffer()
310 gzifstream::gzifstream( const char *name, ios_openmode io_mode )
311 : istream(&buffer), buffer()
313 this->open( name, io_mode );
316 gzifstream::gzifstream( int fd, ios_openmode io_mode )
317 : istream(&buffer), buffer()
319 buffer.attach( fd, io_mode );
322 gzifstream::~gzifstream()
327 gzifstream::open( const char *name, ios_openmode io_mode )
329 if ( !buffer.open( name, io_mode ) )
330 clear( ios_failbit | ios_badbit );
338 if ( !buffer.close() )
339 clear( ios_failbit | ios_badbit );