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