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