libzypp
10.5.0
|
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