00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef gzstream_h
00022 #define gzstream_h
00023
00024 #include <iostream>
00025 #include <vector>
00026 #include <zlib.h>
00027
00029
00030
00034 struct ZlibError
00035 {
00039 int _zError;
00040
00044 int _errno;
00045
00046 ZlibError()
00047 : _zError( 0 ), _errno( 0 )
00048 {}
00049
00053 std::string
00054 strerror() const;
00055 };
00057
00059
00060
00073 class fgzstreambuf : public std::streambuf {
00074
00075 public:
00076
00077 fgzstreambuf( unsigned bufferSize_r = 512 )
00078 : _file( NULL )
00079 , _mode( std::ios_base::openmode(0) )
00080 , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
00081 {}
00082
00083 virtual
00084 ~fgzstreambuf()
00085 { close(); }
00086
00087 bool
00088 isOpen() const
00089 { return _file; }
00090
00091 bool
00092 inReadMode() const
00093 { return( _mode == std::ios_base::in ); }
00094
00095 bool
00096 inWriteMode() const
00097 { return( _mode == std::ios_base::out ); }
00098
00099 fgzstreambuf *
00100 open( const char * name_r, std::ios_base::openmode mode_r );
00101
00102 fgzstreambuf *
00103 close();
00104
00108 ZlibError
00109 zError() const
00110 { return _error; }
00111
00112 protected:
00113
00114 virtual int
00115 sync();
00116
00117 virtual int_type
00118 overflow( int_type c = traits_type::eof() );
00119
00120 virtual int_type
00121 underflow();
00122
00123 virtual pos_type
00124 seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode )
00125 { return seekTo( off_r, way_r ); }
00126
00127 virtual pos_type
00128 seekpos( pos_type pos_r, std::ios_base::openmode )
00129 { return seekTo( off_type(pos_r), std::ios_base::beg ); }
00130
00131 private:
00132
00133 typedef std::vector<char> buffer_type;
00134
00135 gzFile _file;
00136
00137 std::ios_base::openmode _mode;
00138
00139 buffer_type _buffer;
00140
00141 ZlibError _error;
00142
00143 private:
00144
00145 void
00146 setZError()
00147 { gzerror( _file, &_error._zError ); }
00148
00149 std::streamsize
00150 zReadTo( char * buffer_r, std::streamsize maxcount_r );
00151
00152 bool
00153 zWriteFrom( const char * buffer_r, std::streamsize count_r );
00154
00155 pos_type
00156 zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
00157
00158 pos_type
00159 zTell();
00160
00161 pos_type
00162 seekTo( off_type off_r, std::ios_base::seekdir way_r );
00163 };
00165
00167
00168
00177 template<class _BStream,class _StreamBuf>
00178 class fXstream : public _BStream
00179 {
00180 public:
00181
00182 typedef _BStream stream_type;
00183 typedef _StreamBuf streambuf_type;
00184
00185 fXstream()
00186 : stream_type( NULL )
00187 { this->init( &_streambuf ); }
00188
00189 explicit
00190 fXstream( const char * file_r )
00191 : stream_type( NULL )
00192 { this->init( &_streambuf ); this->open( file_r ); }
00193
00194 virtual
00195 ~fXstream()
00196 {}
00197
00198 bool
00199 is_open() const
00200 { return _streambuf.isOpen(); }
00201
00202 void
00203 open( const char * file_r )
00204 {
00205 if ( !_streambuf.open( file_r, defMode(*this) ) )
00206 this->setstate(std::ios_base::failbit);
00207 else
00208 this->clear();
00209 }
00210
00211 void
00212 close()
00213 {
00214 if ( !_streambuf.close() )
00215 this->setstate(std::ios_base::failbit);
00216 }
00217
00221 ZlibError
00222 zError() const
00223 { return _streambuf.zError(); }
00224
00225
00226 private:
00227
00228 streambuf_type _streambuf;
00229
00230 std::ios_base::openmode
00231 defMode( const std::istream & str_r )
00232 { return std::ios_base::in; }
00233
00234 std::ios_base::openmode
00235 defMode( const std::ostream & str_r )
00236 { return std::ios_base::out; }
00237
00238 };
00240
00242
00246 typedef fXstream<std::istream,fgzstreambuf> ifgzstream;
00247
00251 typedef fXstream<std::ostream,fgzstreambuf> ofgzstream;
00252
00254
00255 #endif // gzstream_h