xref: /minix3/common/dist/zlib/contrib/iostream3/zfstream.h (revision 44bedb31d842b4b0444105519bcf929a69fe2dc1)
1*44bedb31SLionel Sambuc /*	$NetBSD: zfstream.h,v 1.1.1.1 2006/01/14 20:10:54 christos Exp $	*/
2*44bedb31SLionel Sambuc 
3*44bedb31SLionel Sambuc /*
4*44bedb31SLionel Sambuc  * A C++ I/O streams interface to the zlib gz* functions
5*44bedb31SLionel Sambuc  *
6*44bedb31SLionel Sambuc  * by Ludwig Schwardt <schwardt@sun.ac.za>
7*44bedb31SLionel Sambuc  * original version by Kevin Ruland <kevin@rodin.wustl.edu>
8*44bedb31SLionel Sambuc  *
9*44bedb31SLionel Sambuc  * This version is standard-compliant and compatible with gcc 3.x.
10*44bedb31SLionel Sambuc  */
11*44bedb31SLionel Sambuc 
12*44bedb31SLionel Sambuc #ifndef ZFSTREAM_H
13*44bedb31SLionel Sambuc #define ZFSTREAM_H
14*44bedb31SLionel Sambuc 
15*44bedb31SLionel Sambuc #include <istream>  // not iostream, since we don't need cin/cout
16*44bedb31SLionel Sambuc #include <ostream>
17*44bedb31SLionel Sambuc #include "zlib.h"
18*44bedb31SLionel Sambuc 
19*44bedb31SLionel Sambuc /*****************************************************************************/
20*44bedb31SLionel Sambuc 
21*44bedb31SLionel Sambuc /**
22*44bedb31SLionel Sambuc  *  @brief  Gzipped file stream buffer class.
23*44bedb31SLionel Sambuc  *
24*44bedb31SLionel Sambuc  *  This class implements basic_filebuf for gzipped files. It doesn't yet support
25*44bedb31SLionel Sambuc  *  seeking (allowed by zlib but slow/limited), putback and read/write access
26*44bedb31SLionel Sambuc  *  (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
27*44bedb31SLionel Sambuc  *  file streambuf.
28*44bedb31SLionel Sambuc */
29*44bedb31SLionel Sambuc class gzfilebuf : public std::streambuf
30*44bedb31SLionel Sambuc {
31*44bedb31SLionel Sambuc public:
32*44bedb31SLionel Sambuc   //  Default constructor.
33*44bedb31SLionel Sambuc   gzfilebuf();
34*44bedb31SLionel Sambuc 
35*44bedb31SLionel Sambuc   //  Destructor.
36*44bedb31SLionel Sambuc   virtual
37*44bedb31SLionel Sambuc   ~gzfilebuf();
38*44bedb31SLionel Sambuc 
39*44bedb31SLionel Sambuc   /**
40*44bedb31SLionel Sambuc    *  @brief  Set compression level and strategy on the fly.
41*44bedb31SLionel Sambuc    *  @param  comp_level  Compression level (see zlib.h for allowed values)
42*44bedb31SLionel Sambuc    *  @param  comp_strategy  Compression strategy (see zlib.h for allowed values)
43*44bedb31SLionel Sambuc    *  @return  Z_OK on success, Z_STREAM_ERROR otherwise.
44*44bedb31SLionel Sambuc    *
45*44bedb31SLionel Sambuc    *  Unfortunately, these parameters cannot be modified separately, as the
46*44bedb31SLionel Sambuc    *  previous zfstream version assumed. Since the strategy is seldom changed,
47*44bedb31SLionel Sambuc    *  it can default and setcompression(level) then becomes like the old
48*44bedb31SLionel Sambuc    *  setcompressionlevel(level).
49*44bedb31SLionel Sambuc   */
50*44bedb31SLionel Sambuc   int
51*44bedb31SLionel Sambuc   setcompression(int comp_level,
52*44bedb31SLionel Sambuc                  int comp_strategy = Z_DEFAULT_STRATEGY);
53*44bedb31SLionel Sambuc 
54*44bedb31SLionel Sambuc   /**
55*44bedb31SLionel Sambuc    *  @brief  Check if file is open.
56*44bedb31SLionel Sambuc    *  @return  True if file is open.
57*44bedb31SLionel Sambuc   */
58*44bedb31SLionel Sambuc   bool
is_open()59*44bedb31SLionel Sambuc   is_open() const { return (file != NULL); }
60*44bedb31SLionel Sambuc 
61*44bedb31SLionel Sambuc   /**
62*44bedb31SLionel Sambuc    *  @brief  Open gzipped file.
63*44bedb31SLionel Sambuc    *  @param  name  File name.
64*44bedb31SLionel Sambuc    *  @param  mode  Open mode flags.
65*44bedb31SLionel Sambuc    *  @return  @c this on success, NULL on failure.
66*44bedb31SLionel Sambuc   */
67*44bedb31SLionel Sambuc   gzfilebuf*
68*44bedb31SLionel Sambuc   open(const char* name,
69*44bedb31SLionel Sambuc        std::ios_base::openmode mode);
70*44bedb31SLionel Sambuc 
71*44bedb31SLionel Sambuc   /**
72*44bedb31SLionel Sambuc    *  @brief  Attach to already open gzipped file.
73*44bedb31SLionel Sambuc    *  @param  fd  File descriptor.
74*44bedb31SLionel Sambuc    *  @param  mode  Open mode flags.
75*44bedb31SLionel Sambuc    *  @return  @c this on success, NULL on failure.
76*44bedb31SLionel Sambuc   */
77*44bedb31SLionel Sambuc   gzfilebuf*
78*44bedb31SLionel Sambuc   attach(int fd,
79*44bedb31SLionel Sambuc          std::ios_base::openmode mode);
80*44bedb31SLionel Sambuc 
81*44bedb31SLionel Sambuc   /**
82*44bedb31SLionel Sambuc    *  @brief  Close gzipped file.
83*44bedb31SLionel Sambuc    *  @return  @c this on success, NULL on failure.
84*44bedb31SLionel Sambuc   */
85*44bedb31SLionel Sambuc   gzfilebuf*
86*44bedb31SLionel Sambuc   close();
87*44bedb31SLionel Sambuc 
88*44bedb31SLionel Sambuc protected:
89*44bedb31SLionel Sambuc   /**
90*44bedb31SLionel Sambuc    *  @brief  Convert ios open mode int to mode string used by zlib.
91*44bedb31SLionel Sambuc    *  @return  True if valid mode flag combination.
92*44bedb31SLionel Sambuc   */
93*44bedb31SLionel Sambuc   bool
94*44bedb31SLionel Sambuc   open_mode(std::ios_base::openmode mode,
95*44bedb31SLionel Sambuc             char* c_mode) const;
96*44bedb31SLionel Sambuc 
97*44bedb31SLionel Sambuc   /**
98*44bedb31SLionel Sambuc    *  @brief  Number of characters available in stream buffer.
99*44bedb31SLionel Sambuc    *  @return  Number of characters.
100*44bedb31SLionel Sambuc    *
101*44bedb31SLionel Sambuc    *  This indicates number of characters in get area of stream buffer.
102*44bedb31SLionel Sambuc    *  These characters can be read without accessing the gzipped file.
103*44bedb31SLionel Sambuc   */
104*44bedb31SLionel Sambuc   virtual std::streamsize
105*44bedb31SLionel Sambuc   showmanyc();
106*44bedb31SLionel Sambuc 
107*44bedb31SLionel Sambuc   /**
108*44bedb31SLionel Sambuc    *  @brief  Fill get area from gzipped file.
109*44bedb31SLionel Sambuc    *  @return  First character in get area on success, EOF on error.
110*44bedb31SLionel Sambuc    *
111*44bedb31SLionel Sambuc    *  This actually reads characters from gzipped file to stream
112*44bedb31SLionel Sambuc    *  buffer. Always buffered.
113*44bedb31SLionel Sambuc   */
114*44bedb31SLionel Sambuc   virtual int_type
115*44bedb31SLionel Sambuc   underflow();
116*44bedb31SLionel Sambuc 
117*44bedb31SLionel Sambuc   /**
118*44bedb31SLionel Sambuc    *  @brief  Write put area to gzipped file.
119*44bedb31SLionel Sambuc    *  @param  c  Extra character to add to buffer contents.
120*44bedb31SLionel Sambuc    *  @return  Non-EOF on success, EOF on error.
121*44bedb31SLionel Sambuc    *
122*44bedb31SLionel Sambuc    *  This actually writes characters in stream buffer to
123*44bedb31SLionel Sambuc    *  gzipped file. With unbuffered output this is done one
124*44bedb31SLionel Sambuc    *  character at a time.
125*44bedb31SLionel Sambuc   */
126*44bedb31SLionel Sambuc   virtual int_type
127*44bedb31SLionel Sambuc   overflow(int_type c = traits_type::eof());
128*44bedb31SLionel Sambuc 
129*44bedb31SLionel Sambuc   /**
130*44bedb31SLionel Sambuc    *  @brief  Installs external stream buffer.
131*44bedb31SLionel Sambuc    *  @param  p  Pointer to char buffer.
132*44bedb31SLionel Sambuc    *  @param  n  Size of external buffer.
133*44bedb31SLionel Sambuc    *  @return  @c this on success, NULL on failure.
134*44bedb31SLionel Sambuc    *
135*44bedb31SLionel Sambuc    *  Call setbuf(0,0) to enable unbuffered output.
136*44bedb31SLionel Sambuc   */
137*44bedb31SLionel Sambuc   virtual std::streambuf*
138*44bedb31SLionel Sambuc   setbuf(char_type* p,
139*44bedb31SLionel Sambuc          std::streamsize n);
140*44bedb31SLionel Sambuc 
141*44bedb31SLionel Sambuc   /**
142*44bedb31SLionel Sambuc    *  @brief  Flush stream buffer to file.
143*44bedb31SLionel Sambuc    *  @return  0 on success, -1 on error.
144*44bedb31SLionel Sambuc    *
145*44bedb31SLionel Sambuc    *  This calls underflow(EOF) to do the job.
146*44bedb31SLionel Sambuc   */
147*44bedb31SLionel Sambuc   virtual int
148*44bedb31SLionel Sambuc   sync();
149*44bedb31SLionel Sambuc 
150*44bedb31SLionel Sambuc //
151*44bedb31SLionel Sambuc // Some future enhancements
152*44bedb31SLionel Sambuc //
153*44bedb31SLionel Sambuc //  virtual int_type uflow();
154*44bedb31SLionel Sambuc //  virtual int_type pbackfail(int_type c = traits_type::eof());
155*44bedb31SLionel Sambuc //  virtual pos_type
156*44bedb31SLionel Sambuc //  seekoff(off_type off,
157*44bedb31SLionel Sambuc //          std::ios_base::seekdir way,
158*44bedb31SLionel Sambuc //          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
159*44bedb31SLionel Sambuc //  virtual pos_type
160*44bedb31SLionel Sambuc //  seekpos(pos_type sp,
161*44bedb31SLionel Sambuc //          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
162*44bedb31SLionel Sambuc 
163*44bedb31SLionel Sambuc private:
164*44bedb31SLionel Sambuc   /**
165*44bedb31SLionel Sambuc    *  @brief  Allocate internal buffer.
166*44bedb31SLionel Sambuc    *
167*44bedb31SLionel Sambuc    *  This function is safe to call multiple times. It will ensure
168*44bedb31SLionel Sambuc    *  that a proper internal buffer exists if it is required. If the
169*44bedb31SLionel Sambuc    *  buffer already exists or is external, the buffer pointers will be
170*44bedb31SLionel Sambuc    *  reset to their original state.
171*44bedb31SLionel Sambuc   */
172*44bedb31SLionel Sambuc   void
173*44bedb31SLionel Sambuc   enable_buffer();
174*44bedb31SLionel Sambuc 
175*44bedb31SLionel Sambuc   /**
176*44bedb31SLionel Sambuc    *  @brief  Destroy internal buffer.
177*44bedb31SLionel Sambuc    *
178*44bedb31SLionel Sambuc    *  This function is safe to call multiple times. It will ensure
179*44bedb31SLionel Sambuc    *  that the internal buffer is deallocated if it exists. In any
180*44bedb31SLionel Sambuc    *  case, it will also reset the buffer pointers.
181*44bedb31SLionel Sambuc   */
182*44bedb31SLionel Sambuc   void
183*44bedb31SLionel Sambuc   disable_buffer();
184*44bedb31SLionel Sambuc 
185*44bedb31SLionel Sambuc   /**
186*44bedb31SLionel Sambuc    *  Underlying file pointer.
187*44bedb31SLionel Sambuc   */
188*44bedb31SLionel Sambuc   gzFile file;
189*44bedb31SLionel Sambuc 
190*44bedb31SLionel Sambuc   /**
191*44bedb31SLionel Sambuc    *  Mode in which file was opened.
192*44bedb31SLionel Sambuc   */
193*44bedb31SLionel Sambuc   std::ios_base::openmode io_mode;
194*44bedb31SLionel Sambuc 
195*44bedb31SLionel Sambuc   /**
196*44bedb31SLionel Sambuc    *  @brief  True if this object owns file descriptor.
197*44bedb31SLionel Sambuc    *
198*44bedb31SLionel Sambuc    *  This makes the class responsible for closing the file
199*44bedb31SLionel Sambuc    *  upon destruction.
200*44bedb31SLionel Sambuc   */
201*44bedb31SLionel Sambuc   bool own_fd;
202*44bedb31SLionel Sambuc 
203*44bedb31SLionel Sambuc   /**
204*44bedb31SLionel Sambuc    *  @brief  Stream buffer.
205*44bedb31SLionel Sambuc    *
206*44bedb31SLionel Sambuc    *  For simplicity this remains allocated on the free store for the
207*44bedb31SLionel Sambuc    *  entire life span of the gzfilebuf object, unless replaced by setbuf.
208*44bedb31SLionel Sambuc   */
209*44bedb31SLionel Sambuc   char_type* buffer;
210*44bedb31SLionel Sambuc 
211*44bedb31SLionel Sambuc   /**
212*44bedb31SLionel Sambuc    *  @brief  Stream buffer size.
213*44bedb31SLionel Sambuc    *
214*44bedb31SLionel Sambuc    *  Defaults to system default buffer size (typically 8192 bytes).
215*44bedb31SLionel Sambuc    *  Modified by setbuf.
216*44bedb31SLionel Sambuc   */
217*44bedb31SLionel Sambuc   std::streamsize buffer_size;
218*44bedb31SLionel Sambuc 
219*44bedb31SLionel Sambuc   /**
220*44bedb31SLionel Sambuc    *  @brief  True if this object owns stream buffer.
221*44bedb31SLionel Sambuc    *
222*44bedb31SLionel Sambuc    *  This makes the class responsible for deleting the buffer
223*44bedb31SLionel Sambuc    *  upon destruction.
224*44bedb31SLionel Sambuc   */
225*44bedb31SLionel Sambuc   bool own_buffer;
226*44bedb31SLionel Sambuc };
227*44bedb31SLionel Sambuc 
228*44bedb31SLionel Sambuc /*****************************************************************************/
229*44bedb31SLionel Sambuc 
230*44bedb31SLionel Sambuc /**
231*44bedb31SLionel Sambuc  *  @brief  Gzipped file input stream class.
232*44bedb31SLionel Sambuc  *
233*44bedb31SLionel Sambuc  *  This class implements ifstream for gzipped files. Seeking and putback
234*44bedb31SLionel Sambuc  *  is not supported yet.
235*44bedb31SLionel Sambuc */
236*44bedb31SLionel Sambuc class gzifstream : public std::istream
237*44bedb31SLionel Sambuc {
238*44bedb31SLionel Sambuc public:
239*44bedb31SLionel Sambuc   //  Default constructor
240*44bedb31SLionel Sambuc   gzifstream();
241*44bedb31SLionel Sambuc 
242*44bedb31SLionel Sambuc   /**
243*44bedb31SLionel Sambuc    *  @brief  Construct stream on gzipped file to be opened.
244*44bedb31SLionel Sambuc    *  @param  name  File name.
245*44bedb31SLionel Sambuc    *  @param  mode  Open mode flags (forced to contain ios::in).
246*44bedb31SLionel Sambuc   */
247*44bedb31SLionel Sambuc   explicit
248*44bedb31SLionel Sambuc   gzifstream(const char* name,
249*44bedb31SLionel Sambuc              std::ios_base::openmode mode = std::ios_base::in);
250*44bedb31SLionel Sambuc 
251*44bedb31SLionel Sambuc   /**
252*44bedb31SLionel Sambuc    *  @brief  Construct stream on already open gzipped file.
253*44bedb31SLionel Sambuc    *  @param  fd    File descriptor.
254*44bedb31SLionel Sambuc    *  @param  mode  Open mode flags (forced to contain ios::in).
255*44bedb31SLionel Sambuc   */
256*44bedb31SLionel Sambuc   explicit
257*44bedb31SLionel Sambuc   gzifstream(int fd,
258*44bedb31SLionel Sambuc              std::ios_base::openmode mode = std::ios_base::in);
259*44bedb31SLionel Sambuc 
260*44bedb31SLionel Sambuc   /**
261*44bedb31SLionel Sambuc    *  Obtain underlying stream buffer.
262*44bedb31SLionel Sambuc   */
263*44bedb31SLionel Sambuc   gzfilebuf*
rdbuf()264*44bedb31SLionel Sambuc   rdbuf() const
265*44bedb31SLionel Sambuc   { return const_cast<gzfilebuf*>(&sb); }
266*44bedb31SLionel Sambuc 
267*44bedb31SLionel Sambuc   /**
268*44bedb31SLionel Sambuc    *  @brief  Check if file is open.
269*44bedb31SLionel Sambuc    *  @return  True if file is open.
270*44bedb31SLionel Sambuc   */
271*44bedb31SLionel Sambuc   bool
is_open()272*44bedb31SLionel Sambuc   is_open() { return sb.is_open(); }
273*44bedb31SLionel Sambuc 
274*44bedb31SLionel Sambuc   /**
275*44bedb31SLionel Sambuc    *  @brief  Open gzipped file.
276*44bedb31SLionel Sambuc    *  @param  name  File name.
277*44bedb31SLionel Sambuc    *  @param  mode  Open mode flags (forced to contain ios::in).
278*44bedb31SLionel Sambuc    *
279*44bedb31SLionel Sambuc    *  Stream will be in state good() if file opens successfully;
280*44bedb31SLionel Sambuc    *  otherwise in state fail(). This differs from the behavior of
281*44bedb31SLionel Sambuc    *  ifstream, which never sets the state to good() and therefore
282*44bedb31SLionel Sambuc    *  won't allow you to reuse the stream for a second file unless
283*44bedb31SLionel Sambuc    *  you manually clear() the state. The choice is a matter of
284*44bedb31SLionel Sambuc    *  convenience.
285*44bedb31SLionel Sambuc   */
286*44bedb31SLionel Sambuc   void
287*44bedb31SLionel Sambuc   open(const char* name,
288*44bedb31SLionel Sambuc        std::ios_base::openmode mode = std::ios_base::in);
289*44bedb31SLionel Sambuc 
290*44bedb31SLionel Sambuc   /**
291*44bedb31SLionel Sambuc    *  @brief  Attach to already open gzipped file.
292*44bedb31SLionel Sambuc    *  @param  fd  File descriptor.
293*44bedb31SLionel Sambuc    *  @param  mode  Open mode flags (forced to contain ios::in).
294*44bedb31SLionel Sambuc    *
295*44bedb31SLionel Sambuc    *  Stream will be in state good() if attach succeeded; otherwise
296*44bedb31SLionel Sambuc    *  in state fail().
297*44bedb31SLionel Sambuc   */
298*44bedb31SLionel Sambuc   void
299*44bedb31SLionel Sambuc   attach(int fd,
300*44bedb31SLionel Sambuc          std::ios_base::openmode mode = std::ios_base::in);
301*44bedb31SLionel Sambuc 
302*44bedb31SLionel Sambuc   /**
303*44bedb31SLionel Sambuc    *  @brief  Close gzipped file.
304*44bedb31SLionel Sambuc    *
305*44bedb31SLionel Sambuc    *  Stream will be in state fail() if close failed.
306*44bedb31SLionel Sambuc   */
307*44bedb31SLionel Sambuc   void
308*44bedb31SLionel Sambuc   close();
309*44bedb31SLionel Sambuc 
310*44bedb31SLionel Sambuc private:
311*44bedb31SLionel Sambuc   /**
312*44bedb31SLionel Sambuc    *  Underlying stream buffer.
313*44bedb31SLionel Sambuc   */
314*44bedb31SLionel Sambuc   gzfilebuf sb;
315*44bedb31SLionel Sambuc };
316*44bedb31SLionel Sambuc 
317*44bedb31SLionel Sambuc /*****************************************************************************/
318*44bedb31SLionel Sambuc 
319*44bedb31SLionel Sambuc /**
320*44bedb31SLionel Sambuc  *  @brief  Gzipped file output stream class.
321*44bedb31SLionel Sambuc  *
322*44bedb31SLionel Sambuc  *  This class implements ofstream for gzipped files. Seeking and putback
323*44bedb31SLionel Sambuc  *  is not supported yet.
324*44bedb31SLionel Sambuc */
325*44bedb31SLionel Sambuc class gzofstream : public std::ostream
326*44bedb31SLionel Sambuc {
327*44bedb31SLionel Sambuc public:
328*44bedb31SLionel Sambuc   //  Default constructor
329*44bedb31SLionel Sambuc   gzofstream();
330*44bedb31SLionel Sambuc 
331*44bedb31SLionel Sambuc   /**
332*44bedb31SLionel Sambuc    *  @brief  Construct stream on gzipped file to be opened.
333*44bedb31SLionel Sambuc    *  @param  name  File name.
334*44bedb31SLionel Sambuc    *  @param  mode  Open mode flags (forced to contain ios::out).
335*44bedb31SLionel Sambuc   */
336*44bedb31SLionel Sambuc   explicit
337*44bedb31SLionel Sambuc   gzofstream(const char* name,
338*44bedb31SLionel Sambuc              std::ios_base::openmode mode = std::ios_base::out);
339*44bedb31SLionel Sambuc 
340*44bedb31SLionel Sambuc   /**
341*44bedb31SLionel Sambuc    *  @brief  Construct stream on already open gzipped file.
342*44bedb31SLionel Sambuc    *  @param  fd    File descriptor.
343*44bedb31SLionel Sambuc    *  @param  mode  Open mode flags (forced to contain ios::out).
344*44bedb31SLionel Sambuc   */
345*44bedb31SLionel Sambuc   explicit
346*44bedb31SLionel Sambuc   gzofstream(int fd,
347*44bedb31SLionel Sambuc              std::ios_base::openmode mode = std::ios_base::out);
348*44bedb31SLionel Sambuc 
349*44bedb31SLionel Sambuc   /**
350*44bedb31SLionel Sambuc    *  Obtain underlying stream buffer.
351*44bedb31SLionel Sambuc   */
352*44bedb31SLionel Sambuc   gzfilebuf*
rdbuf()353*44bedb31SLionel Sambuc   rdbuf() const
354*44bedb31SLionel Sambuc   { return const_cast<gzfilebuf*>(&sb); }
355*44bedb31SLionel Sambuc 
356*44bedb31SLionel Sambuc   /**
357*44bedb31SLionel Sambuc    *  @brief  Check if file is open.
358*44bedb31SLionel Sambuc    *  @return  True if file is open.
359*44bedb31SLionel Sambuc   */
360*44bedb31SLionel Sambuc   bool
is_open()361*44bedb31SLionel Sambuc   is_open() { return sb.is_open(); }
362*44bedb31SLionel Sambuc 
363*44bedb31SLionel Sambuc   /**
364*44bedb31SLionel Sambuc    *  @brief  Open gzipped file.
365*44bedb31SLionel Sambuc    *  @param  name  File name.
366*44bedb31SLionel Sambuc    *  @param  mode  Open mode flags (forced to contain ios::out).
367*44bedb31SLionel Sambuc    *
368*44bedb31SLionel Sambuc    *  Stream will be in state good() if file opens successfully;
369*44bedb31SLionel Sambuc    *  otherwise in state fail(). This differs from the behavior of
370*44bedb31SLionel Sambuc    *  ofstream, which never sets the state to good() and therefore
371*44bedb31SLionel Sambuc    *  won't allow you to reuse the stream for a second file unless
372*44bedb31SLionel Sambuc    *  you manually clear() the state. The choice is a matter of
373*44bedb31SLionel Sambuc    *  convenience.
374*44bedb31SLionel Sambuc   */
375*44bedb31SLionel Sambuc   void
376*44bedb31SLionel Sambuc   open(const char* name,
377*44bedb31SLionel Sambuc        std::ios_base::openmode mode = std::ios_base::out);
378*44bedb31SLionel Sambuc 
379*44bedb31SLionel Sambuc   /**
380*44bedb31SLionel Sambuc    *  @brief  Attach to already open gzipped file.
381*44bedb31SLionel Sambuc    *  @param  fd  File descriptor.
382*44bedb31SLionel Sambuc    *  @param  mode  Open mode flags (forced to contain ios::out).
383*44bedb31SLionel Sambuc    *
384*44bedb31SLionel Sambuc    *  Stream will be in state good() if attach succeeded; otherwise
385*44bedb31SLionel Sambuc    *  in state fail().
386*44bedb31SLionel Sambuc   */
387*44bedb31SLionel Sambuc   void
388*44bedb31SLionel Sambuc   attach(int fd,
389*44bedb31SLionel Sambuc          std::ios_base::openmode mode = std::ios_base::out);
390*44bedb31SLionel Sambuc 
391*44bedb31SLionel Sambuc   /**
392*44bedb31SLionel Sambuc    *  @brief  Close gzipped file.
393*44bedb31SLionel Sambuc    *
394*44bedb31SLionel Sambuc    *  Stream will be in state fail() if close failed.
395*44bedb31SLionel Sambuc   */
396*44bedb31SLionel Sambuc   void
397*44bedb31SLionel Sambuc   close();
398*44bedb31SLionel Sambuc 
399*44bedb31SLionel Sambuc private:
400*44bedb31SLionel Sambuc   /**
401*44bedb31SLionel Sambuc    *  Underlying stream buffer.
402*44bedb31SLionel Sambuc   */
403*44bedb31SLionel Sambuc   gzfilebuf sb;
404*44bedb31SLionel Sambuc };
405*44bedb31SLionel Sambuc 
406*44bedb31SLionel Sambuc /*****************************************************************************/
407*44bedb31SLionel Sambuc 
408*44bedb31SLionel Sambuc /**
409*44bedb31SLionel Sambuc  *  @brief  Gzipped file output stream manipulator class.
410*44bedb31SLionel Sambuc  *
411*44bedb31SLionel Sambuc  *  This class defines a two-argument manipulator for gzofstream. It is used
412*44bedb31SLionel Sambuc  *  as base for the setcompression(int,int) manipulator.
413*44bedb31SLionel Sambuc */
414*44bedb31SLionel Sambuc template<typename T1, typename T2>
415*44bedb31SLionel Sambuc   class gzomanip2
416*44bedb31SLionel Sambuc   {
417*44bedb31SLionel Sambuc   public:
418*44bedb31SLionel Sambuc     // Allows insertor to peek at internals
419*44bedb31SLionel Sambuc     template <typename Ta, typename Tb>
420*44bedb31SLionel Sambuc       friend gzofstream&
421*44bedb31SLionel Sambuc       operator<<(gzofstream&,
422*44bedb31SLionel Sambuc                  const gzomanip2<Ta,Tb>&);
423*44bedb31SLionel Sambuc 
424*44bedb31SLionel Sambuc     // Constructor
425*44bedb31SLionel Sambuc     gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
426*44bedb31SLionel Sambuc               T1 v1,
427*44bedb31SLionel Sambuc               T2 v2);
428*44bedb31SLionel Sambuc   private:
429*44bedb31SLionel Sambuc     // Underlying manipulator function
430*44bedb31SLionel Sambuc     gzofstream&
431*44bedb31SLionel Sambuc     (*func)(gzofstream&, T1, T2);
432*44bedb31SLionel Sambuc 
433*44bedb31SLionel Sambuc     // Arguments for manipulator function
434*44bedb31SLionel Sambuc     T1 val1;
435*44bedb31SLionel Sambuc     T2 val2;
436*44bedb31SLionel Sambuc   };
437*44bedb31SLionel Sambuc 
438*44bedb31SLionel Sambuc /*****************************************************************************/
439*44bedb31SLionel Sambuc 
440*44bedb31SLionel Sambuc // Manipulator function thunks through to stream buffer
441*44bedb31SLionel Sambuc inline gzofstream&
442*44bedb31SLionel Sambuc setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
443*44bedb31SLionel Sambuc {
444*44bedb31SLionel Sambuc   (gzs.rdbuf())->setcompression(l, s);
445*44bedb31SLionel Sambuc   return gzs;
446*44bedb31SLionel Sambuc }
447*44bedb31SLionel Sambuc 
448*44bedb31SLionel Sambuc // Manipulator constructor stores arguments
449*44bedb31SLionel Sambuc template<typename T1, typename T2>
450*44bedb31SLionel Sambuc   inline
gzomanip2(gzofstream & (* f)(gzofstream &,T1,T2),T1 v1,T2 v2)451*44bedb31SLionel Sambuc   gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
452*44bedb31SLionel Sambuc                               T1 v1,
453*44bedb31SLionel Sambuc                               T2 v2)
454*44bedb31SLionel Sambuc   : func(f), val1(v1), val2(v2)
455*44bedb31SLionel Sambuc   { }
456*44bedb31SLionel Sambuc 
457*44bedb31SLionel Sambuc // Insertor applies underlying manipulator function to stream
458*44bedb31SLionel Sambuc template<typename T1, typename T2>
459*44bedb31SLionel Sambuc   inline gzofstream&
460*44bedb31SLionel Sambuc   operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
461*44bedb31SLionel Sambuc   { return (*m.func)(s, m.val1, m.val2); }
462*44bedb31SLionel Sambuc 
463*44bedb31SLionel Sambuc // Insert this onto stream to simplify setting of compression level
464*44bedb31SLionel Sambuc inline gzomanip2<int,int>
465*44bedb31SLionel Sambuc setcompression(int l, int s = Z_DEFAULT_STRATEGY)
466*44bedb31SLionel Sambuc { return gzomanip2<int,int>(&setcompression, l, s); }
467*44bedb31SLionel Sambuc 
468*44bedb31SLionel Sambuc #endif // ZFSTREAM_H
469