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