Mercurial > hg > octave-nkf
annotate src/zfstream.h @ 15536:2e8eb9ac43a5 stable rc-3-6-4-0
3.6.4-rc0 release candidate
* configure.ac (AC_INIT): Version is now 3.6.2-rc0.
(OCTAVE_RELEASE_DATE): Now 2012-05-11.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 17 Oct 2012 10:05:44 -0400 |
parents | 72c96de7a403 |
children | 460a3c6d8bf1 |
rev | line source |
---|---|
5269 | 1 /* |
2 | |
14138
72c96de7a403
maint: update copyright notices for 2012
John W. Eaton <jwe@octave.org>
parents:
12122
diff
changeset
|
3 Copyright (C) 2005-2012 Ludwig Schwardt, Kevin Ruland |
5269 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
5269 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
5269 | 20 |
21 */ | |
22 | |
23 /* | |
24 | |
25 This file is adapted from the zlib 1.2.2 contrib/iostream3 code, | |
26 written by | |
27 | |
28 Ludwig Schwardt <schwardt@sun.ac.za> | |
29 original version by Kevin Ruland <kevin@rodin.wustl.edu> | |
30 | |
31 */ | |
32 | |
33 #ifndef ZFSTREAM_H | |
34 #define ZFSTREAM_H | |
35 | |
36 #ifdef HAVE_ZLIB | |
37 | |
8950
d865363208d6
include <iosfwd> instead of <iostream> in header files
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
38 #include <iosfwd> |
d865363208d6
include <iosfwd> instead of <iostream> in header files
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
39 |
5269 | 40 #include "zlib.h" |
41 | |
42 /*****************************************************************************/ | |
43 | |
44 /** | |
45 * @brief Gzipped file stream buffer class. | |
46 * | |
47 * This class implements basic_filebuf for gzipped files. It doesn't yet support | |
48 * seeking (allowed by zlib but slow/limited), putback and read/write access | |
49 * (tricky). Otherwise, it attempts to be a drop-in replacement for the standard | |
50 * file streambuf. | |
51 */ | |
52 class gzfilebuf : public std::streambuf | |
53 { | |
54 public: | |
55 // Default constructor. | |
56 gzfilebuf(); | |
57 | |
58 // Destructor. | |
59 virtual | |
60 ~gzfilebuf(); | |
61 | |
62 /** | |
63 * @brief Set compression level and strategy on the fly. | |
64 * @param comp_level Compression level (see zlib.h for allowed values) | |
65 * @param comp_strategy Compression strategy (see zlib.h for allowed values) | |
66 * @return Z_OK on success, Z_STREAM_ERROR otherwise. | |
67 * | |
68 * Unfortunately, these parameters cannot be modified separately, as the | |
69 * previous zfstream version assumed. Since the strategy is seldom changed, | |
70 * it can default and setcompression(level) then becomes like the old | |
71 * setcompressionlevel(level). | |
72 */ | |
73 int | |
74 setcompression(int comp_level, | |
75 int comp_strategy = Z_DEFAULT_STRATEGY); | |
76 | |
77 /** | |
78 * @brief Check if file is open. | |
79 * @return True if file is open. | |
80 */ | |
81 bool | |
7520 | 82 is_open() const { return (file != 0); } |
5269 | 83 |
84 /** | |
85 * @brief Open gzipped file. | |
86 * @param name File name. | |
87 * @param mode Open mode flags. | |
88 * @return @c this on success, NULL on failure. | |
89 */ | |
90 gzfilebuf* | |
91 open(const char* name, | |
92 std::ios_base::openmode mode); | |
93 | |
94 /** | |
95 * @brief Attach to already open gzipped file. | |
96 * @param fd File descriptor. | |
97 * @param mode Open mode flags. | |
98 * @return @c this on success, NULL on failure. | |
99 */ | |
100 gzfilebuf* | |
101 attach(int fd, | |
102 std::ios_base::openmode mode); | |
103 | |
104 /** | |
105 * @brief Close gzipped file. | |
106 * @return @c this on success, NULL on failure. | |
107 */ | |
108 gzfilebuf* | |
109 close(); | |
110 | |
111 protected: | |
112 /** | |
113 * @brief Convert ios open mode int to mode string used by zlib. | |
114 * @return True if valid mode flag combination. | |
115 */ | |
116 bool | |
117 open_mode(std::ios_base::openmode mode, | |
118 char* c_mode) const; | |
119 | |
120 /** | |
121 * @brief Number of characters available in stream buffer. | |
122 * @return Number of characters. | |
123 * | |
124 * This indicates number of characters in get area of stream buffer. | |
125 * These characters can be read without accessing the gzipped file. | |
126 */ | |
127 virtual std::streamsize | |
128 showmanyc(); | |
129 | |
130 /** | |
131 * @brief Fill get area from gzipped file. | |
132 * @return First character in get area on success, EOF on error. | |
133 * | |
134 * This actually reads characters from gzipped file to stream | |
135 * buffer. Always buffered. | |
136 */ | |
137 virtual int_type | |
138 underflow(); | |
139 | |
140 /** | |
141 * @brief Write put area to gzipped file. | |
142 * @param c Extra character to add to buffer contents. | |
143 * @return Non-EOF on success, EOF on error. | |
144 * | |
145 * This actually writes characters in stream buffer to | |
146 * gzipped file. With unbuffered output this is done one | |
147 * character at a time. | |
148 */ | |
149 virtual int_type | |
150 overflow(int_type c = traits_type::eof()); | |
151 | |
152 /** | |
153 * @brief Installs external stream buffer. | |
154 * @param p Pointer to char buffer. | |
155 * @param n Size of external buffer. | |
156 * @return @c this on success, NULL on failure. | |
157 * | |
158 * Call setbuf(0,0) to enable unbuffered output. | |
159 */ | |
160 virtual std::streambuf* | |
161 setbuf(char_type* p, | |
162 std::streamsize n); | |
163 | |
164 /** | |
165 * @brief Flush stream buffer to file. | |
166 * @return 0 on success, -1 on error. | |
167 * | |
168 * This calls underflow(EOF) to do the job. | |
169 */ | |
170 virtual int | |
171 sync(); | |
172 | |
173 /** | |
174 * @brief Alters the stream positions. | |
175 * | |
176 * Each derived class provides its own appropriate behavior. | |
177 */ | |
178 virtual pos_type | |
179 seekoff(off_type off, std::ios_base::seekdir way, | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
180 std::ios_base::openmode mode = |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
181 std::ios_base::in|std::ios_base::out); |
5269 | 182 |
183 /** | |
184 * @brief Alters the stream positions. | |
185 * | |
186 * Each derived class provides its own appropriate behavior. | |
187 */ | |
188 virtual pos_type | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
189 seekpos(pos_type sp, std::ios_base::openmode mode = |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
190 std::ios_base::in|std::ios_base::out); |
5269 | 191 |
6777 | 192 virtual int_type |
193 pbackfail (int_type c = traits_type::eof()); | |
194 | |
5269 | 195 // |
196 // Some future enhancements | |
197 // | |
198 // virtual int_type uflow(); | |
199 // virtual int_type pbackfail(int_type c = traits_type::eof()); | |
200 | |
201 private: | |
12122
f4689107dd8c
Explicitly disallow copying in some classes.
Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
parents:
11586
diff
changeset
|
202 |
f4689107dd8c
Explicitly disallow copying in some classes.
Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
parents:
11586
diff
changeset
|
203 // No copying! |
f4689107dd8c
Explicitly disallow copying in some classes.
Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
parents:
11586
diff
changeset
|
204 |
f4689107dd8c
Explicitly disallow copying in some classes.
Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
parents:
11586
diff
changeset
|
205 gzfilebuf (const gzfilebuf&); |
f4689107dd8c
Explicitly disallow copying in some classes.
Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
parents:
11586
diff
changeset
|
206 |
f4689107dd8c
Explicitly disallow copying in some classes.
Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
parents:
11586
diff
changeset
|
207 gzfilebuf& operator = (const gzfilebuf&); |
f4689107dd8c
Explicitly disallow copying in some classes.
Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
parents:
11586
diff
changeset
|
208 |
5269 | 209 /** |
210 * @brief Allocate internal buffer. | |
211 * | |
212 * This function is safe to call multiple times. It will ensure | |
213 * that a proper internal buffer exists if it is required. If the | |
214 * buffer already exists or is external, the buffer pointers will be | |
215 * reset to their original state. | |
216 */ | |
217 void | |
218 enable_buffer(); | |
219 | |
220 /** | |
221 * @brief Destroy internal buffer. | |
222 * | |
223 * This function is safe to call multiple times. It will ensure | |
224 * that the internal buffer is deallocated if it exists. In any | |
225 * case, it will also reset the buffer pointers. | |
226 */ | |
227 void | |
228 disable_buffer(); | |
229 | |
230 /** | |
231 * Underlying file pointer. | |
232 */ | |
233 gzFile file; | |
234 | |
235 /** | |
236 * Mode in which file was opened. | |
237 */ | |
238 std::ios_base::openmode io_mode; | |
239 | |
240 /** | |
241 * @brief True if this object owns file descriptor. | |
242 * | |
243 * This makes the class responsible for closing the file | |
244 * upon destruction. | |
245 */ | |
246 bool own_fd; | |
247 | |
248 /** | |
249 * @brief Stream buffer. | |
250 * | |
251 * For simplicity this remains allocated on the free store for the | |
252 * entire life span of the gzfilebuf object, unless replaced by setbuf. | |
253 */ | |
254 char_type* buffer; | |
255 | |
256 /** | |
257 * @brief Stream buffer size. | |
258 * | |
259 * Defaults to system default buffer size (typically 8192 bytes). | |
260 * Modified by setbuf. | |
261 */ | |
262 std::streamsize buffer_size; | |
263 | |
264 /** | |
265 * @brief True if this object owns stream buffer. | |
266 * | |
267 * This makes the class responsible for deleting the buffer | |
268 * upon destruction. | |
269 */ | |
270 bool own_buffer; | |
271 }; | |
272 | |
273 /*****************************************************************************/ | |
274 | |
275 /** | |
276 * @brief Gzipped file input stream class. | |
277 * | |
278 * This class implements ifstream for gzipped files. Seeking and putback | |
279 * is not supported yet. | |
280 */ | |
281 class gzifstream : public std::istream | |
282 { | |
283 public: | |
284 // Default constructor | |
285 gzifstream(); | |
286 | |
287 /** | |
288 * @brief Construct stream on gzipped file to be opened. | |
289 * @param name File name. | |
290 * @param mode Open mode flags (forced to contain ios::in). | |
291 */ | |
292 explicit | |
293 gzifstream(const char* name, | |
294 std::ios_base::openmode mode = std::ios_base::in); | |
295 | |
296 /** | |
297 * @brief Construct stream on already open gzipped file. | |
298 * @param fd File descriptor. | |
299 * @param mode Open mode flags (forced to contain ios::in). | |
300 */ | |
301 explicit | |
302 gzifstream(int fd, | |
303 std::ios_base::openmode mode = std::ios_base::in); | |
304 | |
305 /** | |
306 * Obtain underlying stream buffer. | |
307 */ | |
308 gzfilebuf* | |
309 rdbuf() const | |
310 { return const_cast<gzfilebuf*>(&sb); } | |
311 | |
312 /** | |
313 * @brief Check if file is open. | |
314 * @return True if file is open. | |
315 */ | |
316 bool | |
317 is_open() { return sb.is_open(); } | |
318 | |
319 /** | |
320 * @brief Open gzipped file. | |
321 * @param name File name. | |
322 * @param mode Open mode flags (forced to contain ios::in). | |
323 * | |
324 * Stream will be in state good() if file opens successfully; | |
325 * otherwise in state fail(). This differs from the behavior of | |
326 * ifstream, which never sets the state to good() and therefore | |
327 * won't allow you to reuse the stream for a second file unless | |
328 * you manually clear() the state. The choice is a matter of | |
329 * convenience. | |
330 */ | |
331 void | |
332 open(const char* name, | |
333 std::ios_base::openmode mode = std::ios_base::in); | |
334 | |
335 /** | |
336 * @brief Attach to already open gzipped file. | |
337 * @param fd File descriptor. | |
338 * @param mode Open mode flags (forced to contain ios::in). | |
339 * | |
340 * Stream will be in state good() if attach succeeded; otherwise | |
341 * in state fail(). | |
342 */ | |
343 void | |
344 attach(int fd, | |
345 std::ios_base::openmode mode = std::ios_base::in); | |
346 | |
347 /** | |
348 * @brief Close gzipped file. | |
349 * | |
350 * Stream will be in state fail() if close failed. | |
351 */ | |
352 void | |
353 close(); | |
354 | |
355 private: | |
356 /** | |
357 * Underlying stream buffer. | |
358 */ | |
359 gzfilebuf sb; | |
360 }; | |
361 | |
362 /*****************************************************************************/ | |
363 | |
364 /** | |
365 * @brief Gzipped file output stream class. | |
366 * | |
367 * This class implements ofstream for gzipped files. Seeking and putback | |
368 * is not supported yet. | |
369 */ | |
370 class gzofstream : public std::ostream | |
371 { | |
372 public: | |
373 // Default constructor | |
374 gzofstream(); | |
375 | |
376 /** | |
377 * @brief Construct stream on gzipped file to be opened. | |
378 * @param name File name. | |
379 * @param mode Open mode flags (forced to contain ios::out). | |
380 */ | |
381 explicit | |
382 gzofstream(const char* name, | |
383 std::ios_base::openmode mode = std::ios_base::out); | |
384 | |
385 /** | |
386 * @brief Construct stream on already open gzipped file. | |
387 * @param fd File descriptor. | |
388 * @param mode Open mode flags (forced to contain ios::out). | |
389 */ | |
390 explicit | |
391 gzofstream(int fd, | |
392 std::ios_base::openmode mode = std::ios_base::out); | |
393 | |
394 /** | |
395 * Obtain underlying stream buffer. | |
396 */ | |
397 gzfilebuf* | |
398 rdbuf() const | |
399 { return const_cast<gzfilebuf*>(&sb); } | |
400 | |
401 /** | |
402 * @brief Check if file is open. | |
403 * @return True if file is open. | |
404 */ | |
405 bool | |
406 is_open() { return sb.is_open(); } | |
407 | |
408 /** | |
409 * @brief Open gzipped file. | |
410 * @param name File name. | |
411 * @param mode Open mode flags (forced to contain ios::out). | |
412 * | |
413 * Stream will be in state good() if file opens successfully; | |
414 * otherwise in state fail(). This differs from the behavior of | |
415 * ofstream, which never sets the state to good() and therefore | |
416 * won't allow you to reuse the stream for a second file unless | |
417 * you manually clear() the state. The choice is a matter of | |
418 * convenience. | |
419 */ | |
420 void | |
421 open(const char* name, | |
422 std::ios_base::openmode mode = std::ios_base::out); | |
423 | |
424 /** | |
425 * @brief Attach to already open gzipped file. | |
426 * @param fd File descriptor. | |
427 * @param mode Open mode flags (forced to contain ios::out). | |
428 * | |
429 * Stream will be in state good() if attach succeeded; otherwise | |
430 * in state fail(). | |
431 */ | |
432 void | |
433 attach(int fd, | |
434 std::ios_base::openmode mode = std::ios_base::out); | |
435 | |
436 /** | |
437 * @brief Close gzipped file. | |
438 * | |
439 * Stream will be in state fail() if close failed. | |
440 */ | |
441 void | |
442 close(); | |
443 | |
444 private: | |
445 /** | |
446 * Underlying stream buffer. | |
447 */ | |
448 gzfilebuf sb; | |
449 }; | |
450 | |
451 /*****************************************************************************/ | |
452 | |
453 /** | |
454 * @brief Gzipped file output stream manipulator class. | |
455 * | |
456 * This class defines a two-argument manipulator for gzofstream. It is used | |
457 * as base for the setcompression(int,int) manipulator. | |
458 */ | |
459 template<typename T1, typename T2> | |
460 class gzomanip2 | |
461 { | |
462 public: | |
463 // Allows insertor to peek at internals | |
464 template <typename Ta, typename Tb> | |
465 friend gzofstream& | |
466 operator<<(gzofstream&, | |
467 const gzomanip2<Ta,Tb>&); | |
468 | |
469 // Constructor | |
470 gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2), | |
471 T1 v1, | |
472 T2 v2); | |
473 private: | |
474 // Underlying manipulator function | |
475 gzofstream& | |
476 (*func)(gzofstream&, T1, T2); | |
477 | |
478 // Arguments for manipulator function | |
479 T1 val1; | |
480 T2 val2; | |
481 }; | |
482 | |
483 /*****************************************************************************/ | |
484 | |
485 // Manipulator function thunks through to stream buffer | |
486 inline gzofstream& | |
487 setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY) | |
488 { | |
489 (gzs.rdbuf())->setcompression(l, s); | |
490 return gzs; | |
491 } | |
492 | |
493 // Manipulator constructor stores arguments | |
494 template<typename T1, typename T2> | |
495 inline | |
496 gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2), | |
497 T1 v1, | |
498 T2 v2) | |
499 : func(f), val1(v1), val2(v2) | |
500 { } | |
501 | |
502 // Insertor applies underlying manipulator function to stream | |
503 template<typename T1, typename T2> | |
504 inline gzofstream& | |
505 operator<<(gzofstream& s, const gzomanip2<T1,T2>& m) | |
506 { return (*m.func)(s, m.val1, m.val2); } | |
507 | |
508 // Insert this onto stream to simplify setting of compression level | |
509 inline gzomanip2<int,int> | |
510 setcompression(int l, int s = Z_DEFAULT_STRATEGY) | |
511 { return gzomanip2<int,int>(&setcompression, l, s); } | |
512 | |
513 #endif // HAVE_ZLIB | |
514 | |
515 #endif // ZFSTREAM_H |