xref: /minix3/common/dist/zlib/contrib/iostream/zfstream.cpp (revision 44bedb31d842b4b0444105519bcf929a69fe2dc1)
1*44bedb31SLionel Sambuc 
2*44bedb31SLionel Sambuc #include "zfstream.h"
3*44bedb31SLionel Sambuc 
gzfilebuf()4*44bedb31SLionel Sambuc gzfilebuf::gzfilebuf() :
5*44bedb31SLionel Sambuc   file(NULL),
6*44bedb31SLionel Sambuc   mode(0),
7*44bedb31SLionel Sambuc   own_file_descriptor(0)
8*44bedb31SLionel Sambuc { }
9*44bedb31SLionel Sambuc 
~gzfilebuf()10*44bedb31SLionel Sambuc gzfilebuf::~gzfilebuf() {
11*44bedb31SLionel Sambuc 
12*44bedb31SLionel Sambuc   sync();
13*44bedb31SLionel Sambuc   if ( own_file_descriptor )
14*44bedb31SLionel Sambuc     close();
15*44bedb31SLionel Sambuc 
16*44bedb31SLionel Sambuc }
17*44bedb31SLionel Sambuc 
open(const char * name,int io_mode)18*44bedb31SLionel Sambuc gzfilebuf *gzfilebuf::open( const char *name,
19*44bedb31SLionel Sambuc                             int io_mode ) {
20*44bedb31SLionel Sambuc 
21*44bedb31SLionel Sambuc   if ( is_open() )
22*44bedb31SLionel Sambuc     return NULL;
23*44bedb31SLionel Sambuc 
24*44bedb31SLionel Sambuc   char char_mode[10];
25*44bedb31SLionel Sambuc   char *p = char_mode;
26*44bedb31SLionel Sambuc 
27*44bedb31SLionel Sambuc   if ( io_mode & ios::in ) {
28*44bedb31SLionel Sambuc     mode = ios::in;
29*44bedb31SLionel Sambuc     *p++ = 'r';
30*44bedb31SLionel Sambuc   } else if ( io_mode & ios::app ) {
31*44bedb31SLionel Sambuc     mode = ios::app;
32*44bedb31SLionel Sambuc     *p++ = 'a';
33*44bedb31SLionel Sambuc   } else {
34*44bedb31SLionel Sambuc     mode = ios::out;
35*44bedb31SLionel Sambuc     *p++ = 'w';
36*44bedb31SLionel Sambuc   }
37*44bedb31SLionel Sambuc 
38*44bedb31SLionel Sambuc   if ( io_mode & ios::binary ) {
39*44bedb31SLionel Sambuc     mode |= ios::binary;
40*44bedb31SLionel Sambuc     *p++ = 'b';
41*44bedb31SLionel Sambuc   }
42*44bedb31SLionel Sambuc 
43*44bedb31SLionel Sambuc   // Hard code the compression level
44*44bedb31SLionel Sambuc   if ( io_mode & (ios::out|ios::app )) {
45*44bedb31SLionel Sambuc     *p++ = '9';
46*44bedb31SLionel Sambuc   }
47*44bedb31SLionel Sambuc 
48*44bedb31SLionel Sambuc   // Put the end-of-string indicator
49*44bedb31SLionel Sambuc   *p = '\0';
50*44bedb31SLionel Sambuc 
51*44bedb31SLionel Sambuc   if ( (file = gzopen(name, char_mode)) == NULL )
52*44bedb31SLionel Sambuc     return NULL;
53*44bedb31SLionel Sambuc 
54*44bedb31SLionel Sambuc   own_file_descriptor = 1;
55*44bedb31SLionel Sambuc 
56*44bedb31SLionel Sambuc   return this;
57*44bedb31SLionel Sambuc 
58*44bedb31SLionel Sambuc }
59*44bedb31SLionel Sambuc 
attach(int file_descriptor,int io_mode)60*44bedb31SLionel Sambuc gzfilebuf *gzfilebuf::attach( int file_descriptor,
61*44bedb31SLionel Sambuc                               int io_mode ) {
62*44bedb31SLionel Sambuc 
63*44bedb31SLionel Sambuc   if ( is_open() )
64*44bedb31SLionel Sambuc     return NULL;
65*44bedb31SLionel Sambuc 
66*44bedb31SLionel Sambuc   char char_mode[10];
67*44bedb31SLionel Sambuc   char *p = char_mode;
68*44bedb31SLionel Sambuc 
69*44bedb31SLionel Sambuc   if ( io_mode & ios::in ) {
70*44bedb31SLionel Sambuc     mode = ios::in;
71*44bedb31SLionel Sambuc     *p++ = 'r';
72*44bedb31SLionel Sambuc   } else if ( io_mode & ios::app ) {
73*44bedb31SLionel Sambuc     mode = ios::app;
74*44bedb31SLionel Sambuc     *p++ = 'a';
75*44bedb31SLionel Sambuc   } else {
76*44bedb31SLionel Sambuc     mode = ios::out;
77*44bedb31SLionel Sambuc     *p++ = 'w';
78*44bedb31SLionel Sambuc   }
79*44bedb31SLionel Sambuc 
80*44bedb31SLionel Sambuc   if ( io_mode & ios::binary ) {
81*44bedb31SLionel Sambuc     mode |= ios::binary;
82*44bedb31SLionel Sambuc     *p++ = 'b';
83*44bedb31SLionel Sambuc   }
84*44bedb31SLionel Sambuc 
85*44bedb31SLionel Sambuc   // Hard code the compression level
86*44bedb31SLionel Sambuc   if ( io_mode & (ios::out|ios::app )) {
87*44bedb31SLionel Sambuc     *p++ = '9';
88*44bedb31SLionel Sambuc   }
89*44bedb31SLionel Sambuc 
90*44bedb31SLionel Sambuc   // Put the end-of-string indicator
91*44bedb31SLionel Sambuc   *p = '\0';
92*44bedb31SLionel Sambuc 
93*44bedb31SLionel Sambuc   if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
94*44bedb31SLionel Sambuc     return NULL;
95*44bedb31SLionel Sambuc 
96*44bedb31SLionel Sambuc   own_file_descriptor = 0;
97*44bedb31SLionel Sambuc 
98*44bedb31SLionel Sambuc   return this;
99*44bedb31SLionel Sambuc 
100*44bedb31SLionel Sambuc }
101*44bedb31SLionel Sambuc 
close()102*44bedb31SLionel Sambuc gzfilebuf *gzfilebuf::close() {
103*44bedb31SLionel Sambuc 
104*44bedb31SLionel Sambuc   if ( is_open() ) {
105*44bedb31SLionel Sambuc 
106*44bedb31SLionel Sambuc     sync();
107*44bedb31SLionel Sambuc     gzclose( file );
108*44bedb31SLionel Sambuc     file = NULL;
109*44bedb31SLionel Sambuc 
110*44bedb31SLionel Sambuc   }
111*44bedb31SLionel Sambuc 
112*44bedb31SLionel Sambuc   return this;
113*44bedb31SLionel Sambuc 
114*44bedb31SLionel Sambuc }
115*44bedb31SLionel Sambuc 
setcompressionlevel(int comp_level)116*44bedb31SLionel Sambuc int gzfilebuf::setcompressionlevel( int comp_level ) {
117*44bedb31SLionel Sambuc 
118*44bedb31SLionel Sambuc   return gzsetparams(file, comp_level, -2);
119*44bedb31SLionel Sambuc 
120*44bedb31SLionel Sambuc }
121*44bedb31SLionel Sambuc 
setcompressionstrategy(int comp_strategy)122*44bedb31SLionel Sambuc int gzfilebuf::setcompressionstrategy( int comp_strategy ) {
123*44bedb31SLionel Sambuc 
124*44bedb31SLionel Sambuc   return gzsetparams(file, -2, comp_strategy);
125*44bedb31SLionel Sambuc 
126*44bedb31SLionel Sambuc }
127*44bedb31SLionel Sambuc 
128*44bedb31SLionel Sambuc 
seekoff(streamoff off,ios::seek_dir dir,int which)129*44bedb31SLionel Sambuc streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
130*44bedb31SLionel Sambuc 
131*44bedb31SLionel Sambuc   return streampos(EOF);
132*44bedb31SLionel Sambuc 
133*44bedb31SLionel Sambuc }
134*44bedb31SLionel Sambuc 
underflow()135*44bedb31SLionel Sambuc int gzfilebuf::underflow() {
136*44bedb31SLionel Sambuc 
137*44bedb31SLionel Sambuc   // If the file hasn't been opened for reading, error.
138*44bedb31SLionel Sambuc   if ( !is_open() || !(mode & ios::in) )
139*44bedb31SLionel Sambuc     return EOF;
140*44bedb31SLionel Sambuc 
141*44bedb31SLionel Sambuc   // if a buffer doesn't exists, allocate one.
142*44bedb31SLionel Sambuc   if ( !base() ) {
143*44bedb31SLionel Sambuc 
144*44bedb31SLionel Sambuc     if ( (allocate()) == EOF )
145*44bedb31SLionel Sambuc       return EOF;
146*44bedb31SLionel Sambuc     setp(0,0);
147*44bedb31SLionel Sambuc 
148*44bedb31SLionel Sambuc   } else {
149*44bedb31SLionel Sambuc 
150*44bedb31SLionel Sambuc     if ( in_avail() )
151*44bedb31SLionel Sambuc       return (unsigned char) *gptr();
152*44bedb31SLionel Sambuc 
153*44bedb31SLionel Sambuc     if ( out_waiting() ) {
154*44bedb31SLionel Sambuc       if ( flushbuf() == EOF )
155*44bedb31SLionel Sambuc         return EOF;
156*44bedb31SLionel Sambuc     }
157*44bedb31SLionel Sambuc 
158*44bedb31SLionel Sambuc   }
159*44bedb31SLionel Sambuc 
160*44bedb31SLionel Sambuc   // Attempt to fill the buffer.
161*44bedb31SLionel Sambuc 
162*44bedb31SLionel Sambuc   int result = fillbuf();
163*44bedb31SLionel Sambuc   if ( result == EOF ) {
164*44bedb31SLionel Sambuc     // disable get area
165*44bedb31SLionel Sambuc     setg(0,0,0);
166*44bedb31SLionel Sambuc     return EOF;
167*44bedb31SLionel Sambuc   }
168*44bedb31SLionel Sambuc 
169*44bedb31SLionel Sambuc   return (unsigned char) *gptr();
170*44bedb31SLionel Sambuc 
171*44bedb31SLionel Sambuc }
172*44bedb31SLionel Sambuc 
overflow(int c)173*44bedb31SLionel Sambuc int gzfilebuf::overflow( int c ) {
174*44bedb31SLionel Sambuc 
175*44bedb31SLionel Sambuc   if ( !is_open() || !(mode & ios::out) )
176*44bedb31SLionel Sambuc     return EOF;
177*44bedb31SLionel Sambuc 
178*44bedb31SLionel Sambuc   if ( !base() ) {
179*44bedb31SLionel Sambuc     if ( allocate() == EOF )
180*44bedb31SLionel Sambuc       return EOF;
181*44bedb31SLionel Sambuc     setg(0,0,0);
182*44bedb31SLionel Sambuc   } else {
183*44bedb31SLionel Sambuc     if (in_avail()) {
184*44bedb31SLionel Sambuc         return EOF;
185*44bedb31SLionel Sambuc     }
186*44bedb31SLionel Sambuc     if (out_waiting()) {
187*44bedb31SLionel Sambuc       if (flushbuf() == EOF)
188*44bedb31SLionel Sambuc         return EOF;
189*44bedb31SLionel Sambuc     }
190*44bedb31SLionel Sambuc   }
191*44bedb31SLionel Sambuc 
192*44bedb31SLionel Sambuc   int bl = blen();
193*44bedb31SLionel Sambuc   setp( base(), base() + bl);
194*44bedb31SLionel Sambuc 
195*44bedb31SLionel Sambuc   if ( c != EOF ) {
196*44bedb31SLionel Sambuc 
197*44bedb31SLionel Sambuc     *pptr() = c;
198*44bedb31SLionel Sambuc     pbump(1);
199*44bedb31SLionel Sambuc 
200*44bedb31SLionel Sambuc   }
201*44bedb31SLionel Sambuc 
202*44bedb31SLionel Sambuc   return 0;
203*44bedb31SLionel Sambuc 
204*44bedb31SLionel Sambuc }
205*44bedb31SLionel Sambuc 
sync()206*44bedb31SLionel Sambuc int gzfilebuf::sync() {
207*44bedb31SLionel Sambuc 
208*44bedb31SLionel Sambuc   if ( !is_open() )
209*44bedb31SLionel Sambuc     return EOF;
210*44bedb31SLionel Sambuc 
211*44bedb31SLionel Sambuc   if ( out_waiting() )
212*44bedb31SLionel Sambuc     return flushbuf();
213*44bedb31SLionel Sambuc 
214*44bedb31SLionel Sambuc   return 0;
215*44bedb31SLionel Sambuc 
216*44bedb31SLionel Sambuc }
217*44bedb31SLionel Sambuc 
flushbuf()218*44bedb31SLionel Sambuc int gzfilebuf::flushbuf() {
219*44bedb31SLionel Sambuc 
220*44bedb31SLionel Sambuc   int n;
221*44bedb31SLionel Sambuc   char *q;
222*44bedb31SLionel Sambuc 
223*44bedb31SLionel Sambuc   q = pbase();
224*44bedb31SLionel Sambuc   n = pptr() - q;
225*44bedb31SLionel Sambuc 
226*44bedb31SLionel Sambuc   if ( gzwrite( file, q, n) < n )
227*44bedb31SLionel Sambuc     return EOF;
228*44bedb31SLionel Sambuc 
229*44bedb31SLionel Sambuc   setp(0,0);
230*44bedb31SLionel Sambuc 
231*44bedb31SLionel Sambuc   return 0;
232*44bedb31SLionel Sambuc 
233*44bedb31SLionel Sambuc }
234*44bedb31SLionel Sambuc 
fillbuf()235*44bedb31SLionel Sambuc int gzfilebuf::fillbuf() {
236*44bedb31SLionel Sambuc 
237*44bedb31SLionel Sambuc   int required;
238*44bedb31SLionel Sambuc   char *p;
239*44bedb31SLionel Sambuc 
240*44bedb31SLionel Sambuc   p = base();
241*44bedb31SLionel Sambuc 
242*44bedb31SLionel Sambuc   required = blen();
243*44bedb31SLionel Sambuc 
244*44bedb31SLionel Sambuc   int t = gzread( file, p, required );
245*44bedb31SLionel Sambuc 
246*44bedb31SLionel Sambuc   if ( t <= 0) return EOF;
247*44bedb31SLionel Sambuc 
248*44bedb31SLionel Sambuc   setg( base(), base(), base()+t);
249*44bedb31SLionel Sambuc 
250*44bedb31SLionel Sambuc   return t;
251*44bedb31SLionel Sambuc 
252*44bedb31SLionel Sambuc }
253*44bedb31SLionel Sambuc 
gzfilestream_common()254*44bedb31SLionel Sambuc gzfilestream_common::gzfilestream_common() :
255*44bedb31SLionel Sambuc   ios( gzfilestream_common::rdbuf() )
256*44bedb31SLionel Sambuc { }
257*44bedb31SLionel Sambuc 
~gzfilestream_common()258*44bedb31SLionel Sambuc gzfilestream_common::~gzfilestream_common()
259*44bedb31SLionel Sambuc { }
260*44bedb31SLionel Sambuc 
attach(int fd,int io_mode)261*44bedb31SLionel Sambuc void gzfilestream_common::attach( int fd, int io_mode ) {
262*44bedb31SLionel Sambuc 
263*44bedb31SLionel Sambuc   if ( !buffer.attach( fd, io_mode) )
264*44bedb31SLionel Sambuc     clear( ios::failbit | ios::badbit );
265*44bedb31SLionel Sambuc   else
266*44bedb31SLionel Sambuc     clear();
267*44bedb31SLionel Sambuc 
268*44bedb31SLionel Sambuc }
269*44bedb31SLionel Sambuc 
open(const char * name,int io_mode)270*44bedb31SLionel Sambuc void gzfilestream_common::open( const char *name, int io_mode ) {
271*44bedb31SLionel Sambuc 
272*44bedb31SLionel Sambuc   if ( !buffer.open( name, io_mode ) )
273*44bedb31SLionel Sambuc     clear( ios::failbit | ios::badbit );
274*44bedb31SLionel Sambuc   else
275*44bedb31SLionel Sambuc     clear();
276*44bedb31SLionel Sambuc 
277*44bedb31SLionel Sambuc }
278*44bedb31SLionel Sambuc 
close()279*44bedb31SLionel Sambuc void gzfilestream_common::close() {
280*44bedb31SLionel Sambuc 
281*44bedb31SLionel Sambuc   if ( !buffer.close() )
282*44bedb31SLionel Sambuc     clear( ios::failbit | ios::badbit );
283*44bedb31SLionel Sambuc 
284*44bedb31SLionel Sambuc }
285*44bedb31SLionel Sambuc 
rdbuf()286*44bedb31SLionel Sambuc gzfilebuf *gzfilestream_common::rdbuf()
287*44bedb31SLionel Sambuc {
288*44bedb31SLionel Sambuc   return &buffer;
289*44bedb31SLionel Sambuc }
290*44bedb31SLionel Sambuc 
gzifstream()291*44bedb31SLionel Sambuc gzifstream::gzifstream() :
292*44bedb31SLionel Sambuc   ios( gzfilestream_common::rdbuf() )
293*44bedb31SLionel Sambuc {
294*44bedb31SLionel Sambuc   clear( ios::badbit );
295*44bedb31SLionel Sambuc }
296*44bedb31SLionel Sambuc 
gzifstream(const char * name,int io_mode)297*44bedb31SLionel Sambuc gzifstream::gzifstream( const char *name, int io_mode ) :
298*44bedb31SLionel Sambuc   ios( gzfilestream_common::rdbuf() )
299*44bedb31SLionel Sambuc {
300*44bedb31SLionel Sambuc   gzfilestream_common::open( name, io_mode );
301*44bedb31SLionel Sambuc }
302*44bedb31SLionel Sambuc 
gzifstream(int fd,int io_mode)303*44bedb31SLionel Sambuc gzifstream::gzifstream( int fd, int io_mode ) :
304*44bedb31SLionel Sambuc   ios( gzfilestream_common::rdbuf() )
305*44bedb31SLionel Sambuc {
306*44bedb31SLionel Sambuc   gzfilestream_common::attach( fd, io_mode );
307*44bedb31SLionel Sambuc }
308*44bedb31SLionel Sambuc 
~gzifstream()309*44bedb31SLionel Sambuc gzifstream::~gzifstream() { }
310*44bedb31SLionel Sambuc 
gzofstream()311*44bedb31SLionel Sambuc gzofstream::gzofstream() :
312*44bedb31SLionel Sambuc   ios( gzfilestream_common::rdbuf() )
313*44bedb31SLionel Sambuc {
314*44bedb31SLionel Sambuc   clear( ios::badbit );
315*44bedb31SLionel Sambuc }
316*44bedb31SLionel Sambuc 
gzofstream(const char * name,int io_mode)317*44bedb31SLionel Sambuc gzofstream::gzofstream( const char *name, int io_mode ) :
318*44bedb31SLionel Sambuc   ios( gzfilestream_common::rdbuf() )
319*44bedb31SLionel Sambuc {
320*44bedb31SLionel Sambuc   gzfilestream_common::open( name, io_mode );
321*44bedb31SLionel Sambuc }
322*44bedb31SLionel Sambuc 
gzofstream(int fd,int io_mode)323*44bedb31SLionel Sambuc gzofstream::gzofstream( int fd, int io_mode ) :
324*44bedb31SLionel Sambuc   ios( gzfilestream_common::rdbuf() )
325*44bedb31SLionel Sambuc {
326*44bedb31SLionel Sambuc   gzfilestream_common::attach( fd, io_mode );
327*44bedb31SLionel Sambuc }
328*44bedb31SLionel Sambuc 
~gzofstream()329*44bedb31SLionel Sambuc gzofstream::~gzofstream() { }
330