zfstream.h revision 1b33c96954667ba382fa595baf7b31290bfdd517
/*
* A C++ I/O streams interface to the zlib gz* functions
*
* by Ludwig Schwardt <schwardt@sun.ac.za>
* original version by Kevin Ruland <kevin@rodin.wustl.edu>
*
* This version is standard-compliant and compatible with gcc 3.x.
*/
#ifndef ZFSTREAM_H
#define ZFSTREAM_H
#include <ostream>
#include "zlib.h"
/*****************************************************************************/
/**
* @brief Gzipped file stream buffer class.
*
* This class implements basic_filebuf for gzipped files. It doesn't yet support
* (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
* file streambuf.
*/
{
// Default constructor.
gzfilebuf();
// Destructor.
~gzfilebuf();
/**
* @brief Set compression level and strategy on the fly.
* @param comp_level Compression level (see zlib.h for allowed values)
* @param comp_strategy Compression strategy (see zlib.h for allowed values)
* @return Z_OK on success, Z_STREAM_ERROR otherwise.
*
* Unfortunately, these parameters cannot be modified separately, as the
* previous zfstream version assumed. Since the strategy is seldom changed,
* it can default and setcompression(level) then becomes like the old
* setcompressionlevel(level).
*/
int
setcompression(int comp_level,
int comp_strategy = Z_DEFAULT_STRATEGY);
/**
* @brief Check if file is open.
* @return True if file is open.
*/
bool
/**
* @brief Open gzipped file.
* @param name File name.
* @param mode Open mode flags.
* @return @c this on success, NULL on failure.
*/
/**
* @brief Attach to already open gzipped file.
* @param fd File descriptor.
* @param mode Open mode flags.
* @return @c this on success, NULL on failure.
*/
/**
* @brief Close gzipped file.
* @return @c this on success, NULL on failure.
*/
close();
/**
* @brief Convert ios open mode int to mode string used by zlib.
* @return True if valid mode flag combination.
*/
bool
char* c_mode) const;
/**
* @brief Number of characters available in stream buffer.
* @return Number of characters.
*
* This indicates number of characters in get area of stream buffer.
* These characters can be read without accessing the gzipped file.
*/
showmanyc();
/**
* @brief Fill get area from gzipped file.
* @return First character in get area on success, EOF on error.
*
* This actually reads characters from gzipped file to stream
* buffer. Always buffered.
*/
underflow();
/**
* @brief Write put area to gzipped file.
* @param c Extra character to add to buffer contents.
* @return Non-EOF on success, EOF on error.
*
* This actually writes characters in stream buffer to
* gzipped file. With unbuffered output this is done one
* character at a time.
*/
/**
* @brief Installs external stream buffer.
* @param p Pointer to char buffer.
* @param n Size of external buffer.
* @return @c this on success, NULL on failure.
*
* Call setbuf(0,0) to enable unbuffered output.
*/
std::streamsize n);
/**
* @brief Flush stream buffer to file.
* @return 0 on success, -1 on error.
*
* This calls underflow(EOF) to do the job.
*/
virtual int
sync();
//
// Some future enhancements
//
// virtual int_type uflow();
// virtual int_type pbackfail(int_type c = traits_type::eof());
// virtual pos_type
// seekoff(off_type off,
// std::ios_base::seekdir way,
// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
// virtual pos_type
// seekpos(pos_type sp,
// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
/**
* @brief Allocate internal buffer.
*
* This function is safe to call multiple times. It will ensure
* that a proper internal buffer exists if it is required. If the
* buffer already exists or is external, the buffer pointers will be
* reset to their original state.
*/
void
/**
* @brief Destroy internal buffer.
*
* This function is safe to call multiple times. It will ensure
* that the internal buffer is deallocated if it exists. In any
* case, it will also reset the buffer pointers.
*/
void
/**
* Underlying file pointer.
*/
/**
* Mode in which file was opened.
*/
/**
* @brief True if this object owns file descriptor.
*
* This makes the class responsible for closing the file
* upon destruction.
*/
bool own_fd;
/**
* @brief Stream buffer.
*
* For simplicity this remains allocated on the free store for the
* entire life span of the gzfilebuf object, unless replaced by setbuf.
*/
/**
* @brief Stream buffer size.
*
* Defaults to system default buffer size (typically 8192 bytes).
* Modified by setbuf.
*/
/**
* @brief True if this object owns stream buffer.
*
* This makes the class responsible for deleting the buffer
* upon destruction.
*/
bool own_buffer;
};
/*****************************************************************************/
/**
* @brief Gzipped file input stream class.
*
* This class implements ifstream for gzipped files. Seeking and putback
* is not supported yet.
*/
{
// Default constructor
gzifstream();
/**
* @brief Construct stream on gzipped file to be opened.
* @param name File name.
* @param mode Open mode flags (forced to contain ios::in).
*/
gzifstream(const char* name,
/**
* @brief Construct stream on already open gzipped file.
* @param fd File descriptor.
* @param mode Open mode flags (forced to contain ios::in).
*/
gzifstream(int fd,
/**
* Obtain underlying stream buffer.
*/
rdbuf() const
/**
* @brief Check if file is open.
* @return True if file is open.
*/
bool
/**
* @brief Open gzipped file.
* @param name File name.
* @param mode Open mode flags (forced to contain ios::in).
*
* Stream will be in state good() if file opens successfully;
* otherwise in state fail(). This differs from the behavior of
* ifstream, which never sets the state to good() and therefore
* won't allow you to reuse the stream for a second file unless
* you manually clear() the state. The choice is a matter of
* convenience.
*/
void
/**
* @brief Attach to already open gzipped file.
* @param fd File descriptor.
* @param mode Open mode flags (forced to contain ios::in).
*
* Stream will be in state good() if attach succeeded; otherwise
* in state fail().
*/
void
/**
* @brief Close gzipped file.
*
* Stream will be in state fail() if close failed.
*/
void
close();
/**
* Underlying stream buffer.
*/
};
/*****************************************************************************/
/**
* @brief Gzipped file output stream class.
*
* This class implements ofstream for gzipped files. Seeking and putback
* is not supported yet.
*/
{
// Default constructor
gzofstream();
/**
* @brief Construct stream on gzipped file to be opened.
* @param name File name.
* @param mode Open mode flags (forced to contain ios::out).
*/
gzofstream(const char* name,
/**
* @brief Construct stream on already open gzipped file.
* @param fd File descriptor.
* @param mode Open mode flags (forced to contain ios::out).
*/
gzofstream(int fd,
/**
* Obtain underlying stream buffer.
*/
rdbuf() const
/**
* @brief Check if file is open.
* @return True if file is open.
*/
bool
/**
* @brief Open gzipped file.
* @param name File name.
* @param mode Open mode flags (forced to contain ios::out).
*
* Stream will be in state good() if file opens successfully;
* otherwise in state fail(). This differs from the behavior of
* ofstream, which never sets the state to good() and therefore
* won't allow you to reuse the stream for a second file unless
* you manually clear() the state. The choice is a matter of
* convenience.
*/
void
/**
* @brief Attach to already open gzipped file.
* @param fd File descriptor.
* @param mode Open mode flags (forced to contain ios::out).
*
* Stream will be in state good() if attach succeeded; otherwise
* in state fail().
*/
void
/**
* @brief Close gzipped file.
*
* Stream will be in state fail() if close failed.
*/
void
close();
/**
* Underlying stream buffer.
*/
};
/*****************************************************************************/
/**
* @brief Gzipped file output stream manipulator class.
*
* This class defines a two-argument manipulator for gzofstream. It is used
* as base for the setcompression(int,int) manipulator.
*/
{
// Allows insertor to peek at internals
operator<<(gzofstream&,
// Constructor
// Underlying manipulator function
// Arguments for manipulator function
};
/*****************************************************************************/
// Manipulator function thunks through to stream buffer
inline gzofstream&
{
return gzs;
}
// Manipulator constructor stores arguments
inline
{ }
// Insertor applies underlying manipulator function to stream
inline gzofstream&
// Insert this onto stream to simplify setting of compression level
inline gzomanip2<int,int>
setcompression(int l, int s = Z_DEFAULT_STRATEGY)
{ return gzomanip2<int,int>(&setcompression, l, s); }
#endif // ZFSTREAM_H