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