revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / z / contrib / iostream3 / zfstream.h
blob8574479ae1e7cd01cc0b0aaed2f457f7b1669603
1 /*
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.
8 */
10 #ifndef ZFSTREAM_H
11 #define ZFSTREAM_H
13 #include <istream> // not iostream, since we don't need cin/cout
14 #include <ostream>
15 #include "zlib.h"
17 /*****************************************************************************/
19 /**
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
25 * file streambuf.
27 class gzfilebuf : public std::streambuf
29 public:
30 // Default constructor.
31 gzfilebuf();
33 // Destructor.
34 virtual
35 ~gzfilebuf();
37 /**
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).
48 int
49 setcompression(int comp_level,
50 int comp_strategy = Z_DEFAULT_STRATEGY);
52 /**
53 * @brief Check if file is open.
54 * @return True if file is open.
56 bool
57 is_open() const { return (file != NULL); }
59 /**
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.
65 gzfilebuf*
66 open(const char* name,
67 std::ios_base::openmode mode);
69 /**
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.
75 gzfilebuf*
76 attach(int fd,
77 std::ios_base::openmode mode);
79 /**
80 * @brief Close gzipped file.
81 * @return @c this on success, NULL on failure.
83 gzfilebuf*
84 close();
86 protected:
87 /**
88 * @brief Convert ios open mode int to mode string used by zlib.
89 * @return True if valid mode flag combination.
91 bool
92 open_mode(std::ios_base::openmode mode,
93 char* c_mode) const;
95 /**
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
103 showmanyc();
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.
112 virtual int_type
113 underflow();
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.
124 virtual int_type
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*
136 setbuf(char_type* p,
137 std::streamsize n);
140 * @brief Flush stream buffer to file.
141 * @return 0 on success, -1 on error.
143 * This calls underflow(EOF) to do the job.
145 virtual int
146 sync();
149 // Some future enhancements
151 // virtual int_type uflow();
152 // virtual int_type pbackfail(int_type c = traits_type::eof());
153 // virtual pos_type
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);
157 // virtual pos_type
158 // seekpos(pos_type sp,
159 // std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
161 private:
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.
170 void
171 enable_buffer();
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.
180 void
181 disable_buffer();
184 * Underlying file pointer.
186 gzFile file;
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
197 * upon destruction.
199 bool own_fd;
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.
207 char_type* buffer;
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
221 * upon destruction.
223 bool own_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
236 public:
237 // Default constructor
238 gzifstream();
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).
245 explicit
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).
254 explicit
255 gzifstream(int fd,
256 std::ios_base::openmode mode = std::ios_base::in);
259 * Obtain underlying stream buffer.
261 gzfilebuf*
262 rdbuf() const
263 { return const_cast<gzfilebuf*>(&sb); }
266 * @brief Check if file is open.
267 * @return True if file is open.
269 bool
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
282 * convenience.
284 void
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
294 * in state fail().
296 void
297 attach(int fd,
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.
305 void
306 close();
308 private:
310 * Underlying stream buffer.
312 gzfilebuf sb;
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
325 public:
326 // Default constructor
327 gzofstream();
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).
334 explicit
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).
343 explicit
344 gzofstream(int fd,
345 std::ios_base::openmode mode = std::ios_base::out);
348 * Obtain underlying stream buffer.
350 gzfilebuf*
351 rdbuf() const
352 { return const_cast<gzfilebuf*>(&sb); }
355 * @brief Check if file is open.
356 * @return True if file is open.
358 bool
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
371 * convenience.
373 void
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
383 * in state fail().
385 void
386 attach(int fd,
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.
394 void
395 close();
397 private:
399 * Underlying stream buffer.
401 gzfilebuf sb;
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>
413 class gzomanip2
415 public:
416 // Allows insertor to peek at internals
417 template <typename Ta, typename Tb>
418 friend gzofstream&
419 operator<<(gzofstream&,
420 const gzomanip2<Ta,Tb>&);
422 // Constructor
423 gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
424 T1 v1,
425 T2 v2);
426 private:
427 // Underlying manipulator function
428 gzofstream&
429 (*func)(gzofstream&, T1, T2);
431 // Arguments for manipulator function
432 T1 val1;
433 T2 val2;
436 /*****************************************************************************/
438 // Manipulator function thunks through to stream buffer
439 inline gzofstream&
440 setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
442 (gzs.rdbuf())->setcompression(l, s);
443 return gzs;
446 // Manipulator constructor stores arguments
447 template<typename T1, typename T2>
448 inline
449 gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
450 T1 v1,
451 T2 v2)
452 : func(f), val1(v1), val2(v2)
455 // Insertor applies underlying manipulator function to stream
456 template<typename T1, typename T2>
457 inline gzofstream&
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); }
466 #endif // ZFSTREAM_H