]> git.mxchange.org Git - simgear.git/blob - Lib/Misc/zfstream.cxx
Fixed an IRIX warning message where an inline function is referenced
[simgear.git] / Lib / 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 program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 //
22 // $Id$
23
24 #include <memory.h>
25 #include "zfstream.hxx"
26
27 //
28 // Construct a gzfilebuf object.
29 // Allocate memory for 'get' buffer and zero all buffer pointers.
30 //
31 gzfilebuf::gzfilebuf()
32     : streambuf(),
33       file(NULL),
34       mode(0),
35       own_file_descriptor(false),
36       ibuf_size(0),
37       ibuffer(0)
38 {
39 //     try {
40     ibuf_size = page_size / sizeof(char);
41     ibuffer = new char [ibuf_size];
42 //     } catch (...) {
43 //      delete [] ibuffer;
44 //     }
45
46     // Null get and set pointers.
47     this->setg(0,0,0);
48     this->setp(0,0);
49 }
50
51 gzfilebuf::~gzfilebuf()
52 {
53     sync();
54     if ( own_file_descriptor )
55         this->close();
56     delete [] ibuffer;
57 }
58
59 void
60 gzfilebuf::cvt_iomode( char* p, ios_openmode io_mode )
61 {
62 //     memset( char_mode, '\0', 10 );
63 //     char* p = char_mode;
64
65     if ( io_mode & ios_in )
66     {
67         mode = ios_in;
68         *p++ = 'r';
69     }
70     else if ( io_mode & ios_app )
71     {
72         mode = ios_app;
73         *p++ = 'a';
74     }
75     else
76     {
77         mode = ios_out;
78         *p++ = 'w';
79     }
80
81     if ( io_mode & ios_binary )
82     {
83         mode |= ios_binary;
84         *p++ = 'b';
85     }
86
87     // Hard code the compression level
88     if ( io_mode & (ios_out | ios_app) )
89     {
90         *p++ = '9';
91     }
92
93     *p = '\0';
94 }
95
96 gzfilebuf*
97 gzfilebuf::open( const char *name, ios_openmode io_mode )
98 {
99     if ( is_open() )
100         return NULL;
101
102     char char_mode[10];
103     cvt_iomode( char_mode, io_mode );
104     if ( (file = gzopen(name, char_mode)) == NULL )
105         return NULL;
106
107     own_file_descriptor = true;
108
109     return this;
110 }
111
112 gzfilebuf*
113 gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
114 {
115     if ( is_open() )
116         return NULL;
117
118     char char_mode[10];
119     cvt_iomode( char_mode, io_mode );
120     if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
121         return NULL;
122
123     own_file_descriptor = false;
124
125     return this;
126 }
127
128 gzfilebuf*
129 gzfilebuf::close()
130 {
131     if ( is_open() )
132     {
133         sync();
134         gzclose( file );
135         file = NULL;
136     }
137
138     return this;
139 }
140
141 // int
142 // gzfilebuf::setcompressionlevel( int comp_level )
143 // {
144 //     return gzsetparams(file, comp_level, -2);
145 // }
146
147 // int
148 // gzfilebuf::setcompressionstrategy( int comp_strategy )
149 // {
150 //     return gzsetparams(file, -2, comp_strategy);
151 // }
152
153
154 streampos
155 gzfilebuf::seekoff( streamoff, ios_seekdir, int )
156 {
157     return streampos(EOF);
158 }
159
160 gzfilebuf::int_type
161 gzfilebuf::overflow( int_type )
162 {
163 #if 0
164     if ( !is_open() || !(mode & ios::out) )
165         return EOF;
166
167     if ( !base() )
168     {
169         if ( allocate() == EOF )
170             return EOF;
171         setg(0,0,0);
172     }
173     else
174     {
175         if (in_avail())
176         {
177             return EOF;
178         }
179
180         if (out_waiting())
181         {
182             if (flushbuf() == EOF)
183                 return EOF;
184         }
185     }
186
187     int bl = blen();
188     setp( base(), base() + bl);
189
190     if ( c != EOF )
191     {
192         *pptr() = c;
193         pbump(1);
194     }
195 #endif
196     return 0;
197 }
198
199 int
200 gzfilebuf::sync()
201 {
202     if ( !is_open() )
203         return EOF;
204
205     if ( pptr() != 0 && pptr() > pbase() )
206         return flushbuf();
207
208     return 0;
209 }
210
211 gzfilebuf::int_type
212 gzfilebuf::flushbuf()
213 {
214     char* q = pbase();
215     int n = pptr() - q;
216
217     if ( gzwrite( file, q, n) < n )
218         return traits_type::eof();
219
220     setp(0,0);
221
222     return 0;
223 }
224
225 gzfilebuf::int_type
226 gzfilebuf::underflow()
227 {
228 //     cerr << "gzfilebuf::underflow(): gptr()=" << (void*)gptr() << endl;
229     // Error if the file not open for reading.
230     if ( !is_open() || !(mode & ios_in) )
231         return traits_type::eof();
232
233     // If the input buffer is empty then try to fill it.
234     if ( gptr() != 0 && gptr() < egptr() )
235     {
236         return int_type(*gptr());
237     }
238     else
239     {
240         return fillbuf() == EOF ? traits_type::eof() : int_type(*gptr());
241     }
242 }
243
244 //
245 // Load the input buffer from the underlying gz file.
246 // Returns number of characters read, or EOF.
247 //
248 int
249 gzfilebuf::fillbuf()
250 {
251     int t = gzread( file, ibuffer, ibuf_size );
252     if ( t <= 0)
253     {
254         // disable get area
255         setg(0,0,0);
256         return EOF;
257     }
258
259     // Set the input (get) pointers
260     setg( ibuffer, ibuffer, ibuffer+t );
261
262 //     cerr << "gzfilebuf::fillbuf():"
263 //       << " t=" << t
264 //       << ", ibuffer=" << (void*)ibuffer
265 //       << ", ibuffer+t=" << (void*)(ibuffer+t) << endl;
266
267     return t;
268 }
269
270 #if 0
271 gzifstream::gzifstream()
272     : istream(&buffer), buffer()
273 {
274     clear( ios_badbit );
275 }
276
277 gzifstream::gzifstream( const char *name, ios_openmode io_mode )
278     : istream(&buffer), buffer()
279 {
280     this->open( name, io_mode );
281 }
282
283 gzifstream::gzifstream( int fd, ios_openmode io_mode )
284     : istream(&buffer), buffer()
285 {
286     buffer.attach( fd, io_mode );
287 }
288
289 gzifstream::~gzifstream()
290 {
291 }
292
293 void
294 gzifstream::open( const char *name, ios_openmode io_mode )
295 {
296     if ( !buffer.open( name, io_mode ) )
297         clear( ios_failbit | ios_badbit );
298     else
299         clear();
300 }
301
302 void
303 gzifstream::close()
304 {
305     if ( !buffer.close() )
306         clear( ios_failbit | ios_badbit );
307 }
308 #endif
309