]> git.mxchange.org Git - simgear.git/blob - simgear/misc/zfstream.cxx
Removal of PLIB/SG from SimGear
[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 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.
21 //
22 // $Id$
23
24 #include <simgear/compiler.h>
25
26 #include <cerrno>
27 #include <memory.h>
28 #include <stdio.h>
29
30 #include "zfstream.hxx"
31
32 //
33 // Construct a gzfilebuf object.
34 // Allocate memory for 'get' buffer and zero all buffer pointers.
35 //
36 gzfilebuf::gzfilebuf()
37     : std::streambuf(),
38       file(NULL),
39       mode(ios_openmode(0)),
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         // perror( "gzfilebuf::open(): " );
111         errno = 0;
112         return NULL;
113     }
114
115     own_file_descriptor = true;
116
117     return this;
118 }
119
120 gzfilebuf*
121 gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
122 {
123     if ( is_open() )
124         return NULL;
125
126     char char_mode[10];
127     cvt_iomode( char_mode, io_mode );
128     if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) {
129         perror( "gzfilebuf::attach(): " );
130         errno = 0;
131         return NULL;
132     }
133
134     own_file_descriptor = false;
135
136     return this;
137 }
138
139 gzfilebuf*
140 gzfilebuf::close()
141 {
142     // cout << "closing ..." ;
143     if ( is_open() )
144     {
145         sync();
146         gzclose( file );
147         file = NULL;
148         // cout << "done" << endl;
149     } else {
150         // cout << "error" << endl;
151     }
152
153     return this;
154 }
155
156 // int
157 // gzfilebuf::setcompressionlevel( int comp_level )
158 // {
159 //     return gzsetparams(file, comp_level, -2);
160 // }
161
162 // int
163 // gzfilebuf::setcompressionstrategy( int comp_strategy )
164 // {
165 //     return gzsetparams(file, -2, comp_strategy);
166 // }
167
168
169 std::streampos
170 gzfilebuf::seekoff( std::streamoff, ios_seekdir, int )
171 {
172     return std::streampos(EOF);
173 }
174
175 gzfilebuf::int_type
176 gzfilebuf::overflow( int_type )
177 {
178 #if 0
179     if ( !is_open() || !(mode & ios::out) )
180         return EOF;
181
182     if ( !base() )
183     {
184         if ( allocate() == EOF )
185             return EOF;
186         setg(0,0,0);
187     }
188     else
189     {
190         if (in_avail())
191         {
192             return EOF;
193         }
194
195         if (out_waiting())
196         {
197             if (flushbuf() == EOF)
198                 return EOF;
199         }
200     }
201
202     int bl = blen();
203     setp( base(), base() + bl);
204
205     if ( c != EOF )
206     {
207         *pptr() = c;
208         pbump(1);
209     }
210 #endif
211     return 0;
212 }
213
214 int
215 gzfilebuf::sync()
216 {
217     if ( !is_open() )
218         return EOF;
219
220     if ( pptr() != 0 && pptr() > pbase() )
221         return flushbuf();
222
223     return 0;
224 }
225
226 gzfilebuf::int_type
227 gzfilebuf::flushbuf()
228 {
229     char* q = pbase();
230     int n = pptr() - q;
231
232     if ( gzwrite( file, q, n) < n )
233         return traits_type::eof();
234
235     setp(0,0);
236
237     return 0;
238 }
239
240 gzfilebuf::int_type
241 gzfilebuf::underflow()
242 {
243 //     cerr << "gzfilebuf::underflow(): gptr()=" << (void*)gptr() << endl;
244     // Error if the file not open for reading.
245     if ( !is_open() || !(mode & ios_in) )
246         return traits_type::eof();
247
248     // If the input buffer is empty then try to fill it.
249     if ( gptr() != 0 && gptr() < egptr() )
250     {
251         return int_type(*gptr());
252     }
253     else
254     {
255         return fillbuf() == EOF ? traits_type::eof() : int_type(*gptr());
256     }
257 }
258
259 //
260 // Load the input buffer from the underlying gz file.
261 // Returns number of characters read, or EOF.
262 //
263 int
264 gzfilebuf::fillbuf()
265 {
266     int t = gzread( file, ibuffer, ibuf_size );
267     if ( t <= 0)
268     {
269         // disable get area
270         setg(0,0,0);
271         return EOF;
272     }
273
274     // Set the input (get) pointers
275     setg( ibuffer, ibuffer, ibuffer+t );
276
277 //     cerr << "gzfilebuf::fillbuf():"
278 //       << " t=" << t
279 //       << ", ibuffer=" << (void*)ibuffer
280 //       << ", ibuffer+t=" << (void*)(ibuffer+t) << endl;
281
282     return t;
283 }
284
285 #if 0
286 gzifstream::gzifstream()
287     : istream(&buffer), buffer()
288 {
289     clear( ios_badbit );
290 }
291
292 gzifstream::gzifstream( const char *name, ios_openmode io_mode )
293     : istream(&buffer), buffer()
294 {
295     this->open( name, io_mode );
296 }
297
298 gzifstream::gzifstream( int fd, ios_openmode io_mode )
299     : istream(&buffer), buffer()
300 {
301     buffer.attach( fd, io_mode );
302 }
303
304 gzifstream::~gzifstream()
305 {
306 }
307
308 void
309 gzifstream::open( const char *name, ios_openmode io_mode )
310 {
311     if ( !buffer.open( name, io_mode ) )
312         clear( ios_failbit | ios_badbit );
313     else
314         clear();
315 }
316
317 void
318 gzifstream::close()
319 {
320     if ( !buffer.close() )
321         clear( ios_failbit | ios_badbit );
322 }
323 #endif
324