00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef ZYPP_BASE_GZSTREAM_H
00022 #define ZYPP_BASE_GZSTREAM_H
00023
00024 #include <iostream>
00025 #include <vector>
00026 #include <zlib.h>
00027
00029 namespace zypp
00030 {
00031
00033 namespace gzstream_detail
00034 {
00035
00037
00038
00042 struct ZlibError
00043 {
00047 int _zError;
00048
00052 int _errno;
00053
00054 ZlibError()
00055 : _zError( 0 ), _errno( 0 )
00056 {}
00057
00061 std::string
00062 strerror() const;
00063 };
00065
00067
00068
00081 class fgzstreambuf : public std::streambuf {
00082
00083 public:
00084
00085 fgzstreambuf( unsigned bufferSize_r = 512 )
00086 : _fd( -1 )
00087 ,_file( NULL )
00088 , _mode( std::ios_base::openmode(0) )
00089 , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
00090 {}
00091
00092 virtual
00093 ~fgzstreambuf()
00094 { close(); }
00095
00096 bool
00097 isOpen() const
00098 { return _file; }
00099
00100 bool
00101 inReadMode() const
00102 { return( _mode == std::ios_base::in ); }
00103
00104 bool
00105 inWriteMode() const
00106 { return( _mode == std::ios_base::out ); }
00107
00108 fgzstreambuf *
00109 open( const char * name_r, std::ios_base::openmode mode_r = std::ios_base::in );
00110
00111 fgzstreambuf *
00112 close();
00113
00116 pos_type compressed_tell() const;
00117
00121 ZlibError
00122 zError() const
00123 { return _error; }
00124
00125 protected:
00126
00127 virtual int
00128 sync();
00129
00130 virtual int_type
00131 overflow( int_type c = traits_type::eof() );
00132
00133 virtual int_type
00134 underflow();
00135
00136 virtual pos_type
00137 seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode )
00138 { return seekTo( off_r, way_r ); }
00139
00140 virtual pos_type
00141 seekpos( pos_type pos_r, std::ios_base::openmode )
00142 { return seekTo( off_type(pos_r), std::ios_base::beg ); }
00143
00144 private:
00145
00146 typedef std::vector<char> buffer_type;
00147
00149 int _fd;
00150
00151 gzFile _file;
00152
00153 std::ios_base::openmode _mode;
00154
00155 buffer_type _buffer;
00156
00157 ZlibError _error;
00158
00159 private:
00160
00161 void
00162 setZError()
00163 { gzerror( _file, &_error._zError ); }
00164
00165 std::streamsize
00166 zReadTo( char * buffer_r, std::streamsize maxcount_r );
00167
00168 bool
00169 zWriteFrom( const char * buffer_r, std::streamsize count_r );
00170
00171 pos_type
00172 zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
00173
00174 pos_type
00175 zTell();
00176
00177 pos_type
00178 seekTo( off_type off_r, std::ios_base::seekdir way_r );
00179 };
00181
00183
00184
00193 template<class _BStream,class _StreamBuf>
00194 class fXstream : public _BStream
00195 {
00196 public:
00197
00198 typedef gzstream_detail::ZlibError ZlibError;
00199 typedef _BStream stream_type;
00200 typedef _StreamBuf streambuf_type;
00201
00202 fXstream()
00203 : stream_type( NULL )
00204 { this->init( &_streambuf ); }
00205
00206 explicit
00207 fXstream( const char * file_r )
00208 : stream_type( NULL )
00209 { this->init( &_streambuf ); this->open( file_r ); }
00210
00211 virtual
00212 ~fXstream()
00213 {}
00214
00215 bool
00216 is_open() const
00217 { return _streambuf.isOpen(); }
00218
00219 void
00220 open( const char * file_r )
00221 {
00222 if ( !_streambuf.open( file_r, defMode(*this) ) )
00223 this->setstate(std::ios_base::failbit);
00224 else
00225 this->clear();
00226 }
00227
00228 void
00229 close()
00230 {
00231 if ( !_streambuf.close() )
00232 this->setstate(std::ios_base::failbit);
00233 }
00234
00238 ZlibError
00239 zError() const
00240 { return _streambuf.zError(); }
00241
00244 const streambuf_type&
00245 getbuf() const
00246 { return _streambuf; }
00247
00248 private:
00249
00250 streambuf_type _streambuf;
00251
00252 std::ios_base::openmode
00253 defMode( const std::istream & str_r )
00254 { return std::ios_base::in; }
00255
00256 std::ios_base::openmode
00257 defMode( const std::ostream & str_r )
00258 { return std::ios_base::out; }
00259
00260 };
00262
00264 }
00266
00270 typedef gzstream_detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
00271
00275 typedef gzstream_detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
00276
00278 }
00280
00281 #endif // ZYPP_BASE_GZSTREAM_H