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 : _file( NULL )
00087 , _mode( std::ios_base::openmode(0) )
00088 , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
00089 {}
00090
00091 virtual
00092 ~fgzstreambuf()
00093 { close(); }
00094
00095 bool
00096 isOpen() const
00097 { return _file; }
00098
00099 bool
00100 inReadMode() const
00101 { return( _mode == std::ios_base::in ); }
00102
00103 bool
00104 inWriteMode() const
00105 { return( _mode == std::ios_base::out ); }
00106
00107 fgzstreambuf *
00108 open( const char * name_r, std::ios_base::openmode mode_r = std::ios_base::in );
00109
00110 fgzstreambuf *
00111 close();
00112
00116 ZlibError
00117 zError() const
00118 { return _error; }
00119
00120 protected:
00121
00122 virtual int
00123 sync();
00124
00125 virtual int_type
00126 overflow( int_type c = traits_type::eof() );
00127
00128 virtual int_type
00129 underflow();
00130
00131 virtual pos_type
00132 seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode )
00133 { return seekTo( off_r, way_r ); }
00134
00135 virtual pos_type
00136 seekpos( pos_type pos_r, std::ios_base::openmode )
00137 { return seekTo( off_type(pos_r), std::ios_base::beg ); }
00138
00139 private:
00140
00141 typedef std::vector<char> buffer_type;
00142
00143 gzFile _file;
00144
00145 std::ios_base::openmode _mode;
00146
00147 buffer_type _buffer;
00148
00149 ZlibError _error;
00150
00151 private:
00152
00153 void
00154 setZError()
00155 { gzerror( _file, &_error._zError ); }
00156
00157 std::streamsize
00158 zReadTo( char * buffer_r, std::streamsize maxcount_r );
00159
00160 bool
00161 zWriteFrom( const char * buffer_r, std::streamsize count_r );
00162
00163 pos_type
00164 zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
00165
00166 pos_type
00167 zTell();
00168
00169 pos_type
00170 seekTo( off_type off_r, std::ios_base::seekdir way_r );
00171 };
00173
00175
00176
00185 template<class _BStream,class _StreamBuf>
00186 class fXstream : public _BStream
00187 {
00188 public:
00189
00190 typedef gzstream_detail::ZlibError ZlibError;
00191 typedef _BStream stream_type;
00192 typedef _StreamBuf streambuf_type;
00193
00194 fXstream()
00195 : stream_type( NULL )
00196 { this->init( &_streambuf ); }
00197
00198 explicit
00199 fXstream( const char * file_r )
00200 : stream_type( NULL )
00201 { this->init( &_streambuf ); this->open( file_r ); }
00202
00203 virtual
00204 ~fXstream()
00205 {}
00206
00207 bool
00208 is_open() const
00209 { return _streambuf.isOpen(); }
00210
00211 void
00212 open( const char * file_r )
00213 {
00214 if ( !_streambuf.open( file_r, defMode(*this) ) )
00215 this->setstate(std::ios_base::failbit);
00216 else
00217 this->clear();
00218 }
00219
00220 void
00221 close()
00222 {
00223 if ( !_streambuf.close() )
00224 this->setstate(std::ios_base::failbit);
00225 }
00226
00230 ZlibError
00231 zError() const
00232 { return _streambuf.zError(); }
00233
00234
00235 private:
00236
00237 streambuf_type _streambuf;
00238
00239 std::ios_base::openmode
00240 defMode( const std::istream & str_r )
00241 { return std::ios_base::in; }
00242
00243 std::ios_base::openmode
00244 defMode( const std::ostream & str_r )
00245 { return std::ios_base::out; }
00246
00247 };
00249
00251 }
00253
00257 typedef gzstream_detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
00258
00262 typedef gzstream_detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
00263
00265 }
00267
00268 #endif // ZYPP_BASE_GZSTREAM_H