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