2
* A C++ I/O streams interface to the zlib gz* functions
4
* by Ludwig Schwardt <schwardt@sun.ac.za>
5
* original version by Kevin Ruland <kevin@rodin.wustl.edu>
7
* This version is standard-compliant and compatible with gcc 3.x.
13
#include <istream> // not iostream, since we don't need cin/cout
17
/*****************************************************************************/
20
* @brief Gzipped file stream buffer class.
22
* This class implements basic_filebuf for gzipped files. It doesn't yet support
23
* seeking (allowed by zlib but slow/limited), putback and read/write access
24
* (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
27
class gzfilebuf : public std::streambuf
30
// Default constructor.
38
* @brief Set compression level and strategy on the fly.
39
* @param comp_level Compression level (see zlib.h for allowed values)
40
* @param comp_strategy Compression strategy (see zlib.h for allowed values)
41
* @return Z_OK on success, Z_STREAM_ERROR otherwise.
43
* Unfortunately, these parameters cannot be modified separately, as the
44
* previous zfstream version assumed. Since the strategy is seldom changed,
45
* it can default and setcompression(level) then becomes like the old
46
* setcompressionlevel(level).
49
setcompression(int comp_level,
50
int comp_strategy = Z_DEFAULT_STRATEGY);
53
* @brief Check if file is open.
54
* @return True if file is open.
57
is_open() const { return (file != NULL); }
60
* @brief Open gzipped file.
61
* @param name File name.
62
* @param mode Open mode flags.
63
* @return @c this on success, NULL on failure.
66
open(const char* name,
67
std::ios_base::openmode mode);
70
* @brief Attach to already open gzipped file.
71
* @param fd File descriptor.
72
* @param mode Open mode flags.
73
* @return @c this on success, NULL on failure.
77
std::ios_base::openmode mode);
80
* @brief Close gzipped file.
81
* @return @c this on success, NULL on failure.
88
* @brief Convert ios open mode int to mode string used by zlib.
89
* @return True if valid mode flag combination.
92
open_mode(std::ios_base::openmode mode,
96
* @brief Number of characters available in stream buffer.
97
* @return Number of characters.
99
* This indicates number of characters in get area of stream buffer.
100
* These characters can be read without accessing the gzipped file.
102
virtual std::streamsize
106
* @brief Fill get area from gzipped file.
107
* @return First character in get area on success, EOF on error.
109
* This actually reads characters from gzipped file to stream
110
* buffer. Always buffered.
116
* @brief Write put area to gzipped file.
117
* @param c Extra character to add to buffer contents.
118
* @return Non-EOF on success, EOF on error.
120
* This actually writes characters in stream buffer to
121
* gzipped file. With unbuffered output this is done one
122
* character at a time.
125
overflow(int_type c = traits_type::eof());
128
* @brief Installs external stream buffer.
129
* @param p Pointer to char buffer.
130
* @param n Size of external buffer.
131
* @return @c this on success, NULL on failure.
133
* Call setbuf(0,0) to enable unbuffered output.
135
virtual std::streambuf*
140
* @brief Flush stream buffer to file.
141
* @return 0 on success, -1 on error.
143
* This calls underflow(EOF) to do the job.
149
// Some future enhancements
151
// virtual int_type uflow();
152
// virtual int_type pbackfail(int_type c = traits_type::eof());
154
// seekoff(off_type off,
155
// std::ios_base::seekdir way,
156
// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
158
// seekpos(pos_type sp,
159
// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
163
* @brief Allocate internal buffer.
165
* This function is safe to call multiple times. It will ensure
166
* that a proper internal buffer exists if it is required. If the
167
* buffer already exists or is external, the buffer pointers will be
168
* reset to their original state.
174
* @brief Destroy internal buffer.
176
* This function is safe to call multiple times. It will ensure
177
* that the internal buffer is deallocated if it exists. In any
178
* case, it will also reset the buffer pointers.
184
* Underlying file pointer.
189
* Mode in which file was opened.
191
std::ios_base::openmode io_mode;
194
* @brief True if this object owns file descriptor.
196
* This makes the class responsible for closing the file
202
* @brief Stream buffer.
204
* For simplicity this remains allocated on the free store for the
205
* entire life span of the gzfilebuf object, unless replaced by setbuf.
210
* @brief Stream buffer size.
212
* Defaults to system default buffer size (typically 8192 bytes).
213
* Modified by setbuf.
215
std::streamsize buffer_size;
218
* @brief True if this object owns stream buffer.
220
* This makes the class responsible for deleting the buffer
226
/*****************************************************************************/
229
* @brief Gzipped file input stream class.
231
* This class implements ifstream for gzipped files. Seeking and putback
232
* is not supported yet.
234
class gzifstream : public std::istream
237
// Default constructor
241
* @brief Construct stream on gzipped file to be opened.
242
* @param name File name.
243
* @param mode Open mode flags (forced to contain ios::in).
246
gzifstream(const char* name,
247
std::ios_base::openmode mode = std::ios_base::in);
250
* @brief Construct stream on already open gzipped file.
251
* @param fd File descriptor.
252
* @param mode Open mode flags (forced to contain ios::in).
256
std::ios_base::openmode mode = std::ios_base::in);
259
* Obtain underlying stream buffer.
263
{ return const_cast<gzfilebuf*>(&sb); }
266
* @brief Check if file is open.
267
* @return True if file is open.
270
is_open() { return sb.is_open(); }
273
* @brief Open gzipped file.
274
* @param name File name.
275
* @param mode Open mode flags (forced to contain ios::in).
277
* Stream will be in state good() if file opens successfully;
278
* otherwise in state fail(). This differs from the behavior of
279
* ifstream, which never sets the state to good() and therefore
280
* won't allow you to reuse the stream for a second file unless
281
* you manually clear() the state. The choice is a matter of
285
open(const char* name,
286
std::ios_base::openmode mode = std::ios_base::in);
289
* @brief Attach to already open gzipped file.
290
* @param fd File descriptor.
291
* @param mode Open mode flags (forced to contain ios::in).
293
* Stream will be in state good() if attach succeeded; otherwise
298
std::ios_base::openmode mode = std::ios_base::in);
301
* @brief Close gzipped file.
303
* Stream will be in state fail() if close failed.
310
* Underlying stream buffer.
315
/*****************************************************************************/
318
* @brief Gzipped file output stream class.
320
* This class implements ofstream for gzipped files. Seeking and putback
321
* is not supported yet.
323
class gzofstream : public std::ostream
326
// Default constructor
330
* @brief Construct stream on gzipped file to be opened.
331
* @param name File name.
332
* @param mode Open mode flags (forced to contain ios::out).
335
gzofstream(const char* name,
336
std::ios_base::openmode mode = std::ios_base::out);
339
* @brief Construct stream on already open gzipped file.
340
* @param fd File descriptor.
341
* @param mode Open mode flags (forced to contain ios::out).
345
std::ios_base::openmode mode = std::ios_base::out);
348
* Obtain underlying stream buffer.
352
{ return const_cast<gzfilebuf*>(&sb); }
355
* @brief Check if file is open.
356
* @return True if file is open.
359
is_open() { return sb.is_open(); }
362
* @brief Open gzipped file.
363
* @param name File name.
364
* @param mode Open mode flags (forced to contain ios::out).
366
* Stream will be in state good() if file opens successfully;
367
* otherwise in state fail(). This differs from the behavior of
368
* ofstream, which never sets the state to good() and therefore
369
* won't allow you to reuse the stream for a second file unless
370
* you manually clear() the state. The choice is a matter of
374
open(const char* name,
375
std::ios_base::openmode mode = std::ios_base::out);
378
* @brief Attach to already open gzipped file.
379
* @param fd File descriptor.
380
* @param mode Open mode flags (forced to contain ios::out).
382
* Stream will be in state good() if attach succeeded; otherwise
387
std::ios_base::openmode mode = std::ios_base::out);
390
* @brief Close gzipped file.
392
* Stream will be in state fail() if close failed.
399
* Underlying stream buffer.
404
/*****************************************************************************/
407
* @brief Gzipped file output stream manipulator class.
409
* This class defines a two-argument manipulator for gzofstream. It is used
410
* as base for the setcompression(int,int) manipulator.
412
template<typename T1, typename T2>
416
// Allows insertor to peek at internals
417
template <typename Ta, typename Tb>
419
operator<<(gzofstream&,
420
const gzomanip2<Ta,Tb>&);
423
gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
427
// Underlying manipulator function
429
(*func)(gzofstream&, T1, T2);
431
// Arguments for manipulator function
436
/*****************************************************************************/
438
// Manipulator function thunks through to stream buffer
440
setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
442
(gzs.rdbuf())->setcompression(l, s);
446
// Manipulator constructor stores arguments
447
template<typename T1, typename T2>
449
gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
452
: func(f), val1(v1), val2(v2)
455
// Insertor applies underlying manipulator function to stream
456
template<typename T1, typename T2>
458
operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
459
{ return (*m.func)(s, m.val1, m.val2); }
461
// Insert this onto stream to simplify setting of compression level
462
inline gzomanip2<int,int>
463
setcompression(int l, int s = Z_DEFAULT_STRATEGY)
464
{ return gzomanip2<int,int>(&setcompression, l, s); }