111293Sandreas.hansson@arm.com/*
211293Sandreas.hansson@arm.com * A C++ I/O streams interface to the zlib gz* functions
311293Sandreas.hansson@arm.com *
411293Sandreas.hansson@arm.com * by Ludwig Schwardt <schwardt@sun.ac.za>
511293Sandreas.hansson@arm.com * original version by Kevin Ruland <kevin@rodin.wustl.edu>
611293Sandreas.hansson@arm.com *
711293Sandreas.hansson@arm.com * This version is standard-compliant and compatible with gcc 3.x.
811293Sandreas.hansson@arm.com */
911293Sandreas.hansson@arm.com
1011293Sandreas.hansson@arm.com#ifndef ZFSTREAM_H
1111293Sandreas.hansson@arm.com#define ZFSTREAM_H
1211293Sandreas.hansson@arm.com
1311293Sandreas.hansson@arm.com#include <istream>  // not iostream, since we don't need cin/cout
1411293Sandreas.hansson@arm.com#include <ostream>
1511293Sandreas.hansson@arm.com#include "zlib.h"
1611293Sandreas.hansson@arm.com
1711293Sandreas.hansson@arm.com/*****************************************************************************/
1811293Sandreas.hansson@arm.com
1911293Sandreas.hansson@arm.com/**
2011293Sandreas.hansson@arm.com *  @brief  Gzipped file stream buffer class.
2111293Sandreas.hansson@arm.com *
2211293Sandreas.hansson@arm.com *  This class implements basic_filebuf for gzipped files. It doesn't yet support
2311293Sandreas.hansson@arm.com *  seeking (allowed by zlib but slow/limited), putback and read/write access
2411293Sandreas.hansson@arm.com *  (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
2511293Sandreas.hansson@arm.com *  file streambuf.
2611293Sandreas.hansson@arm.com*/
2711293Sandreas.hansson@arm.comclass gzfilebuf : public std::streambuf
2811293Sandreas.hansson@arm.com{
2911293Sandreas.hansson@arm.compublic:
3011293Sandreas.hansson@arm.com  //  Default constructor.
3111293Sandreas.hansson@arm.com  gzfilebuf();
3211293Sandreas.hansson@arm.com
3311293Sandreas.hansson@arm.com  //  Destructor.
3411293Sandreas.hansson@arm.com  virtual
3511293Sandreas.hansson@arm.com  ~gzfilebuf();
3611293Sandreas.hansson@arm.com
3711293Sandreas.hansson@arm.com  /**
3811293Sandreas.hansson@arm.com   *  @brief  Set compression level and strategy on the fly.
3911293Sandreas.hansson@arm.com   *  @param  comp_level  Compression level (see zlib.h for allowed values)
4011293Sandreas.hansson@arm.com   *  @param  comp_strategy  Compression strategy (see zlib.h for allowed values)
4111293Sandreas.hansson@arm.com   *  @return  Z_OK on success, Z_STREAM_ERROR otherwise.
4211293Sandreas.hansson@arm.com   *
4311293Sandreas.hansson@arm.com   *  Unfortunately, these parameters cannot be modified separately, as the
4411293Sandreas.hansson@arm.com   *  previous zfstream version assumed. Since the strategy is seldom changed,
4511293Sandreas.hansson@arm.com   *  it can default and setcompression(level) then becomes like the old
4611293Sandreas.hansson@arm.com   *  setcompressionlevel(level).
4711293Sandreas.hansson@arm.com  */
4811293Sandreas.hansson@arm.com  int
4911293Sandreas.hansson@arm.com  setcompression(int comp_level,
5011293Sandreas.hansson@arm.com                 int comp_strategy = Z_DEFAULT_STRATEGY);
5111293Sandreas.hansson@arm.com
5211293Sandreas.hansson@arm.com  /**
5311293Sandreas.hansson@arm.com   *  @brief  Check if file is open.
5411293Sandreas.hansson@arm.com   *  @return  True if file is open.
5511293Sandreas.hansson@arm.com  */
5611293Sandreas.hansson@arm.com  bool
5711293Sandreas.hansson@arm.com  is_open() const { return (file != NULL); }
5811293Sandreas.hansson@arm.com
5911293Sandreas.hansson@arm.com  /**
6011293Sandreas.hansson@arm.com   *  @brief  Open gzipped file.
6111293Sandreas.hansson@arm.com   *  @param  name  File name.
6211293Sandreas.hansson@arm.com   *  @param  mode  Open mode flags.
6311293Sandreas.hansson@arm.com   *  @return  @c this on success, NULL on failure.
6411293Sandreas.hansson@arm.com  */
6511293Sandreas.hansson@arm.com  gzfilebuf*
6611293Sandreas.hansson@arm.com  open(const char* name,
6711293Sandreas.hansson@arm.com       std::ios_base::openmode mode);
6811293Sandreas.hansson@arm.com
6911293Sandreas.hansson@arm.com  /**
7011293Sandreas.hansson@arm.com   *  @brief  Attach to already open gzipped file.
7111293Sandreas.hansson@arm.com   *  @param  fd  File descriptor.
7211293Sandreas.hansson@arm.com   *  @param  mode  Open mode flags.
7311293Sandreas.hansson@arm.com   *  @return  @c this on success, NULL on failure.
7411293Sandreas.hansson@arm.com  */
7511293Sandreas.hansson@arm.com  gzfilebuf*
7611293Sandreas.hansson@arm.com  attach(int fd,
7711293Sandreas.hansson@arm.com         std::ios_base::openmode mode);
7811293Sandreas.hansson@arm.com
7911293Sandreas.hansson@arm.com  /**
8011293Sandreas.hansson@arm.com   *  @brief  Close gzipped file.
8111293Sandreas.hansson@arm.com   *  @return  @c this on success, NULL on failure.
8211293Sandreas.hansson@arm.com  */
8311293Sandreas.hansson@arm.com  gzfilebuf*
8411293Sandreas.hansson@arm.com  close();
8511293Sandreas.hansson@arm.com
8611293Sandreas.hansson@arm.comprotected:
8711293Sandreas.hansson@arm.com  /**
8811293Sandreas.hansson@arm.com   *  @brief  Convert ios open mode int to mode string used by zlib.
8911293Sandreas.hansson@arm.com   *  @return  True if valid mode flag combination.
9011293Sandreas.hansson@arm.com  */
9111293Sandreas.hansson@arm.com  bool
9211293Sandreas.hansson@arm.com  open_mode(std::ios_base::openmode mode,
9311293Sandreas.hansson@arm.com            char* c_mode) const;
9411293Sandreas.hansson@arm.com
9511293Sandreas.hansson@arm.com  /**
9611293Sandreas.hansson@arm.com   *  @brief  Number of characters available in stream buffer.
9711293Sandreas.hansson@arm.com   *  @return  Number of characters.
9811293Sandreas.hansson@arm.com   *
9911293Sandreas.hansson@arm.com   *  This indicates number of characters in get area of stream buffer.
10011293Sandreas.hansson@arm.com   *  These characters can be read without accessing the gzipped file.
10111293Sandreas.hansson@arm.com  */
10211293Sandreas.hansson@arm.com  virtual std::streamsize
10311293Sandreas.hansson@arm.com  showmanyc();
10411293Sandreas.hansson@arm.com
10511293Sandreas.hansson@arm.com  /**
10611293Sandreas.hansson@arm.com   *  @brief  Fill get area from gzipped file.
10711293Sandreas.hansson@arm.com   *  @return  First character in get area on success, EOF on error.
10811293Sandreas.hansson@arm.com   *
10911293Sandreas.hansson@arm.com   *  This actually reads characters from gzipped file to stream
11011293Sandreas.hansson@arm.com   *  buffer. Always buffered.
11111293Sandreas.hansson@arm.com  */
11211293Sandreas.hansson@arm.com  virtual int_type
11311293Sandreas.hansson@arm.com  underflow();
11411293Sandreas.hansson@arm.com
11511293Sandreas.hansson@arm.com  /**
11611293Sandreas.hansson@arm.com   *  @brief  Write put area to gzipped file.
11711293Sandreas.hansson@arm.com   *  @param  c  Extra character to add to buffer contents.
11811293Sandreas.hansson@arm.com   *  @return  Non-EOF on success, EOF on error.
11911293Sandreas.hansson@arm.com   *
12011293Sandreas.hansson@arm.com   *  This actually writes characters in stream buffer to
12111293Sandreas.hansson@arm.com   *  gzipped file. With unbuffered output this is done one
12211293Sandreas.hansson@arm.com   *  character at a time.
12311293Sandreas.hansson@arm.com  */
12411293Sandreas.hansson@arm.com  virtual int_type
12511293Sandreas.hansson@arm.com  overflow(int_type c = traits_type::eof());
12611293Sandreas.hansson@arm.com
12711293Sandreas.hansson@arm.com  /**
12811293Sandreas.hansson@arm.com   *  @brief  Installs external stream buffer.
12911293Sandreas.hansson@arm.com   *  @param  p  Pointer to char buffer.
13011293Sandreas.hansson@arm.com   *  @param  n  Size of external buffer.
13111293Sandreas.hansson@arm.com   *  @return  @c this on success, NULL on failure.
13211293Sandreas.hansson@arm.com   *
13311293Sandreas.hansson@arm.com   *  Call setbuf(0,0) to enable unbuffered output.
13411293Sandreas.hansson@arm.com  */
13511293Sandreas.hansson@arm.com  virtual std::streambuf*
13611293Sandreas.hansson@arm.com  setbuf(char_type* p,
13711293Sandreas.hansson@arm.com         std::streamsize n);
13811293Sandreas.hansson@arm.com
13911293Sandreas.hansson@arm.com  /**
14011293Sandreas.hansson@arm.com   *  @brief  Flush stream buffer to file.
14111293Sandreas.hansson@arm.com   *  @return  0 on success, -1 on error.
14211293Sandreas.hansson@arm.com   *
14311293Sandreas.hansson@arm.com   *  This calls underflow(EOF) to do the job.
14411293Sandreas.hansson@arm.com  */
14511293Sandreas.hansson@arm.com  virtual int
14611293Sandreas.hansson@arm.com  sync();
14711293Sandreas.hansson@arm.com
14811293Sandreas.hansson@arm.com//
14911293Sandreas.hansson@arm.com// Some future enhancements
15011293Sandreas.hansson@arm.com//
15111293Sandreas.hansson@arm.com//  virtual int_type uflow();
15211293Sandreas.hansson@arm.com//  virtual int_type pbackfail(int_type c = traits_type::eof());
15311293Sandreas.hansson@arm.com//  virtual pos_type
15411293Sandreas.hansson@arm.com//  seekoff(off_type off,
15511293Sandreas.hansson@arm.com//          std::ios_base::seekdir way,
15611293Sandreas.hansson@arm.com//          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
15711293Sandreas.hansson@arm.com//  virtual pos_type
15811293Sandreas.hansson@arm.com//  seekpos(pos_type sp,
15911293Sandreas.hansson@arm.com//          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
16011293Sandreas.hansson@arm.com
16111293Sandreas.hansson@arm.comprivate:
16211293Sandreas.hansson@arm.com  /**
16311293Sandreas.hansson@arm.com   *  @brief  Allocate internal buffer.
16411293Sandreas.hansson@arm.com   *
16511293Sandreas.hansson@arm.com   *  This function is safe to call multiple times. It will ensure
16611293Sandreas.hansson@arm.com   *  that a proper internal buffer exists if it is required. If the
16711293Sandreas.hansson@arm.com   *  buffer already exists or is external, the buffer pointers will be
16811293Sandreas.hansson@arm.com   *  reset to their original state.
16911293Sandreas.hansson@arm.com  */
17011293Sandreas.hansson@arm.com  void
17111293Sandreas.hansson@arm.com  enable_buffer();
17211293Sandreas.hansson@arm.com
17311293Sandreas.hansson@arm.com  /**
17411293Sandreas.hansson@arm.com   *  @brief  Destroy internal buffer.
17511293Sandreas.hansson@arm.com   *
17611293Sandreas.hansson@arm.com   *  This function is safe to call multiple times. It will ensure
17711293Sandreas.hansson@arm.com   *  that the internal buffer is deallocated if it exists. In any
17811293Sandreas.hansson@arm.com   *  case, it will also reset the buffer pointers.
17911293Sandreas.hansson@arm.com  */
18011293Sandreas.hansson@arm.com  void
18111293Sandreas.hansson@arm.com  disable_buffer();
18211293Sandreas.hansson@arm.com
18311293Sandreas.hansson@arm.com  /**
18411293Sandreas.hansson@arm.com   *  Underlying file pointer.
18511293Sandreas.hansson@arm.com  */
18611293Sandreas.hansson@arm.com  gzFile file;
18711293Sandreas.hansson@arm.com
18811293Sandreas.hansson@arm.com  /**
18911293Sandreas.hansson@arm.com   *  Mode in which file was opened.
19011293Sandreas.hansson@arm.com  */
19111293Sandreas.hansson@arm.com  std::ios_base::openmode io_mode;
19211293Sandreas.hansson@arm.com
19311293Sandreas.hansson@arm.com  /**
19411293Sandreas.hansson@arm.com   *  @brief  True if this object owns file descriptor.
19511293Sandreas.hansson@arm.com   *
19611293Sandreas.hansson@arm.com   *  This makes the class responsible for closing the file
19711293Sandreas.hansson@arm.com   *  upon destruction.
19811293Sandreas.hansson@arm.com  */
19911293Sandreas.hansson@arm.com  bool own_fd;
20011293Sandreas.hansson@arm.com
20111293Sandreas.hansson@arm.com  /**
20211293Sandreas.hansson@arm.com   *  @brief  Stream buffer.
20311293Sandreas.hansson@arm.com   *
20411293Sandreas.hansson@arm.com   *  For simplicity this remains allocated on the free store for the
20511293Sandreas.hansson@arm.com   *  entire life span of the gzfilebuf object, unless replaced by setbuf.
20611293Sandreas.hansson@arm.com  */
20711293Sandreas.hansson@arm.com  char_type* buffer;
20811293Sandreas.hansson@arm.com
20911293Sandreas.hansson@arm.com  /**
21011293Sandreas.hansson@arm.com   *  @brief  Stream buffer size.
21111293Sandreas.hansson@arm.com   *
21211293Sandreas.hansson@arm.com   *  Defaults to system default buffer size (typically 8192 bytes).
21311293Sandreas.hansson@arm.com   *  Modified by setbuf.
21411293Sandreas.hansson@arm.com  */
21511293Sandreas.hansson@arm.com  std::streamsize buffer_size;
21611293Sandreas.hansson@arm.com
21711293Sandreas.hansson@arm.com  /**
21811293Sandreas.hansson@arm.com   *  @brief  True if this object owns stream buffer.
21911293Sandreas.hansson@arm.com   *
22011293Sandreas.hansson@arm.com   *  This makes the class responsible for deleting the buffer
22111293Sandreas.hansson@arm.com   *  upon destruction.
22211293Sandreas.hansson@arm.com  */
22311293Sandreas.hansson@arm.com  bool own_buffer;
22411293Sandreas.hansson@arm.com};
22511293Sandreas.hansson@arm.com
22611293Sandreas.hansson@arm.com/*****************************************************************************/
22711293Sandreas.hansson@arm.com
22811293Sandreas.hansson@arm.com/**
22911293Sandreas.hansson@arm.com *  @brief  Gzipped file input stream class.
23011293Sandreas.hansson@arm.com *
23111293Sandreas.hansson@arm.com *  This class implements ifstream for gzipped files. Seeking and putback
23211293Sandreas.hansson@arm.com *  is not supported yet.
23311293Sandreas.hansson@arm.com*/
23411293Sandreas.hansson@arm.comclass gzifstream : public std::istream
23511293Sandreas.hansson@arm.com{
23611293Sandreas.hansson@arm.compublic:
23711293Sandreas.hansson@arm.com  //  Default constructor
23811293Sandreas.hansson@arm.com  gzifstream();
23911293Sandreas.hansson@arm.com
24011293Sandreas.hansson@arm.com  /**
24111293Sandreas.hansson@arm.com   *  @brief  Construct stream on gzipped file to be opened.
24211293Sandreas.hansson@arm.com   *  @param  name  File name.
24311293Sandreas.hansson@arm.com   *  @param  mode  Open mode flags (forced to contain ios::in).
24411293Sandreas.hansson@arm.com  */
24511293Sandreas.hansson@arm.com  explicit
24611293Sandreas.hansson@arm.com  gzifstream(const char* name,
24711293Sandreas.hansson@arm.com             std::ios_base::openmode mode = std::ios_base::in);
24811293Sandreas.hansson@arm.com
24911293Sandreas.hansson@arm.com  /**
25011293Sandreas.hansson@arm.com   *  @brief  Construct stream on already open gzipped file.
25111293Sandreas.hansson@arm.com   *  @param  fd    File descriptor.
25211293Sandreas.hansson@arm.com   *  @param  mode  Open mode flags (forced to contain ios::in).
25311293Sandreas.hansson@arm.com  */
25411293Sandreas.hansson@arm.com  explicit
25511293Sandreas.hansson@arm.com  gzifstream(int fd,
25611293Sandreas.hansson@arm.com             std::ios_base::openmode mode = std::ios_base::in);
25711293Sandreas.hansson@arm.com
25811293Sandreas.hansson@arm.com  /**
25911293Sandreas.hansson@arm.com   *  Obtain underlying stream buffer.
26011293Sandreas.hansson@arm.com  */
26111293Sandreas.hansson@arm.com  gzfilebuf*
26211293Sandreas.hansson@arm.com  rdbuf() const
26311293Sandreas.hansson@arm.com  { return const_cast<gzfilebuf*>(&sb); }
26411293Sandreas.hansson@arm.com
26511293Sandreas.hansson@arm.com  /**
26611293Sandreas.hansson@arm.com   *  @brief  Check if file is open.
26711293Sandreas.hansson@arm.com   *  @return  True if file is open.
26811293Sandreas.hansson@arm.com  */
26911293Sandreas.hansson@arm.com  bool
27011293Sandreas.hansson@arm.com  is_open() { return sb.is_open(); }
27111293Sandreas.hansson@arm.com
27211293Sandreas.hansson@arm.com  /**
27311293Sandreas.hansson@arm.com   *  @brief  Open gzipped file.
27411293Sandreas.hansson@arm.com   *  @param  name  File name.
27511293Sandreas.hansson@arm.com   *  @param  mode  Open mode flags (forced to contain ios::in).
27611293Sandreas.hansson@arm.com   *
27711293Sandreas.hansson@arm.com   *  Stream will be in state good() if file opens successfully;
27811293Sandreas.hansson@arm.com   *  otherwise in state fail(). This differs from the behavior of
27911293Sandreas.hansson@arm.com   *  ifstream, which never sets the state to good() and therefore
28011293Sandreas.hansson@arm.com   *  won't allow you to reuse the stream for a second file unless
28111293Sandreas.hansson@arm.com   *  you manually clear() the state. The choice is a matter of
28211293Sandreas.hansson@arm.com   *  convenience.
28311293Sandreas.hansson@arm.com  */
28411293Sandreas.hansson@arm.com  void
28511293Sandreas.hansson@arm.com  open(const char* name,
28611293Sandreas.hansson@arm.com       std::ios_base::openmode mode = std::ios_base::in);
28711293Sandreas.hansson@arm.com
28811293Sandreas.hansson@arm.com  /**
28911293Sandreas.hansson@arm.com   *  @brief  Attach to already open gzipped file.
29011293Sandreas.hansson@arm.com   *  @param  fd  File descriptor.
29111293Sandreas.hansson@arm.com   *  @param  mode  Open mode flags (forced to contain ios::in).
29211293Sandreas.hansson@arm.com   *
29311293Sandreas.hansson@arm.com   *  Stream will be in state good() if attach succeeded; otherwise
29411293Sandreas.hansson@arm.com   *  in state fail().
29511293Sandreas.hansson@arm.com  */
29611293Sandreas.hansson@arm.com  void
29711293Sandreas.hansson@arm.com  attach(int fd,
29811293Sandreas.hansson@arm.com         std::ios_base::openmode mode = std::ios_base::in);
29911293Sandreas.hansson@arm.com
30011293Sandreas.hansson@arm.com  /**
30111293Sandreas.hansson@arm.com   *  @brief  Close gzipped file.
30211293Sandreas.hansson@arm.com   *
30311293Sandreas.hansson@arm.com   *  Stream will be in state fail() if close failed.
30411293Sandreas.hansson@arm.com  */
30511293Sandreas.hansson@arm.com  void
30611293Sandreas.hansson@arm.com  close();
30711293Sandreas.hansson@arm.com
30811293Sandreas.hansson@arm.comprivate:
30911293Sandreas.hansson@arm.com  /**
31011293Sandreas.hansson@arm.com   *  Underlying stream buffer.
31111293Sandreas.hansson@arm.com  */
31211293Sandreas.hansson@arm.com  gzfilebuf sb;
31311293Sandreas.hansson@arm.com};
31411293Sandreas.hansson@arm.com
31511293Sandreas.hansson@arm.com/*****************************************************************************/
31611293Sandreas.hansson@arm.com
31711293Sandreas.hansson@arm.com/**
31811293Sandreas.hansson@arm.com *  @brief  Gzipped file output stream class.
31911293Sandreas.hansson@arm.com *
32011293Sandreas.hansson@arm.com *  This class implements ofstream for gzipped files. Seeking and putback
32111293Sandreas.hansson@arm.com *  is not supported yet.
32211293Sandreas.hansson@arm.com*/
32311293Sandreas.hansson@arm.comclass gzofstream : public std::ostream
32411293Sandreas.hansson@arm.com{
32511293Sandreas.hansson@arm.compublic:
32611293Sandreas.hansson@arm.com  //  Default constructor
32711293Sandreas.hansson@arm.com  gzofstream();
32811293Sandreas.hansson@arm.com
32911293Sandreas.hansson@arm.com  /**
33011293Sandreas.hansson@arm.com   *  @brief  Construct stream on gzipped file to be opened.
33111293Sandreas.hansson@arm.com   *  @param  name  File name.
33211293Sandreas.hansson@arm.com   *  @param  mode  Open mode flags (forced to contain ios::out).
33311293Sandreas.hansson@arm.com  */
33411293Sandreas.hansson@arm.com  explicit
33511293Sandreas.hansson@arm.com  gzofstream(const char* name,
33611293Sandreas.hansson@arm.com             std::ios_base::openmode mode = std::ios_base::out);
33711293Sandreas.hansson@arm.com
33811293Sandreas.hansson@arm.com  /**
33911293Sandreas.hansson@arm.com   *  @brief  Construct stream on already open gzipped file.
34011293Sandreas.hansson@arm.com   *  @param  fd    File descriptor.
34111293Sandreas.hansson@arm.com   *  @param  mode  Open mode flags (forced to contain ios::out).
34211293Sandreas.hansson@arm.com  */
34311293Sandreas.hansson@arm.com  explicit
34411293Sandreas.hansson@arm.com  gzofstream(int fd,
34511293Sandreas.hansson@arm.com             std::ios_base::openmode mode = std::ios_base::out);
34611293Sandreas.hansson@arm.com
34711293Sandreas.hansson@arm.com  /**
34811293Sandreas.hansson@arm.com   *  Obtain underlying stream buffer.
34911293Sandreas.hansson@arm.com  */
35011293Sandreas.hansson@arm.com  gzfilebuf*
35111293Sandreas.hansson@arm.com  rdbuf() const
35211293Sandreas.hansson@arm.com  { return const_cast<gzfilebuf*>(&sb); }
35311293Sandreas.hansson@arm.com
35411293Sandreas.hansson@arm.com  /**
35511293Sandreas.hansson@arm.com   *  @brief  Check if file is open.
35611293Sandreas.hansson@arm.com   *  @return  True if file is open.
35711293Sandreas.hansson@arm.com  */
35811293Sandreas.hansson@arm.com  bool
35911293Sandreas.hansson@arm.com  is_open() { return sb.is_open(); }
36011293Sandreas.hansson@arm.com
36111293Sandreas.hansson@arm.com  /**
36211293Sandreas.hansson@arm.com   *  @brief  Open gzipped file.
36311293Sandreas.hansson@arm.com   *  @param  name  File name.
36411293Sandreas.hansson@arm.com   *  @param  mode  Open mode flags (forced to contain ios::out).
36511293Sandreas.hansson@arm.com   *
36611293Sandreas.hansson@arm.com   *  Stream will be in state good() if file opens successfully;
36711293Sandreas.hansson@arm.com   *  otherwise in state fail(). This differs from the behavior of
36811293Sandreas.hansson@arm.com   *  ofstream, which never sets the state to good() and therefore
36911293Sandreas.hansson@arm.com   *  won't allow you to reuse the stream for a second file unless
37011293Sandreas.hansson@arm.com   *  you manually clear() the state. The choice is a matter of
37111293Sandreas.hansson@arm.com   *  convenience.
37211293Sandreas.hansson@arm.com  */
37311293Sandreas.hansson@arm.com  void
37411293Sandreas.hansson@arm.com  open(const char* name,
37511293Sandreas.hansson@arm.com       std::ios_base::openmode mode = std::ios_base::out);
37611293Sandreas.hansson@arm.com
37711293Sandreas.hansson@arm.com  /**
37811293Sandreas.hansson@arm.com   *  @brief  Attach to already open gzipped file.
37911293Sandreas.hansson@arm.com   *  @param  fd  File descriptor.
38011293Sandreas.hansson@arm.com   *  @param  mode  Open mode flags (forced to contain ios::out).
38111293Sandreas.hansson@arm.com   *
38211293Sandreas.hansson@arm.com   *  Stream will be in state good() if attach succeeded; otherwise
38311293Sandreas.hansson@arm.com   *  in state fail().
38411293Sandreas.hansson@arm.com  */
38511293Sandreas.hansson@arm.com  void
38611293Sandreas.hansson@arm.com  attach(int fd,
38711293Sandreas.hansson@arm.com         std::ios_base::openmode mode = std::ios_base::out);
38811293Sandreas.hansson@arm.com
38911293Sandreas.hansson@arm.com  /**
39011293Sandreas.hansson@arm.com   *  @brief  Close gzipped file.
39111293Sandreas.hansson@arm.com   *
39211293Sandreas.hansson@arm.com   *  Stream will be in state fail() if close failed.
39311293Sandreas.hansson@arm.com  */
39411293Sandreas.hansson@arm.com  void
39511293Sandreas.hansson@arm.com  close();
39611293Sandreas.hansson@arm.com
39711293Sandreas.hansson@arm.comprivate:
39811293Sandreas.hansson@arm.com  /**
39911293Sandreas.hansson@arm.com   *  Underlying stream buffer.
40011293Sandreas.hansson@arm.com  */
40111293Sandreas.hansson@arm.com  gzfilebuf sb;
40211293Sandreas.hansson@arm.com};
40311293Sandreas.hansson@arm.com
40411293Sandreas.hansson@arm.com/*****************************************************************************/
40511293Sandreas.hansson@arm.com
40611293Sandreas.hansson@arm.com/**
40711293Sandreas.hansson@arm.com *  @brief  Gzipped file output stream manipulator class.
40811293Sandreas.hansson@arm.com *
40911293Sandreas.hansson@arm.com *  This class defines a two-argument manipulator for gzofstream. It is used
41011293Sandreas.hansson@arm.com *  as base for the setcompression(int,int) manipulator.
41111293Sandreas.hansson@arm.com*/
41211293Sandreas.hansson@arm.comtemplate<typename T1, typename T2>
41311293Sandreas.hansson@arm.com  class gzomanip2
41411293Sandreas.hansson@arm.com  {
41511293Sandreas.hansson@arm.com  public:
41611293Sandreas.hansson@arm.com    // Allows insertor to peek at internals
41711293Sandreas.hansson@arm.com    template <typename Ta, typename Tb>
41811293Sandreas.hansson@arm.com      friend gzofstream&
41911293Sandreas.hansson@arm.com      operator<<(gzofstream&,
42011293Sandreas.hansson@arm.com                 const gzomanip2<Ta,Tb>&);
42111293Sandreas.hansson@arm.com
42211293Sandreas.hansson@arm.com    // Constructor
42311293Sandreas.hansson@arm.com    gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
42411293Sandreas.hansson@arm.com              T1 v1,
42511293Sandreas.hansson@arm.com              T2 v2);
42611293Sandreas.hansson@arm.com  private:
42711293Sandreas.hansson@arm.com    // Underlying manipulator function
42811293Sandreas.hansson@arm.com    gzofstream&
42911293Sandreas.hansson@arm.com    (*func)(gzofstream&, T1, T2);
43011293Sandreas.hansson@arm.com
43111293Sandreas.hansson@arm.com    // Arguments for manipulator function
43211293Sandreas.hansson@arm.com    T1 val1;
43311293Sandreas.hansson@arm.com    T2 val2;
43411293Sandreas.hansson@arm.com  };
43511293Sandreas.hansson@arm.com
43611293Sandreas.hansson@arm.com/*****************************************************************************/
43711293Sandreas.hansson@arm.com
43811293Sandreas.hansson@arm.com// Manipulator function thunks through to stream buffer
43911293Sandreas.hansson@arm.cominline gzofstream&
44011293Sandreas.hansson@arm.comsetcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
44111293Sandreas.hansson@arm.com{
44211293Sandreas.hansson@arm.com  (gzs.rdbuf())->setcompression(l, s);
44311293Sandreas.hansson@arm.com  return gzs;
44411293Sandreas.hansson@arm.com}
44511293Sandreas.hansson@arm.com
44611293Sandreas.hansson@arm.com// Manipulator constructor stores arguments
44711293Sandreas.hansson@arm.comtemplate<typename T1, typename T2>
44811293Sandreas.hansson@arm.com  inline
44911293Sandreas.hansson@arm.com  gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
45011293Sandreas.hansson@arm.com                              T1 v1,
45111293Sandreas.hansson@arm.com                              T2 v2)
45211293Sandreas.hansson@arm.com  : func(f), val1(v1), val2(v2)
45311293Sandreas.hansson@arm.com  { }
45411293Sandreas.hansson@arm.com
45511293Sandreas.hansson@arm.com// Insertor applies underlying manipulator function to stream
45611293Sandreas.hansson@arm.comtemplate<typename T1, typename T2>
45711293Sandreas.hansson@arm.com  inline gzofstream&
45811293Sandreas.hansson@arm.com  operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
45911293Sandreas.hansson@arm.com  { return (*m.func)(s, m.val1, m.val2); }
46011293Sandreas.hansson@arm.com
46111293Sandreas.hansson@arm.com// Insert this onto stream to simplify setting of compression level
46211293Sandreas.hansson@arm.cominline gzomanip2<int,int>
46311293Sandreas.hansson@arm.comsetcompression(int l, int s = Z_DEFAULT_STRATEGY)
46411293Sandreas.hansson@arm.com{ return gzomanip2<int,int>(&setcompression, l, s); }
46511293Sandreas.hansson@arm.com
46611293Sandreas.hansson@arm.com#endif // ZFSTREAM_H
467