libzypp  10.5.0
GzStream.h
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                                                                      |
00003 |                      __   __    ____ _____ ____                      |
00004 |                      \ \ / /_ _/ ___|_   _|___ \                     |
00005 |                       \ V / _` \___ \ | |   __) |                    |
00006 |                        | | (_| |___) || |  / __/                     |
00007 |                        |_|\__,_|____/ |_| |_____|                    |
00008 |                                                                      |
00009 |                               core system                            |
00010 |                                         (C) SuSE Linux Products GmbH |
00011 \----------------------------------------------------------------------/
00012 
00013   File:       GzStream.h
00014 
00015   Author:     Michael Andres <ma@suse.de>
00016   Maintainer: Michael Andres <ma@suse.de>
00017 
00018   Purpose: Streams reading and writing gzip files.
00019 
00020 /-*/
00021 #ifndef ZYPP_BASE_GZSTREAM_H
00022 #define ZYPP_BASE_GZSTREAM_H
00023 
00024 #include <iosfwd>
00025 #include <streambuf>
00026 #include <vector>
00027 #include <zlib.h>
00028 
00030 namespace zypp
00031 { 
00032 
00034   namespace gzstream_detail
00035   { 
00036 
00038     //
00039     //  CLASS NAME : ZlibError
00043     struct ZlibError
00044     {
00048       int _zError;
00049 
00053       int _errno;
00054 
00055       ZlibError()
00056       : _zError( 0 ), _errno( 0 )
00057       {}
00058 
00062       std::string
00063       strerror() const;
00064     };
00066 
00068     inline std::ostream & operator<<( std::ostream & str, const ZlibError & obj )
00069     { return str << obj.strerror(); }
00070 
00072     //
00073     //  CLASS NAME : fgzstreambuf
00086     class fgzstreambuf : public std::streambuf {
00087 
00088     public:
00089 
00090       fgzstreambuf( unsigned bufferSize_r = 512 )
00091       : _fd( -1 )
00092       ,_file( NULL )
00093       , _mode( std::ios_base::openmode(0) )
00094       , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
00095       {}
00096 
00097       virtual
00098       ~fgzstreambuf()
00099       { close(); }
00100 
00101       bool
00102       isOpen() const
00103       { return _file; }
00104 
00105       bool
00106       inReadMode() const
00107       { return( _mode == std::ios_base::in ); }
00108 
00109       bool
00110       inWriteMode() const
00111       { return( _mode == std::ios_base::out ); }
00112 
00113       fgzstreambuf *
00114       open( const char * name_r, std::ios_base::openmode mode_r = std::ios_base::in );
00115 
00116         fgzstreambuf *
00117         close();
00118 
00121         pos_type compressed_tell() const;
00122 
00126         ZlibError
00127         zError() const
00128         { return _error; }
00129 
00130     protected:
00131 
00132       virtual int
00133       sync();
00134 
00135       virtual int_type
00136       overflow( int_type c = traits_type::eof() );
00137 
00138       virtual int_type
00139       underflow();
00140 
00141       virtual pos_type
00142       seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode /* ignored */ )
00143       { return seekTo( off_r, way_r ); }
00144 
00145       virtual pos_type
00146       seekpos( pos_type pos_r, std::ios_base::openmode /* ignored */ )
00147       { return seekTo( off_type(pos_r), std::ios_base::beg ); }
00148 
00149     private:
00150 
00151       typedef std::vector<char> buffer_type;
00152 
00154       int                      _fd;
00155 
00156       gzFile                   _file;
00157 
00158       std::ios_base::openmode  _mode;
00159 
00160       buffer_type              _buffer;
00161 
00162       ZlibError                _error;
00163 
00164     private:
00165 
00166       void
00167       setZError()
00168       { gzerror( _file, &_error._zError ); }
00169 
00170       std::streamsize
00171       zReadTo( char * buffer_r, std::streamsize maxcount_r );
00172 
00173       bool
00174       zWriteFrom( const char * buffer_r, std::streamsize count_r );
00175 
00176       pos_type
00177       zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
00178 
00179       pos_type
00180       zTell();
00181 
00182       pos_type
00183       seekTo( off_type off_r, std::ios_base::seekdir way_r );
00184     };
00186 
00188     //
00189     //  CLASS NAME : fXstream<class _BStr,class _SBuf>
00198     template<class _BStream,class _StreamBuf>
00199       class fXstream : public _BStream
00200       {
00201       public:
00202 
00203         typedef gzstream_detail::ZlibError ZlibError;
00204         typedef _BStream                   stream_type;
00205         typedef _StreamBuf                 streambuf_type;
00206 
00207         fXstream()
00208         : stream_type( NULL )
00209         { this->init( &_streambuf ); }
00210 
00211         explicit
00212         fXstream( const char * file_r )
00213         : stream_type( NULL )
00214         { this->init( &_streambuf ); this->open( file_r ); }
00215 
00216         virtual
00217         ~fXstream()
00218         {}
00219 
00220         bool
00221         is_open() const
00222         { return _streambuf.isOpen(); }
00223 
00224         void
00225         open( const char * file_r )
00226         {
00227           if ( !_streambuf.open( file_r, defMode(*this) ) )
00228             this->setstate(std::ios_base::failbit);
00229           else
00230             this->clear();
00231         }
00232 
00233         void
00234         close()
00235         {
00236           if ( !_streambuf.close() )
00237             this->setstate(std::ios_base::failbit);
00238         }
00239 
00243         ZlibError
00244         zError() const
00245         { return _streambuf.zError(); }
00246 
00249         const streambuf_type&
00250         getbuf() const
00251         { return _streambuf; }
00252 
00253       private:
00254 
00255         streambuf_type _streambuf;
00256 
00257         std::ios_base::openmode
00258         defMode( const std::istream & str_r )
00259         { return std::ios_base::in; }
00260 
00261         std::ios_base::openmode
00262         defMode( const std::ostream & str_r )
00263         { return std::ios_base::out; }
00264 
00265       };
00267 
00269   } // namespace gzstream_detail
00271 
00275   typedef gzstream_detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
00276 
00280   typedef gzstream_detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
00281 
00283 } // namespace zypp
00285 
00286 #endif // ZYPP_BASE_GZSTREAM_H