GzStream.h
Go to the documentation of this file.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 inline std::ostream & operator<<( std::ostream & str, const ZlibError & obj )
00069 { return str << obj.strerror(); }
00070
00072
00073
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 )
00143 { return seekTo( off_r, way_r ); }
00144
00145 virtual pos_type
00146 seekpos( pos_type pos_r, std::ios_base::openmode )
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
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 }
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 }
00285
00286 #endif // ZYPP_BASE_GZSTREAM_H