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