]> git.mxchange.org Git - simgear.git/blob - simgear/misc/zfstream.cxx
Added a touch of error checking to the screen dump routine, i.e. don't
[simgear.git] / simgear / misc / zfstream.cxx
1 //  A C++ I/O streams interface to the zlib gz* functions
2 //
3 // Written by Bernie Bright, 1998
4 // Based on zlib/contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
5 //
6 // Copyright (C) 1998  Bernie Bright - bbright@c031.aone.net.au
7 //
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.
12 //
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.
17 //
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the
20 // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 // Boston, MA  02111-1307, USA.
22 //
23 // $Id$
24
25 #include <memory.h>
26 #include "zfstream.hxx"
27
28 //
29 // Construct a gzfilebuf object.
30 // Allocate memory for 'get' buffer and zero all buffer pointers.
31 //
32 gzfilebuf::gzfilebuf()
33     : streambuf(),
34       file(NULL),
35 #if defined( __MWERKS__ )
36       mode(ios_openmode(0)),
37 #else
38       mode(0),
39 #endif
40       own_file_descriptor(false),
41       ibuf_size(0),
42       ibuffer(0)
43 {
44 //     try {
45     ibuf_size = page_size / sizeof(char);
46     ibuffer = new char [ibuf_size];
47 //     } catch (...) {
48 //      delete [] ibuffer;
49 //     }
50
51     // Null get and set pointers.
52     this->setg(0,0,0);
53     this->setp(0,0);
54 }
55
56 gzfilebuf::~gzfilebuf()
57 {
58     sync();
59     if ( own_file_descriptor )
60         this->close();
61     delete [] ibuffer;
62 }
63
64 void
65 gzfilebuf::cvt_iomode( char* p, ios_openmode io_mode )
66 {
67 //     memset( char_mode, '\0', 10 );
68 //     char* p = char_mode;
69
70     if ( io_mode & ios_in )
71     {
72         mode = ios_in;
73         *p++ = 'r';
74     }
75     else if ( io_mode & ios_app )
76     {
77         mode = ios_app;
78         *p++ = 'a';
79     }
80     else
81     {
82         mode = ios_out;
83         *p++ = 'w';
84     }
85
86     if ( io_mode & ios_binary )
87     {
88         mode |= ios_binary;
89         *p++ = 'b';
90     }
91
92     // Hard code the compression level
93     if ( io_mode & (ios_out | ios_app) )
94     {
95         *p++ = '9';
96     }
97
98     *p = '\0';
99 }
100
101 gzfilebuf*
102 gzfilebuf::open( const char *name, ios_openmode io_mode )
103 {
104     if ( is_open() )
105         return NULL;
106
107     char char_mode[10];
108     cvt_iomode( char_mode, io_mode );
109     if ( (file = gzopen(name, char_mode)) == NULL )
110         return NULL;
111
112     own_file_descriptor = true;
113
114     return this;
115 }
116
117 gzfilebuf*
118 gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
119 {
120     if ( is_open() )
121         return NULL;
122
123     char char_mode[10];
124     cvt_iomode( char_mode, io_mode );
125     if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
126         return NULL;
127
128     own_file_descriptor = false;
129
130     return this;
131 }
132
133 gzfilebuf*
134 gzfilebuf::close()
135 {
136     if ( is_open() )
137     {
138         sync();
139         gzclose( file );
140         file = NULL;
141     }
142
143     return this;
144 }
145
146 // int
147 // gzfilebuf::setcompressionlevel( int comp_level )
148 // {
149 //     return gzsetparams(file, comp_level, -2);
150 // }
151
152 // int
153 // gzfilebuf::setcompressionstrategy( int comp_strategy )
154 // {
155 //     return gzsetparams(file, -2, comp_strategy);
156 // }
157
158
159 streampos
160 gzfilebuf::seekoff( streamoff, ios_seekdir, int )
161 {
162     return streampos(EOF);
163 }
164
165 gzfilebuf::int_type
166 gzfilebuf::overflow( int_type )
167 {
168 #if 0
169     if ( !is_open() || !(mode & ios::out) )
170         return EOF;
171
172     if ( !base() )
173     {
174         if ( allocate() == EOF )
175             return EOF;
176         setg(0,0,0);
177     }
178     else
179     {
180         if (in_avail())
181         {
182             return EOF;
183         }
184
185         if (out_waiting())
186         {
187             if (flushbuf() == EOF)
188                 return EOF;
189         }
190     }
191
192     int bl = blen();
193     setp( base(), base() + bl);
194
195     if ( c != EOF )
196     {
197         *pptr() = c;
198         pbump(1);
199     }
200 #endif
201     return 0;
202 }
203
204 int
205 gzfilebuf::sync()
206 {
207     if ( !is_open() )
208         return EOF;
209
210     if ( pptr() != 0 && pptr() > pbase() )
211         return flushbuf();
212
213     return 0;
214 }
215
216 gzfilebuf::int_type
217 gzfilebuf::flushbuf()
218 {
219     char* q = pbase();
220     int n = pptr() - q;
221
222     if ( gzwrite( file, q, n) < n )
223         return traits_type::eof();
224
225     setp(0,0);
226
227     return 0;
228 }
229
230 gzfilebuf::int_type
231 gzfilebuf::underflow()
232 {
233 //     cerr << "gzfilebuf::underflow(): gptr()=" << (void*)gptr() << endl;
234     // Error if the file not open for reading.
235     if ( !is_open() || !(mode & ios_in) )
236         return traits_type::eof();
237
238     // If the input buffer is empty then try to fill it.
239     if ( gptr() != 0 && gptr() < egptr() )
240     {
241         return int_type(*gptr());
242     }
243     else
244     {
245         return fillbuf() == EOF ? traits_type::eof() : int_type(*gptr());
246     }
247 }
248
249 //
250 // Load the input buffer from the underlying gz file.
251 // Returns number of characters read, or EOF.
252 //
253 int
254 gzfilebuf::fillbuf()
255 {
256     int t = gzread( file, ibuffer, ibuf_size );
257     if ( t <= 0)
258     {
259         // disable get area
260         setg(0,0,0);
261         return EOF;
262     }
263
264     // Set the input (get) pointers
265     setg( ibuffer, ibuffer, ibuffer+t );
266
267 //     cerr << "gzfilebuf::fillbuf():"
268 //       << " t=" << t
269 //       << ", ibuffer=" << (void*)ibuffer
270 //       << ", ibuffer+t=" << (void*)(ibuffer+t) << endl;
271
272     return t;
273 }
274
275 #if 0
276 gzifstream::gzifstream()
277     : istream(&buffer), buffer()
278 {
279     clear( ios_badbit );
280 }
281
282 gzifstream::gzifstream( const char *name, ios_openmode io_mode )
283     : istream(&buffer), buffer()
284 {
285     this->open( name, io_mode );
286 }
287
288 gzifstream::gzifstream( int fd, ios_openmode io_mode )
289     : istream(&buffer), buffer()
290 {
291     buffer.attach( fd, io_mode );
292 }
293
294 gzifstream::~gzifstream()
295 {
296 }
297
298 void
299 gzifstream::open( const char *name, ios_openmode io_mode )
300 {
301     if ( !buffer.open( name, io_mode ) )
302         clear( ios_failbit | ios_badbit );
303     else
304         clear();
305 }
306
307 void
308 gzifstream::close()
309 {
310     if ( !buffer.close() )
311         clear( ios_failbit | ios_badbit );
312 }
313 #endif
314