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