]> git.mxchange.org Git - flightgear.git/blob - Lib/Misc/zfstream.cxx
Merge FG_Lib as subdirectory
[flightgear.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 // (Log is kept at end of this file)
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       mode(0),
36       own_file_descriptor(false),
37       ibuf_size(0),
38       ibuffer(0)
39 {
40 //     try {
41     ibuf_size = page_size / sizeof(char);
42     ibuffer = new char [ibuf_size];
43 //     } catch (...) {
44 //      delete [] ibuffer;
45 //     }
46
47     // Null get and set pointers.
48     this->setg(0,0,0);
49     this->setp(0,0);
50 }
51
52 gzfilebuf::~gzfilebuf()
53 {
54     sync();
55     if ( own_file_descriptor )
56         this->close();
57     delete [] ibuffer;
58 }
59
60 void
61 gzfilebuf::cvt_iomode( char* p, ios_openmode io_mode )
62 {
63 //     memset( char_mode, '\0', 10 );
64 //     char* p = char_mode;
65
66     if ( io_mode & ios_in )
67     {
68         mode = ios_in;
69         *p++ = 'r';
70     }
71     else if ( io_mode & ios_app )
72     {
73         mode = ios_app;
74         *p++ = 'a';
75     }
76     else
77     {
78         mode = ios_out;
79         *p++ = 'w';
80     }
81
82     if ( io_mode & ios_binary )
83     {
84         mode |= ios_binary;
85         *p++ = 'b';
86     }
87
88     // Hard code the compression level
89     if ( io_mode & (ios_out | ios_app) )
90     {
91         *p++ = '9';
92     }
93
94     *p = '\0';
95 }
96
97 gzfilebuf*
98 gzfilebuf::open( const char *name, ios_openmode io_mode )
99 {
100     if ( is_open() )
101         return NULL;
102
103     char char_mode[10];
104     cvt_iomode( char_mode, io_mode );
105     if ( (file = gzopen(name, char_mode)) == NULL )
106         return NULL;
107
108     own_file_descriptor = true;
109
110     return this;
111 }
112
113 gzfilebuf*
114 gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
115 {
116     if ( is_open() )
117         return NULL;
118
119     char char_mode[10];
120     cvt_iomode( char_mode, io_mode );
121     if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
122         return NULL;
123
124     own_file_descriptor = false;
125
126     return this;
127 }
128
129 gzfilebuf*
130 gzfilebuf::close()
131 {
132     if ( is_open() )
133     {
134         sync();
135         gzclose( file );
136         file = NULL;
137     }
138
139     return this;
140 }
141
142 // int
143 // gzfilebuf::setcompressionlevel( int comp_level )
144 // {
145 //     return gzsetparams(file, comp_level, -2);
146 // }
147
148 // int
149 // gzfilebuf::setcompressionstrategy( int comp_strategy )
150 // {
151 //     return gzsetparams(file, -2, comp_strategy);
152 // }
153
154
155 streampos
156 gzfilebuf::seekoff( streamoff, ios_seekdir, int )
157 {
158     return streampos(EOF);
159 }
160
161 gzfilebuf::int_type
162 gzfilebuf::overflow( int_type )
163 {
164 #if 0
165     if ( !is_open() || !(mode & ios::out) )
166         return EOF;
167
168     if ( !base() )
169     {
170         if ( allocate() == EOF )
171             return EOF;
172         setg(0,0,0);
173     }
174     else
175     {
176         if (in_avail())
177         {
178             return EOF;
179         }
180
181         if (out_waiting())
182         {
183             if (flushbuf() == EOF)
184                 return EOF;
185         }
186     }
187
188     int bl = blen();
189     setp( base(), base() + bl);
190
191     if ( c != EOF )
192     {
193         *pptr() = c;
194         pbump(1);
195     }
196 #endif
197     return 0;
198 }
199
200 int
201 gzfilebuf::sync()
202 {
203     if ( !is_open() )
204         return EOF;
205
206     if ( pptr() != 0 && pptr() > pbase() )
207         return flushbuf();
208
209     return 0;
210 }
211
212 gzfilebuf::int_type
213 gzfilebuf::flushbuf()
214 {
215     char* q = pbase();
216     int n = pptr() - q;
217
218     if ( gzwrite( file, q, n) < n )
219         return traits_type::eof();
220
221     setp(0,0);
222
223     return 0;
224 }
225
226 gzfilebuf::int_type
227 gzfilebuf::underflow()
228 {
229 //     cerr << "gzfilebuf::underflow(): gptr()=" << (void*)gptr() << endl;
230     // Error if the file not open for reading.
231     if ( !is_open() || !(mode & ios_in) )
232         return traits_type::eof();
233
234     // If the input buffer is empty then try to fill it.
235     if ( gptr() != 0 && gptr() < egptr() )
236     {
237         return int_type(*gptr());
238     }
239     else
240     {
241         return fillbuf() == EOF ? traits_type::eof() : int_type(*gptr());
242     }
243 }
244
245 //
246 // Load the input buffer from the underlying gz file.
247 // Returns number of characters read, or EOF.
248 //
249 int
250 gzfilebuf::fillbuf()
251 {
252     int t = gzread( file, ibuffer, ibuf_size );
253     if ( t <= 0)
254     {
255         // disable get area
256         setg(0,0,0);
257         return EOF;
258     }
259
260     // Set the input (get) pointers
261     setg( ibuffer, ibuffer, ibuffer+t );
262
263 //     cerr << "gzfilebuf::fillbuf():"
264 //       << " t=" << t
265 //       << ", ibuffer=" << (void*)ibuffer
266 //       << ", ibuffer+t=" << (void*)(ibuffer+t) << endl;
267
268     return t;
269 }
270
271 #if 0
272 gzifstream::gzifstream()
273     : istream(&buffer), buffer()
274 {
275     clear( ios_badbit );
276 }
277
278 gzifstream::gzifstream( const char *name, ios_openmode io_mode )
279     : istream(&buffer), buffer()
280 {
281     this->open( name, io_mode );
282 }
283
284 gzifstream::gzifstream( int fd, ios_openmode io_mode )
285     : istream(&buffer), buffer()
286 {
287     buffer.attach( fd, io_mode );
288 }
289
290 gzifstream::~gzifstream()
291 {
292 }
293
294 void
295 gzifstream::open( const char *name, ios_openmode io_mode )
296 {
297     if ( !buffer.open( name, io_mode ) )
298         clear( ios_failbit | ios_badbit );
299     else
300         clear();
301 }
302
303 void
304 gzifstream::close()
305 {
306     if ( !buffer.close() )
307         clear( ios_failbit | ios_badbit );
308 }
309 #endif
310
311 // $Log$
312 // Revision 1.3  1999/01/19 20:41:48  curt
313 // Portability updates contributed by Bernie Bright.
314 //
315 // Revision 1.2  1998/11/06 14:05:14  curt
316 // More portability improvements by Bernie Bright.
317 //