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