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 <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
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
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 )
00139 { return seekTo( off_r, way_r ); }
00140
00141 virtual pos_type
00142 seekpos( pos_type pos_r, std::ios_base::openmode )
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
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 }
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 }
00281
00282 #endif // ZYPP_BASE_GZSTREAM_H