00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "zypp/base/GzStream.h"
00023
00025 namespace zypp
00026 {
00027
00028 namespace gzstream_detail
00029 {
00030
00031
00033
00034
00035
00037
00039
00040
00041
00042
00043 std::string
00044 ZlibError::strerror() const
00045 {
00046 std::string ret = ( _zError ? ::zError( _zError ) : "OK" );
00047 if ( _zError == Z_ERRNO )
00048 ret += std::string("(") + ::strerror( _errno ) + ")";
00049 return ret;
00050 }
00051
00053
00054
00055
00057
00059
00060
00061
00062
00063 fgzstreambuf *
00064 fgzstreambuf::open( const char * name_r, std::ios_base::openmode mode_r )
00065 {
00066 fgzstreambuf * ret = NULL;
00067 if ( ! isOpen() )
00068 {
00069 if ( mode_r == std::ios_base::in )
00070 _file = gzopen( name_r, "rb" );
00071 else if ( mode_r == std::ios_base::out )
00072 _file = gzopen( name_r, "wb" );
00073
00074
00075 if ( isOpen() )
00076 {
00077
00078 _mode = mode_r;
00079 if ( inReadMode() )
00080 {
00081 setp( NULL, NULL );
00082 setg( &(_buffer[0]), &(_buffer[0]), &(_buffer[0]) );
00083 }
00084 else
00085 {
00086 setp( &(_buffer[0]), &(_buffer[_buffer.size()-1]) );
00087 setg( NULL, NULL, NULL );
00088 }
00089 ret = this;
00090 }
00091 else
00092 setZError();
00093 }
00094 return ret;
00095 }
00096
00098
00099
00100
00101
00102 fgzstreambuf *
00103 fgzstreambuf::close()
00104 {
00105 fgzstreambuf * ret = NULL;
00106 if ( isOpen() )
00107 {
00108 bool failed = false;
00109 if ( sync() != 0 )
00110 failed = true;
00111 if ( gzclose( _file ) != Z_OK )
00112 {
00113 failed = true;
00114 setZError();
00115 }
00116
00117
00118 _file = NULL;
00119 _mode = std::ios_base::openmode(0);
00120 setp( NULL, NULL );
00121 setg( NULL, NULL, NULL );
00122 if ( ! failed )
00123 ret = this;
00124 }
00125 return ret;
00126 }
00127
00129
00130
00131
00132
00133 int
00134 fgzstreambuf::sync()
00135 {
00136 int ret = 0;
00137 if ( pbase() < pptr() ) {
00138 const int_type res = overflow();
00139 if ( traits_type::eq_int_type( res, traits_type::eof() ) )
00140 ret = -1;
00141 }
00142 return ret;
00143 }
00144
00146
00147
00148
00149
00150 fgzstreambuf::int_type
00151 fgzstreambuf::overflow( int_type c )
00152 {
00153 int_type ret = traits_type::eof();
00154 if ( inWriteMode() )
00155 {
00156 if ( ! traits_type::eq_int_type( c, traits_type::eof() ) )
00157 {
00158 *pptr() = traits_type::to_char_type( c );
00159 pbump(1);
00160 }
00161 if ( pbase() <= pptr() )
00162 {
00163 if ( zWriteFrom( pbase(), pptr() - pbase() ) )
00164 {
00165 setp( &(_buffer[0]), &(_buffer[_buffer.size()-1]) );
00166 ret = traits_type::not_eof( c );
00167 }
00168
00169 }
00170 }
00171 return ret;
00172 }
00173
00175
00176
00177
00178
00179 fgzstreambuf::int_type
00180 fgzstreambuf::underflow()
00181 {
00182 int_type ret = traits_type::eof();
00183 if ( inReadMode() )
00184 {
00185 if ( gptr() < egptr() )
00186 return traits_type::to_int_type( *gptr() );
00187
00188 const std::streamsize got = zReadTo( &(_buffer[0]), _buffer.size() );
00189 if ( got > 0 )
00190 {
00191 setg( &(_buffer[0]), &(_buffer[0]), &(_buffer[got]) );
00192 ret = traits_type::to_int_type( *gptr() );
00193 }
00194 else if ( got == 0 )
00195 {
00196
00197 setg( &(_buffer[0]), &(_buffer[0]), &(_buffer[0]) );
00198 }
00199
00200 }
00201 return ret;
00202 }
00203
00205
00206
00207
00208
00209 std::streamsize
00210 fgzstreambuf::zReadTo( char * buffer_r, std::streamsize maxcount_r )
00211 {
00212 int read = gzread( _file, buffer_r, maxcount_r );
00213 if ( read < 0 )
00214 setZError();
00215 return read;
00216 }
00217
00219
00220
00221
00222
00223 bool
00224 fgzstreambuf::zWriteFrom( const char * buffer_r, std::streamsize count_r )
00225 {
00226 int written = 0;
00227 if ( count_r )
00228 {
00229 if ( (written = gzwrite( _file, buffer_r, count_r )) == 0 )
00230 setZError();
00231 }
00232 return( written == count_r );
00233 }
00234
00236
00237
00238
00239
00240 fgzstreambuf::pos_type
00241 fgzstreambuf::zSeekTo( off_type off_r, std::ios_base::seekdir way_r )
00242 {
00243 z_off_t ret = gzseek( _file, off_r, way_r );
00244 if ( ret == -1 )
00245 setZError();
00246 return ret;
00247 }
00248
00250
00251
00252
00253
00254 fgzstreambuf::pos_type
00255 fgzstreambuf::zTell()
00256 {
00257 z_off_t ret = gztell( _file );
00258 if ( ret == -1 )
00259 setZError();
00260 return ret;
00261 }
00262
00264
00265
00266
00267
00268 fgzstreambuf::pos_type
00269 fgzstreambuf::seekTo( off_type off_r, std::ios_base::seekdir way_r )
00270 {
00271 pos_type ret = pos_type(off_type(-1));
00272 if ( isOpen() )
00273 {
00274 if ( inWriteMode() )
00275 {
00276 if ( sync() == 0 )
00277 ret = zSeekTo( off_r, way_r );
00278 }
00279 else
00280 {
00281 off_type zegptr = zTell();
00282 if ( zegptr != off_type(-1) )
00283 {
00284 if ( way_r == std::ios_base::end )
00285 {
00286
00287
00288
00289 setg( &(_buffer[0]), &(_buffer[0]), &(_buffer[0]) );
00290 ret = zSeekTo( off_r, way_r );
00291 }
00292 else
00293 {
00294
00295 off_type zeback = zegptr - ( egptr() - eback() );
00296 off_type zgptr = zegptr - ( egptr() - gptr() );
00297 off_type zngptr = off_r;
00298 if ( way_r == std::ios_base::cur )
00299 {
00300 zngptr += zgptr;
00301 way_r = std::ios_base::beg;
00302 }
00303
00304 if ( way_r == std::ios_base::beg )
00305 {
00306 if ( zeback <= zngptr && zngptr <= zegptr )
00307 {
00308
00309
00310 setg( eback(),
00311 eback() + (zngptr-zeback),
00312 egptr() );
00313 ret = pos_type(zngptr);
00314 }
00315 else
00316 {
00317
00318 setg( &(_buffer[0]), &(_buffer[0]), &(_buffer[0]) );
00319 ret = zSeekTo( off_r, way_r );
00320 }
00321 }
00322 }
00323 }
00324 }
00325 }
00326 return ret;
00327 }
00328
00330 }
00333 }
00335