1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
10 | (C) SuSE Linux Products GmbH |
11 \----------------------------------------------------------------------/
15 Author: Michael Andres <ma@suse.de>
16 Maintainer: Michael Andres <ma@suse.de>
18 Purpose: Streams reading and writing gzip files.
21 #ifndef ZYPP_BASE_GZSTREAM_H
22 #define ZYPP_BASE_GZSTREAM_H
28 ///////////////////////////////////////////////////////////////////
30 { /////////////////////////////////////////////////////////////////
32 ///////////////////////////////////////////////////////////////////
33 namespace gzstream_detail
34 { /////////////////////////////////////////////////////////////////
36 ///////////////////////////////////////////////////////////////////
38 // CLASS NAME : ZlibError
40 * @short Helper class to ship zlib errors.
50 * errno, valid if zError is Z_ERRNO
55 : _zError( 0 ), _errno( 0 )
59 * Return string describing the zlib error code
64 ///////////////////////////////////////////////////////////////////
66 ///////////////////////////////////////////////////////////////////
68 // CLASS NAME : fgzstreambuf
70 * @short Streambuffer reading or writing gzip files.
72 * Read and write mode are mutual exclusive. Seek is supported,
73 * but zlib restrictions appy (only forward seek in write mode;
74 * backward seek in read mode might be expensive).Putback is not
77 * Reading plain (no gziped) files is possible as well.
79 * This streambuf is used in @ref ifgzstream and @ref ofgzstream.
81 class fgzstreambuf : public std::streambuf {
85 fgzstreambuf( unsigned bufferSize_r = 512 )
88 , _mode( std::ios_base::openmode(0) )
89 , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
102 { return( _mode == std::ios_base::in ); }
106 { return( _mode == std::ios_base::out ); }
109 open( const char * name_r, std::ios_base::openmode mode_r = std::ios_base::in );
114 //! Tell the file position in the compressed file.
115 //! Analogous to tell(2), complementary to gztell.
116 pos_type compressed_tell() const;
119 * The last error returned fron zlib.
131 overflow( int_type c = traits_type::eof() );
137 seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode /* ignored */ )
138 { return seekTo( off_r, way_r ); }
141 seekpos( pos_type pos_r, std::ios_base::openmode /* ignored */ )
142 { return seekTo( off_type(pos_r), std::ios_base::beg ); }
146 typedef std::vector<char> buffer_type;
148 //! file descriptor of the compressed file
153 std::ios_base::openmode _mode;
163 { gzerror( _file, &_error._zError ); }
166 zReadTo( char * buffer_r, std::streamsize maxcount_r );
169 zWriteFrom( const char * buffer_r, std::streamsize count_r );
172 zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
178 seekTo( off_type off_r, std::ios_base::seekdir way_r );
180 ///////////////////////////////////////////////////////////////////
182 ///////////////////////////////////////////////////////////////////
184 // CLASS NAME : fXstream<class _BStr,class _SBuf>
186 * @short Common template to define ifgzstream/ofgzstream
187 * reading/writing gzip files.
189 * Don't use fXstream directly, but @ref ifgzstream or
190 * @ref ofgzstream. fXstream is just to avoid almost
193 template<class _BStream,class _StreamBuf>
194 class fXstream : public _BStream
198 typedef gzstream_detail::ZlibError ZlibError;
199 typedef _BStream stream_type;
200 typedef _StreamBuf streambuf_type;
203 : stream_type( NULL )
204 { this->init( &_streambuf ); }
207 fXstream( const char * file_r )
208 : stream_type( NULL )
209 { this->init( &_streambuf ); this->open( file_r ); }
217 { return _streambuf.isOpen(); }
220 open( const char * file_r )
222 if ( !_streambuf.open( file_r, defMode(*this) ) )
223 this->setstate(std::ios_base::failbit);
231 if ( !_streambuf.close() )
232 this->setstate(std::ios_base::failbit);
236 * The last error returned retuned fron zlib.
240 { return _streambuf.zError(); }
242 //! Similar to ios::rdbuf.
243 //! But it returns our specific type, not the generic streambuf *.
244 const streambuf_type&
246 { return _streambuf; }
250 streambuf_type _streambuf;
252 std::ios_base::openmode
253 defMode( const std::istream & str_r )
254 { return std::ios_base::in; }
256 std::ios_base::openmode
257 defMode( const std::ostream & str_r )
258 { return std::ios_base::out; }
261 ///////////////////////////////////////////////////////////////////
263 /////////////////////////////////////////////////////////////////
264 } // namespace gzstream_detail
265 ///////////////////////////////////////////////////////////////////
268 * istream reading gzip files as well as plain files.
270 typedef gzstream_detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
273 * ostream writing gzip files.
275 typedef gzstream_detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
277 /////////////////////////////////////////////////////////////////
279 ///////////////////////////////////////////////////////////////////
281 #endif // ZYPP_BASE_GZSTREAM_H