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     //
00069     //  CLASS NAME : fgzstreambuf
00082     class fgzstreambuf : public std::streambuf {
00083 
00084     public:
00085 
00086       fgzstreambuf( unsigned bufferSize_r = 512 )
00087       : _fd( -1 )
00088       ,_file( NULL )
00089       , _mode( std::ios_base::openmode(0) )
00090       , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
00091       {}
00092 
00093       virtual
00094       ~fgzstreambuf()
00095       { close(); }
00096 
00097       bool
00098       isOpen() const
00099       { return _file; }
00100 
00101       bool
00102       inReadMode() const
00103       { return( _mode == std::ios_base::in ); }
00104 
00105       bool
00106       inWriteMode() const
00107       { return( _mode == std::ios_base::out ); }
00108 
00109       fgzstreambuf *
00110       open( const char * name_r, std::ios_base::openmode mode_r = std::ios_base::in );
00111 
00112         fgzstreambuf *
00113         close();
00114 
00117         pos_type compressed_tell() const;
00118 
00122         ZlibError
00123         zError() const
00124         { return _error; }
00125 
00126     protected:
00127 
00128       virtual int
00129       sync();
00130 
00131       virtual int_type
00132       overflow( int_type c = traits_type::eof() );
00133 
00134       virtual int_type
00135       underflow();
00136 
00137       virtual pos_type
00138       seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode /* ignored */ )
00139       { return seekTo( off_r, way_r ); }
00140 
00141       virtual pos_type
00142       seekpos( pos_type pos_r, std::ios_base::openmode /* ignored */ )
00143       { return seekTo( off_type(pos_r), std::ios_base::beg ); }
00144 
00145     private:
00146 
00147       typedef std::vector<char> buffer_type;
00148 
00150       int                      _fd;
00151 
00152       gzFile                   _file;
00153 
00154       std::ios_base::openmode  _mode;
00155 
00156       buffer_type              _buffer;
00157 
00158       ZlibError                _error;
00159 
00160     private:
00161 
00162       void
00163       setZError()
00164       { gzerror( _file, &_error._zError ); }
00165 
00166       std::streamsize
00167       zReadTo( char * buffer_r, std::streamsize maxcount_r );
00168 
00169       bool
00170       zWriteFrom( const char * buffer_r, std::streamsize count_r );
00171 
00172       pos_type
00173       zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
00174 
00175       pos_type
00176       zTell();
00177 
00178       pos_type
00179       seekTo( off_type off_r, std::ios_base::seekdir way_r );
00180     };
00182 
00184     //
00185     //  CLASS NAME : fXstream<class _BStr,class _SBuf>
00194     template<class _BStream,class _StreamBuf>
00195       class fXstream : public _BStream
00196       {
00197       public:
00198 
00199         typedef gzstream_detail::ZlibError ZlibError;
00200         typedef _BStream                   stream_type;
00201         typedef _StreamBuf                 streambuf_type;
00202 
00203         fXstream()
00204         : stream_type( NULL )
00205         { this->init( &_streambuf ); }
00206 
00207         explicit
00208         fXstream( const char * file_r )
00209         : stream_type( NULL )
00210         { this->init( &_streambuf ); this->open( file_r ); }
00211 
00212         virtual
00213         ~fXstream()
00214         {}
00215 
00216         bool
00217         is_open() const
00218         { return _streambuf.isOpen(); }
00219 
00220         void
00221         open( const char * file_r )
00222         {
00223           if ( !_streambuf.open( file_r, defMode(*this) ) )
00224             this->setstate(std::ios_base::failbit);
00225           else
00226             this->clear();
00227         }
00228 
00229         void
00230         close()
00231         {
00232           if ( !_streambuf.close() )
00233             this->setstate(std::ios_base::failbit);
00234         }
00235 
00239         ZlibError
00240         zError() const
00241         { return _streambuf.zError(); }
00242 
00245         const streambuf_type&
00246         getbuf() const
00247         { return _streambuf; }
00248 
00249       private:
00250 
00251         streambuf_type _streambuf;
00252 
00253         std::ios_base::openmode
00254         defMode( const std::istream & str_r )
00255         { return std::ios_base::in; }
00256 
00257         std::ios_base::openmode
00258         defMode( const std::ostream & str_r )
00259         { return std::ios_base::out; }
00260 
00261       };
00263 
00265   } // namespace gzstream_detail
00267 
00271   typedef gzstream_detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
00272 
00276   typedef gzstream_detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
00277 
00279 } // namespace zypp
00281 
00282 #endif // ZYPP_BASE_GZSTREAM_H

Generated on Tue Sep 25 19:22:58 2007 for libzypp by  doxygen 1.5.3