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