1 1.1 christos 2 1.1 christos #include "zfstream.h" 3 1.1 christos 4 1.1 christos gzfilebuf::gzfilebuf() : 5 1.1 christos file(NULL), 6 1.1 christos mode(0), 7 1.1 christos own_file_descriptor(0) 8 1.1 christos { } 9 1.1 christos 10 1.1 christos gzfilebuf::~gzfilebuf() { 11 1.1 christos 12 1.1 christos sync(); 13 1.1 christos if ( own_file_descriptor ) 14 1.1 christos close(); 15 1.1 christos 16 1.1 christos } 17 1.1 christos 18 1.1 christos gzfilebuf *gzfilebuf::open( const char *name, 19 1.1 christos int io_mode ) { 20 1.1 christos 21 1.1 christos if ( is_open() ) 22 1.1 christos return NULL; 23 1.1 christos 24 1.1 christos char char_mode[10]; 25 1.1 christos char *p = char_mode; 26 1.1 christos 27 1.1 christos if ( io_mode & ios::in ) { 28 1.1 christos mode = ios::in; 29 1.1 christos *p++ = 'r'; 30 1.1 christos } else if ( io_mode & ios::app ) { 31 1.1 christos mode = ios::app; 32 1.1 christos *p++ = 'a'; 33 1.1 christos } else { 34 1.1 christos mode = ios::out; 35 1.1 christos *p++ = 'w'; 36 1.1 christos } 37 1.1 christos 38 1.1 christos if ( io_mode & ios::binary ) { 39 1.1 christos mode |= ios::binary; 40 1.1 christos *p++ = 'b'; 41 1.1 christos } 42 1.1 christos 43 1.1 christos // Hard code the compression level 44 1.1 christos if ( io_mode & (ios::out|ios::app )) { 45 1.1 christos *p++ = '9'; 46 1.1 christos } 47 1.1 christos 48 1.1 christos // Put the end-of-string indicator 49 1.1 christos *p = '\0'; 50 1.1 christos 51 1.1 christos if ( (file = gzopen(name, char_mode)) == NULL ) 52 1.1 christos return NULL; 53 1.1 christos 54 1.1 christos own_file_descriptor = 1; 55 1.1 christos 56 1.1 christos return this; 57 1.1 christos 58 1.1 christos } 59 1.1 christos 60 1.1 christos gzfilebuf *gzfilebuf::attach( int file_descriptor, 61 1.1 christos int io_mode ) { 62 1.1 christos 63 1.1 christos if ( is_open() ) 64 1.1 christos return NULL; 65 1.1 christos 66 1.1 christos char char_mode[10]; 67 1.1 christos char *p = char_mode; 68 1.1 christos 69 1.1 christos if ( io_mode & ios::in ) { 70 1.1 christos mode = ios::in; 71 1.1 christos *p++ = 'r'; 72 1.1 christos } else if ( io_mode & ios::app ) { 73 1.1 christos mode = ios::app; 74 1.1 christos *p++ = 'a'; 75 1.1 christos } else { 76 1.1 christos mode = ios::out; 77 1.1 christos *p++ = 'w'; 78 1.1 christos } 79 1.1 christos 80 1.1 christos if ( io_mode & ios::binary ) { 81 1.1 christos mode |= ios::binary; 82 1.1 christos *p++ = 'b'; 83 1.1 christos } 84 1.1 christos 85 1.1 christos // Hard code the compression level 86 1.1 christos if ( io_mode & (ios::out|ios::app )) { 87 1.1 christos *p++ = '9'; 88 1.1 christos } 89 1.1 christos 90 1.1 christos // Put the end-of-string indicator 91 1.1 christos *p = '\0'; 92 1.1 christos 93 1.1 christos if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) 94 1.1 christos return NULL; 95 1.1 christos 96 1.1 christos own_file_descriptor = 0; 97 1.1 christos 98 1.1 christos return this; 99 1.1 christos 100 1.1 christos } 101 1.1 christos 102 1.1 christos gzfilebuf *gzfilebuf::close() { 103 1.1 christos 104 1.1 christos if ( is_open() ) { 105 1.1 christos 106 1.1 christos sync(); 107 1.1 christos gzclose( file ); 108 1.1 christos file = NULL; 109 1.1 christos 110 1.1 christos } 111 1.1 christos 112 1.1 christos return this; 113 1.1 christos 114 1.1 christos } 115 1.1 christos 116 1.1 christos int gzfilebuf::setcompressionlevel( int comp_level ) { 117 1.1 christos 118 1.1 christos return gzsetparams(file, comp_level, -2); 119 1.1 christos 120 1.1 christos } 121 1.1 christos 122 1.1 christos int gzfilebuf::setcompressionstrategy( int comp_strategy ) { 123 1.1 christos 124 1.1 christos return gzsetparams(file, -2, comp_strategy); 125 1.1 christos 126 1.1 christos } 127 1.1 christos 128 1.1 christos 129 1.1 christos streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { 130 1.1 christos 131 1.1 christos return streampos(EOF); 132 1.1 christos 133 1.1 christos } 134 1.1 christos 135 1.1 christos int gzfilebuf::underflow() { 136 1.1 christos 137 1.1 christos // If the file hasn't been opened for reading, error. 138 1.1 christos if ( !is_open() || !(mode & ios::in) ) 139 1.1 christos return EOF; 140 1.1 christos 141 1.1 christos // if a buffer doesn't exists, allocate one. 142 1.1 christos if ( !base() ) { 143 1.1 christos 144 1.1 christos if ( (allocate()) == EOF ) 145 1.1 christos return EOF; 146 1.1 christos setp(0,0); 147 1.1 christos 148 1.1 christos } else { 149 1.1 christos 150 1.1 christos if ( in_avail() ) 151 1.1 christos return (unsigned char) *gptr(); 152 1.1 christos 153 1.1 christos if ( out_waiting() ) { 154 1.1 christos if ( flushbuf() == EOF ) 155 1.1 christos return EOF; 156 1.1 christos } 157 1.1 christos 158 1.1 christos } 159 1.1 christos 160 1.1 christos // Attempt to fill the buffer. 161 1.1 christos 162 1.1 christos int result = fillbuf(); 163 1.1 christos if ( result == EOF ) { 164 1.1 christos // disable get area 165 1.1 christos setg(0,0,0); 166 1.1 christos return EOF; 167 1.1 christos } 168 1.1 christos 169 1.1 christos return (unsigned char) *gptr(); 170 1.1 christos 171 1.1 christos } 172 1.1 christos 173 1.1 christos int gzfilebuf::overflow( int c ) { 174 1.1 christos 175 1.1 christos if ( !is_open() || !(mode & ios::out) ) 176 1.1 christos return EOF; 177 1.1 christos 178 1.1 christos if ( !base() ) { 179 1.1 christos if ( allocate() == EOF ) 180 1.1 christos return EOF; 181 1.1 christos setg(0,0,0); 182 1.1 christos } else { 183 1.1 christos if (in_avail()) { 184 1.1 christos return EOF; 185 1.1 christos } 186 1.1 christos if (out_waiting()) { 187 1.1 christos if (flushbuf() == EOF) 188 1.1 christos return EOF; 189 1.1 christos } 190 1.1 christos } 191 1.1 christos 192 1.1 christos int bl = blen(); 193 1.1 christos setp( base(), base() + bl); 194 1.1 christos 195 1.1 christos if ( c != EOF ) { 196 1.1 christos 197 1.1 christos *pptr() = c; 198 1.1 christos pbump(1); 199 1.1 christos 200 1.1 christos } 201 1.1 christos 202 1.1 christos return 0; 203 1.1 christos 204 1.1 christos } 205 1.1 christos 206 1.1 christos int gzfilebuf::sync() { 207 1.1 christos 208 1.1 christos if ( !is_open() ) 209 1.1 christos return EOF; 210 1.1 christos 211 1.1 christos if ( out_waiting() ) 212 1.1 christos return flushbuf(); 213 1.1 christos 214 1.1 christos return 0; 215 1.1 christos 216 1.1 christos } 217 1.1 christos 218 1.1 christos int gzfilebuf::flushbuf() { 219 1.1 christos 220 1.1 christos int n; 221 1.1 christos char *q; 222 1.1 christos 223 1.1 christos q = pbase(); 224 1.1 christos n = pptr() - q; 225 1.1 christos 226 1.1 christos if ( gzwrite( file, q, n) < n ) 227 1.1 christos return EOF; 228 1.1 christos 229 1.1 christos setp(0,0); 230 1.1 christos 231 1.1 christos return 0; 232 1.1 christos 233 1.1 christos } 234 1.1 christos 235 1.1 christos int gzfilebuf::fillbuf() { 236 1.1 christos 237 1.1 christos int required; 238 1.1 christos char *p; 239 1.1 christos 240 1.1 christos p = base(); 241 1.1 christos 242 1.1 christos required = blen(); 243 1.1 christos 244 1.1 christos int t = gzread( file, p, required ); 245 1.1 christos 246 1.1 christos if ( t <= 0) return EOF; 247 1.1 christos 248 1.1 christos setg( base(), base(), base()+t); 249 1.1 christos 250 1.1 christos return t; 251 1.1 christos 252 1.1 christos } 253 1.1 christos 254 1.1 christos gzfilestream_common::gzfilestream_common() : 255 1.1 christos ios( gzfilestream_common::rdbuf() ) 256 1.1 christos { } 257 1.1 christos 258 1.1 christos gzfilestream_common::~gzfilestream_common() 259 1.1 christos { } 260 1.1 christos 261 1.1 christos void gzfilestream_common::attach( int fd, int io_mode ) { 262 1.1 christos 263 1.1 christos if ( !buffer.attach( fd, io_mode) ) 264 1.1 christos clear( ios::failbit | ios::badbit ); 265 1.1 christos else 266 1.1 christos clear(); 267 1.1 christos 268 1.1 christos } 269 1.1 christos 270 1.1 christos void gzfilestream_common::open( const char *name, int io_mode ) { 271 1.1 christos 272 1.1 christos if ( !buffer.open( name, io_mode ) ) 273 1.1 christos clear( ios::failbit | ios::badbit ); 274 1.1 christos else 275 1.1 christos clear(); 276 1.1 christos 277 1.1 christos } 278 1.1 christos 279 1.1 christos void gzfilestream_common::close() { 280 1.1 christos 281 1.1 christos if ( !buffer.close() ) 282 1.1 christos clear( ios::failbit | ios::badbit ); 283 1.1 christos 284 1.1 christos } 285 1.1 christos 286 1.1 christos gzfilebuf *gzfilestream_common::rdbuf() 287 1.1 christos { 288 1.1 christos return &buffer; 289 1.1 christos } 290 1.1 christos 291 1.1 christos gzifstream::gzifstream() : 292 1.1 christos ios( gzfilestream_common::rdbuf() ) 293 1.1 christos { 294 1.1 christos clear( ios::badbit ); 295 1.1 christos } 296 1.1 christos 297 1.1 christos gzifstream::gzifstream( const char *name, int io_mode ) : 298 1.1 christos ios( gzfilestream_common::rdbuf() ) 299 1.1 christos { 300 1.1 christos gzfilestream_common::open( name, io_mode ); 301 1.1 christos } 302 1.1 christos 303 1.1 christos gzifstream::gzifstream( int fd, int io_mode ) : 304 1.1 christos ios( gzfilestream_common::rdbuf() ) 305 1.1 christos { 306 1.1 christos gzfilestream_common::attach( fd, io_mode ); 307 1.1 christos } 308 1.1 christos 309 1.1 christos gzifstream::~gzifstream() { } 310 1.1 christos 311 1.1 christos gzofstream::gzofstream() : 312 1.1 christos ios( gzfilestream_common::rdbuf() ) 313 1.1 christos { 314 1.1 christos clear( ios::badbit ); 315 1.1 christos } 316 1.1 christos 317 1.1 christos gzofstream::gzofstream( const char *name, int io_mode ) : 318 1.1 christos ios( gzfilestream_common::rdbuf() ) 319 1.1 christos { 320 1.1 christos gzfilestream_common::open( name, io_mode ); 321 1.1 christos } 322 1.1 christos 323 1.1 christos gzofstream::gzofstream( int fd, int io_mode ) : 324 1.1 christos ios( gzfilestream_common::rdbuf() ) 325 1.1 christos { 326 1.1 christos gzfilestream_common::attach( fd, io_mode ); 327 1.1 christos } 328 1.1 christos 329 1.1 christos gzofstream::~gzofstream() { } 330