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
29 ///////////////////////////////////////////////////////////////////
31 { /////////////////////////////////////////////////////////////////
33 ///////////////////////////////////////////////////////////////////
34 namespace gzstream_detail
35 { /////////////////////////////////////////////////////////////////
37 ///////////////////////////////////////////////////////////////////
39 // CLASS NAME : ZlibError
41 * @short Helper class to ship zlib errors.
51 * errno, valid if zError is Z_ERRNO
56 : _zError( 0 ), _errno( 0 )
60 * Return string describing the zlib error code
65 ///////////////////////////////////////////////////////////////////
67 /** \relates ZlibError Stream output. */
68 inline std::ostream & operator<<( std::ostream & str, const ZlibError & obj )
69 { return str << obj.strerror(); }
71 ///////////////////////////////////////////////////////////////////
73 // CLASS NAME : fgzstreambuf
75 * @short Streambuffer reading or writing gzip files.
77 * Read and write mode are mutual exclusive. Seek is supported,
78 * but zlib restrictions appy (only forward seek in write mode;
79 * backward seek in read mode might be expensive).Putback is not
82 * Reading plain (no gziped) files is possible as well.
84 * This streambuf is used in @ref ifgzstream and @ref ofgzstream.
86 class fgzstreambuf : public std::streambuf {
90 fgzstreambuf( unsigned bufferSize_r = 512 )
93 , _mode( std::ios_base::openmode(0) )
94 , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
107 { return( _mode == std::ios_base::in ); }
111 { return( _mode == std::ios_base::out ); }
114 open( const char * name_r, std::ios_base::openmode mode_r = std::ios_base::in );
119 //! Tell the file position in the compressed file.
120 //! Analogous to tell(2), complementary to gztell.
121 pos_type compressed_tell() const;
124 * The last error returned fron zlib.
136 overflow( int_type c = traits_type::eof() );
142 seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode /* ignored */ )
143 { return seekTo( off_r, way_r ); }
146 seekpos( pos_type pos_r, std::ios_base::openmode /* ignored */ )
147 { return seekTo( off_type(pos_r), std::ios_base::beg ); }
151 typedef std::vector<char> buffer_type;
153 //! file descriptor of the compressed file
158 std::ios_base::openmode _mode;
168 { gzerror( _file, &_error._zError ); }
171 zReadTo( char * buffer_r, std::streamsize maxcount_r );
174 zWriteFrom( const char * buffer_r, std::streamsize count_r );
177 zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
183 seekTo( off_type off_r, std::ios_base::seekdir way_r );
185 ///////////////////////////////////////////////////////////////////
187 ///////////////////////////////////////////////////////////////////
189 // CLASS NAME : fXstream<class TBStr,class TSBuf>
191 * @short Common template to define ifgzstream/ofgzstream
192 * reading/writing gzip files.
194 * Don't use fXstream directly, but @ref ifgzstream or
195 * @ref ofgzstream. fXstream is just to avoid almost
198 template<class TBStream,class TStreamBuf>
199 class fXstream : public TBStream
203 typedef gzstream_detail::ZlibError ZlibError;
204 typedef TBStream stream_type;
205 typedef TStreamBuf streambuf_type;
208 : stream_type( NULL )
209 { this->init( &_streambuf ); }
212 fXstream( const char * file_r )
213 : stream_type( NULL )
214 { this->init( &_streambuf ); this->open( file_r ); }
222 { return _streambuf.isOpen(); }
225 open( const char * file_r )
227 if ( !_streambuf.open( file_r, defMode(*this) ) )
228 this->setstate(std::ios_base::failbit);
236 if ( !_streambuf.close() )
237 this->setstate(std::ios_base::failbit);
241 * The last error returned retuned fron zlib.
245 { return _streambuf.zError(); }
247 //! Similar to ios::rdbuf.
248 //! But it returns our specific type, not the generic streambuf *.
249 const streambuf_type&
251 { return _streambuf; }
255 streambuf_type _streambuf;
257 std::ios_base::openmode
258 defMode( const std::istream & str_r )
259 { return std::ios_base::in; }
261 std::ios_base::openmode
262 defMode( const std::ostream & str_r )
263 { return std::ios_base::out; }
266 ///////////////////////////////////////////////////////////////////
268 /////////////////////////////////////////////////////////////////
269 } // namespace gzstream_detail
270 ///////////////////////////////////////////////////////////////////
273 * istream reading gzip files as well as plain files.
275 typedef gzstream_detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
278 * ostream writing gzip files.
280 typedef gzstream_detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
282 /////////////////////////////////////////////////////////////////
284 ///////////////////////////////////////////////////////////////////
286 #endif // ZYPP_BASE_GZSTREAM_H