| (C) SuSE Linux Products GmbH |
\----------------------------------------------------------------------/
- File: gzstream.h
+ File: GzStream.h
Author: Michael Andres <ma@suse.de>
Maintainer: Michael Andres <ma@suse.de>
Purpose: Streams reading and writing gzip files.
/-*/
-#ifndef gzstream_h
-#define gzstream_h
+#ifndef ZYPP_BASE_GZSTREAM_H
+#define ZYPP_BASE_GZSTREAM_H
-#include <iostream>
+#include <iosfwd>
+#include <streambuf>
#include <vector>
#include <zlib.h>
///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ZlibError
-/**
- * @short Helper class to ship zlib errors.
- **/
-struct ZlibError
-{
- /**
- * The zlib error code
- **/
- int _zError;
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
- /**
- * errno, valid if zError is Z_ERRNO
- **/
- int _errno;
+ ///////////////////////////////////////////////////////////////////
+ namespace gzstream_detail
+ { /////////////////////////////////////////////////////////////////
- ZlibError()
- : _zError( 0 ), _errno( 0 )
- {}
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ZlibError
+ /**
+ * @short Helper class to ship zlib errors.
+ **/
+ struct ZlibError
+ {
+ /**
+ * The zlib error code
+ **/
+ int _zError;
+
+ /**
+ * errno, valid if zError is Z_ERRNO
+ **/
+ int _errno;
+
+ ZlibError()
+ : _zError( 0 ), _errno( 0 )
+ {}
+
+ /**
+ * Return string describing the zlib error code
+ **/
+ std::string
+ strerror() const;
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /** \relates ZlibError Stream output. */
+ inline std::ostream & operator<<( std::ostream & str, const ZlibError & obj )
+ { return str << obj.strerror(); }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : fgzstreambuf
+ /**
+ * @short Streambuffer reading or writing gzip files.
+ *
+ * Read and write mode are mutual exclusive. Seek is supported,
+ * but zlib restrictions appy (only forward seek in write mode;
+ * backward seek in read mode might be expensive).Putback is not
+ * supported.
+ *
+ * Reading plain (no gziped) files is possible as well.
+ *
+ * This streambuf is used in @ref ifgzstream and @ref ofgzstream.
+ **/
+ class fgzstreambuf : public std::streambuf {
- /**
- * Return string describing the zlib error code
- **/
- std::string
- strerror() const;
-};
-///////////////////////////////////////////////////////////////////
+ public:
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : fgzstreambuf
-/**
- * @short Streambuffer reading or writing gzip files.
- *
- * Read and write mode are mutual exclusive. Seek is supported,
- * but zlib restrictions appy (only forward seek in write mode;
- * backward seek in read mode might be expensive).Putback is not
- * supported.
- *
- * Reading plain (no gziped) files is possible as well.
- *
- * This streambuf is used in @ref ifgzstream and @ref ofgzstream.
- **/
-class fgzstreambuf : public std::streambuf {
-
- public:
-
- fgzstreambuf( unsigned bufferSize_r = 512 )
- : _file( NULL )
- , _mode( std::ios_base::openmode(0) )
- , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
- {}
-
- virtual
- ~fgzstreambuf()
- { close(); }
-
- bool
- isOpen() const
- { return _file; }
-
- bool
- inReadMode() const
- { return( _mode == std::ios_base::in ); }
-
- bool
- inWriteMode() const
- { return( _mode == std::ios_base::out ); }
-
- fgzstreambuf *
- open( const char * name_r, std::ios_base::openmode mode_r );
-
- fgzstreambuf *
- close();
+ fgzstreambuf( unsigned bufferSize_r = 512 )
+ : _fd( -1 )
+ ,_file( NULL )
+ , _mode( std::ios_base::openmode(0) )
+ , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
+ {}
- /**
- * The last error returned retuned fron zlib.
- **/
- ZlibError
- zError() const
- { return _error; }
+ virtual
+ ~fgzstreambuf()
+ { close(); }
- protected:
+ bool
+ isOpen() const
+ { return _file; }
- virtual int
- sync();
+ bool
+ inReadMode() const
+ { return( _mode == std::ios_base::in ); }
- virtual int_type
- overflow( int_type c = traits_type::eof() );
+ bool
+ inWriteMode() const
+ { return( _mode == std::ios_base::out ); }
- virtual int_type
- underflow();
+ fgzstreambuf *
+ open( const char * name_r, std::ios_base::openmode mode_r = std::ios_base::in );
- virtual pos_type
- seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode /* ignored */ )
- { return seekTo( off_r, way_r ); }
+ fgzstreambuf *
+ close();
- virtual pos_type
- seekpos( pos_type pos_r, std::ios_base::openmode /* ignored */ )
- { return seekTo( off_type(pos_r), std::ios_base::beg ); }
+ //! Tell the file position in the compressed file.
+ //! Analogous to tell(2), complementary to gztell.
+ pos_type compressed_tell() const;
- private:
+ /**
+ * The last error returned fron zlib.
+ **/
+ ZlibError
+ zError() const
+ { return _error; }
- typedef std::vector<char> buffer_type;
+ protected:
- gzFile _file;
+ virtual int
+ sync();
- std::ios_base::openmode _mode;
+ virtual int_type
+ overflow( int_type c = traits_type::eof() );
- buffer_type _buffer;
+ virtual int_type
+ underflow();
- ZlibError _error;
+ virtual pos_type
+ seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode /* ignored */ )
+ { return seekTo( off_r, way_r ); }
- private:
+ virtual pos_type
+ seekpos( pos_type pos_r, std::ios_base::openmode /* ignored */ )
+ { return seekTo( off_type(pos_r), std::ios_base::beg ); }
- void
- setZError()
- { gzerror( _file, &_error._zError ); }
+ private:
- std::streamsize
- zReadTo( char * buffer_r, std::streamsize maxcount_r );
+ typedef std::vector<char> buffer_type;
- bool
- zWriteFrom( const char * buffer_r, std::streamsize count_r );
+ //! file descriptor of the compressed file
+ int _fd;
- pos_type
- zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
+ gzFile _file;
- pos_type
- zTell();
+ std::ios_base::openmode _mode;
- pos_type
- seekTo( off_type off_r, std::ios_base::seekdir way_r );
-};
-///////////////////////////////////////////////////////////////////
+ buffer_type _buffer;
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : fXstream<class _BStr,class _SBuf>
-/**
- * @short Common template to define ifgzstream/ofgzstream
- * reading/writing gzip files.
- *
- * Don't use fXstream directly, but @ref ifgzstream or
- * @ref ofgzstream. fXstream is just to aviod almost
- * duplicate code.
- **/
-template<class _BStream,class _StreamBuf>
- class fXstream : public _BStream
- {
- public:
-
- typedef _BStream stream_type;
- typedef _StreamBuf streambuf_type;
-
- fXstream()
- : stream_type( NULL )
- { this->init( &_streambuf ); }
-
- explicit
- fXstream( const char * file_r )
- : stream_type( NULL )
- { this->init( &_streambuf ); this->open( file_r ); }
-
- virtual
- ~fXstream()
- {}
-
- bool
- is_open() const
- { return _streambuf.isOpen(); }
-
- void
- open( const char * file_r )
- {
- if ( !_streambuf.open( file_r, defMode(*this) ) )
- this->setstate(std::ios_base::failbit);
- else
- this->clear();
- }
-
- void
- close()
- {
- if ( !_streambuf.close() )
- this->setstate(std::ios_base::failbit);
- }
+ ZlibError _error;
- /**
- * The last error returned retuned fron zlib.
- **/
- ZlibError
- zError() const
- { return _streambuf.zError(); }
+ private:
+ void
+ setZError()
+ { gzerror( _file, &_error._zError ); }
- private:
+ std::streamsize
+ zReadTo( char * buffer_r, std::streamsize maxcount_r );
- streambuf_type _streambuf;
+ bool
+ zWriteFrom( const char * buffer_r, std::streamsize count_r );
- std::ios_base::openmode
- defMode( const std::istream & str_r )
- { return std::ios_base::in; }
+ pos_type
+ zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
- std::ios_base::openmode
- defMode( const std::ostream & str_r )
- { return std::ios_base::out; }
+ pos_type
+ zTell();
-};
-///////////////////////////////////////////////////////////////////
+ pos_type
+ seekTo( off_type off_r, std::ios_base::seekdir way_r );
+ };
+ ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : fXstream<class TBStr,class TSBuf>
+ /**
+ * @short Common template to define ifgzstream/ofgzstream
+ * reading/writing gzip files.
+ *
+ * Don't use fXstream directly, but @ref ifgzstream or
+ * @ref ofgzstream. fXstream is just to avoid almost
+ * duplicate code.
+ **/
+ template<class TBStream,class TStreamBuf>
+ class fXstream : public TBStream
+ {
+ public:
+
+ typedef gzstream_detail::ZlibError ZlibError;
+ typedef TBStream stream_type;
+ typedef TStreamBuf streambuf_type;
+
+ fXstream()
+ : stream_type( NULL )
+ { this->init( &_streambuf ); }
+
+ explicit
+ fXstream( const char * file_r )
+ : stream_type( NULL )
+ { this->init( &_streambuf ); this->open( file_r ); }
+
+ virtual
+ ~fXstream()
+ {}
+
+ bool
+ is_open() const
+ { return _streambuf.isOpen(); }
+
+ void
+ open( const char * file_r )
+ {
+ if ( !_streambuf.open( file_r, defMode(*this) ) )
+ this->setstate(std::ios_base::failbit);
+ else
+ this->clear();
+ }
+
+ void
+ close()
+ {
+ if ( !_streambuf.close() )
+ this->setstate(std::ios_base::failbit);
+ }
+
+ /**
+ * The last error returned retuned fron zlib.
+ **/
+ ZlibError
+ zError() const
+ { return _streambuf.zError(); }
+
+ //! Similar to ios::rdbuf.
+ //! But it returns our specific type, not the generic streambuf *.
+ const streambuf_type&
+ getbuf() const
+ { return _streambuf; }
+
+ private:
+
+ streambuf_type _streambuf;
+
+ std::ios_base::openmode
+ defMode( const std::istream & str_r )
+ { return std::ios_base::in; }
+
+ std::ios_base::openmode
+ defMode( const std::ostream & str_r )
+ { return std::ios_base::out; }
+
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////
+ } // namespace gzstream_detail
+ ///////////////////////////////////////////////////////////////////
-/**
- * istream reading gzip files as well as plain files.
- **/
-typedef fXstream<std::istream,fgzstreambuf> ifgzstream;
+ /**
+ * istream reading gzip files as well as plain files.
+ **/
+ typedef gzstream_detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
-/**
- * ostream writing gzip files.
- **/
-typedef fXstream<std::ostream,fgzstreambuf> ofgzstream;
+ /**
+ * ostream writing gzip files.
+ **/
+ typedef gzstream_detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
///////////////////////////////////////////////////////////////////
-#endif // gzstream_h
+#endif // ZYPP_BASE_GZSTREAM_H