00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <simgear/compiler.h>
00025
00026 #include <cerrno>
00027 #include <memory.h>
00028 #include <stdio.h>
00029
00030 #include "zfstream.hxx"
00031
00032
00033
00034
00035
00036 gzfilebuf::gzfilebuf()
00037 : std::streambuf(),
00038 file(NULL),
00039 mode(ios_openmode(0)),
00040 own_file_descriptor(false),
00041 ibuf_size(0),
00042 ibuffer(0)
00043 {
00044
00045 ibuf_size = page_size / sizeof(char);
00046 ibuffer = new char [ibuf_size];
00047
00048
00049
00050
00051
00052 this->setg(0,0,0);
00053 this->setp(0,0);
00054 }
00055
00056 gzfilebuf::~gzfilebuf()
00057 {
00058 sync();
00059 if ( own_file_descriptor )
00060 this->close();
00061 delete [] ibuffer;
00062 }
00063
00064 void
00065 gzfilebuf::cvt_iomode( char* p, ios_openmode io_mode )
00066 {
00067
00068
00069
00070 if ( io_mode & ios_in )
00071 {
00072 mode = ios_in;
00073 *p++ = 'r';
00074 }
00075 else if ( io_mode & ios_app )
00076 {
00077 mode = ios_app;
00078 *p++ = 'a';
00079 }
00080 else
00081 {
00082 mode = ios_out;
00083 *p++ = 'w';
00084 }
00085
00086 if ( io_mode & ios_binary )
00087 {
00088 mode |= ios_binary;
00089 *p++ = 'b';
00090 }
00091
00092
00093 if ( io_mode & (ios_out | ios_app) )
00094 {
00095 *p++ = '9';
00096 }
00097
00098 *p = '\0';
00099 }
00100
00101 gzfilebuf*
00102 gzfilebuf::open( const char *name, ios_openmode io_mode )
00103 {
00104 if ( is_open() )
00105 return NULL;
00106
00107 char char_mode[10];
00108 cvt_iomode( char_mode, io_mode );
00109 if ( (file = gzopen(name, char_mode)) == NULL ) {
00110
00111 errno = 0;
00112 return NULL;
00113 }
00114
00115 own_file_descriptor = true;
00116
00117 return this;
00118 }
00119
00120 gzfilebuf*
00121 gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
00122 {
00123 if ( is_open() )
00124 return NULL;
00125
00126 char char_mode[10];
00127 cvt_iomode( char_mode, io_mode );
00128 if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) {
00129 perror( "gzfilebuf::attach(): " );
00130 errno = 0;
00131 return NULL;
00132 }
00133
00134 own_file_descriptor = false;
00135
00136 return this;
00137 }
00138
00139 gzfilebuf*
00140 gzfilebuf::close()
00141 {
00142
00143 if ( is_open() )
00144 {
00145 sync();
00146 gzclose( file );
00147 file = NULL;
00148
00149 } else {
00150
00151 }
00152
00153 return this;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 std::streampos
00170 gzfilebuf::seekoff( std::streamoff, ios_seekdir, int )
00171 {
00172 return std::streampos(EOF);
00173 }
00174
00175 gzfilebuf::int_type
00176 gzfilebuf::overflow( int_type )
00177 {
00178 #if 0
00179 if ( !is_open() || !(mode & ios::out) )
00180 return EOF;
00181
00182 if ( !base() )
00183 {
00184 if ( allocate() == EOF )
00185 return EOF;
00186 setg(0,0,0);
00187 }
00188 else
00189 {
00190 if (in_avail())
00191 {
00192 return EOF;
00193 }
00194
00195 if (out_waiting())
00196 {
00197 if (flushbuf() == EOF)
00198 return EOF;
00199 }
00200 }
00201
00202 int bl = blen();
00203 setp( base(), base() + bl);
00204
00205 if ( c != EOF )
00206 {
00207 *pptr() = c;
00208 pbump(1);
00209 }
00210 #endif
00211 return 0;
00212 }
00213
00214 int
00215 gzfilebuf::sync()
00216 {
00217 if ( !is_open() )
00218 return EOF;
00219
00220 if ( pptr() != 0 && pptr() > pbase() )
00221 return flushbuf();
00222
00223 return 0;
00224 }
00225
00226 gzfilebuf::int_type
00227 gzfilebuf::flushbuf()
00228 {
00229 char* q = pbase();
00230 int n = pptr() - q;
00231
00232 if ( gzwrite( file, q, n) < n )
00233 return traits_type::eof();
00234
00235 setp(0,0);
00236
00237 return 0;
00238 }
00239
00240 gzfilebuf::int_type
00241 gzfilebuf::underflow()
00242 {
00243
00244
00245 if ( !is_open() || !(mode & ios_in) )
00246 return traits_type::eof();
00247
00248
00249 if ( gptr() != 0 && gptr() < egptr() )
00250 {
00251 return int_type(*gptr());
00252 }
00253 else
00254 {
00255 return fillbuf() == EOF ? traits_type::eof() : int_type(*gptr());
00256 }
00257 }
00258
00259
00260
00261
00262
00263 int
00264 gzfilebuf::fillbuf()
00265 {
00266 int t = gzread( file, ibuffer, ibuf_size );
00267 if ( t <= 0)
00268 {
00269
00270 setg(0,0,0);
00271 return EOF;
00272 }
00273
00274
00275 setg( ibuffer, ibuffer, ibuffer+t );
00276
00277
00278
00279
00280
00281
00282 return t;
00283 }
00284
00285 #if 0
00286 gzifstream::gzifstream()
00287 : istream(&buffer), buffer()
00288 {
00289 clear( ios_badbit );
00290 }
00291
00292 gzifstream::gzifstream( const char *name, ios_openmode io_mode )
00293 : istream(&buffer), buffer()
00294 {
00295 this->open( name, io_mode );
00296 }
00297
00298 gzifstream::gzifstream( int fd, ios_openmode io_mode )
00299 : istream(&buffer), buffer()
00300 {
00301 buffer.attach( fd, io_mode );
00302 }
00303
00304 gzifstream::~gzifstream()
00305 {
00306 }
00307
00308 void
00309 gzifstream::open( const char *name, ios_openmode io_mode )
00310 {
00311 if ( !buffer.open( name, io_mode ) )
00312 clear( ios_failbit | ios_badbit );
00313 else
00314 clear();
00315 }
00316
00317 void
00318 gzifstream::close()
00319 {
00320 if ( !buffer.close() )
00321 clear( ios_failbit | ios_badbit );
00322 }
00323 #endif
00324