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