#include <vector>
#include <zlib.h>
+#include "zypp/base/SimpleStreambuf.h"
+#include "zypp/base/fXstream.h"
+
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
inline std::ostream & operator<<( std::ostream & str, const ZlibError & obj )
{ return str << obj.strerror(); }
+
///////////////////////////////////////////////////////////////////
//
- // CLASS NAME : fgzstreambuf
+ // CLASS NAME : gzstreambufimpl
/**
* @short Streambuffer reading or writing gzip files.
*
*
* This streambuf is used in @ref ifgzstream and @ref ofgzstream.
**/
- class fgzstreambuf : public std::streambuf {
-
+ class gzstreambufimpl {
public:
- fgzstreambuf( unsigned bufferSize_r = 512 )
- : _fd( -1 )
- ,_file( NULL )
- , _mode( std::ios_base::openmode(0) )
- , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
- {}
+ using error_type = ZlibError;
- virtual
- ~fgzstreambuf()
- { close(); }
+ ~gzstreambufimpl()
+ { closeImpl(); }
bool
- isOpen() const
+ isOpen () const
{ return _file; }
bool
- inReadMode() const
+ canRead () const
{ return( _mode == std::ios_base::in ); }
bool
- inWriteMode() const
+ canWrite () const
{ return( _mode == std::ios_base::out ); }
- fgzstreambuf *
- open( const char * name_r, std::ios_base::openmode mode_r = std::ios_base::in );
+ bool
+ canSeek ( std::ios_base::seekdir way_r ) const
+ { return ( way_r == std::ios_base::beg || way_r == std::ios_base::cur ); }
- fgzstreambuf *
- close();
+ protected:
+ bool openImpl( const char * name_r, std::ios_base::openmode mode_r );
+ bool closeImpl ();
- //! Tell the file position in the compressed file.
- //! Analogous to tell(2), complementary to gztell.
- pos_type compressed_tell() const;
+ //! Tell the file position in the compressed file.
+ //! Analogous to tell(2), complementary to gztell.
+ off_t compressed_tell() const;
- /**
+ public:
+ /**
* The last error returned fron zlib.
**/
- ZlibError
- zError() const
- { return _error; }
-
- protected:
-
- virtual int
- sync();
-
- virtual int_type
- overflow( int_type c = traits_type::eof() );
-
- virtual int_type
- underflow();
-
- 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 ); }
-
- virtual pos_type
- seekpos( pos_type pos_r, std::ios_base::openmode /* ignored */ )
- { return seekTo( off_type(pos_r), std::ios_base::beg ); }
-
- private:
-
- typedef std::vector<char> buffer_type;
-
- //! file descriptor of the compressed file
- int _fd;
-
- gzFile _file;
+ error_type
+ error() const
+ { return _error; }
- std::ios_base::openmode _mode;
-
- buffer_type _buffer;
-
- ZlibError _error;
+ std::streamsize readData ( char * buffer_r, std::streamsize maxcount_r );
+ bool writeData( const char * buffer_r, std::streamsize count_r );
+ off_t seekTo( off_t off_r, std::ios_base::seekdir way_r, std::ios_base::openmode omode_r );
+ off_t tell() const;
private:
void
- setZError()
+ setZError() const
{ gzerror( _file, &_error._zError ); }
- std::streamsize
- zReadTo( char * buffer_r, std::streamsize maxcount_r );
+ //! file descriptor of the compressed file
+ int _fd = -1;
- bool
- zWriteFrom( const char * buffer_r, std::streamsize count_r );
+ gzFile _file = nullptr;
- pos_type
- zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
+ std::ios_base::openmode _mode = std::ios_base::openmode(0);
- pos_type
- zTell();
+ mutable ZlibError _error;
- 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; }
-
- };
- ///////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////
+ using fgzstreambuf = detail::SimpleStreamBuf<gzstreambufimpl>;
} // namespace gzstream_detail
- ///////////////////////////////////////////////////////////////////
/**
* istream reading gzip files as well as plain files.
**/
- typedef gzstream_detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
+ typedef detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
/**
* ostream writing gzip files.
**/
- typedef gzstream_detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
+ typedef detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
/////////////////////////////////////////////////////////////////
} // namespace zypp