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