1275793eaSopenharmony_ci 2275793eaSopenharmony_ci#include "zfstream.h" 3275793eaSopenharmony_ci 4275793eaSopenharmony_cigzfilebuf::gzfilebuf() : 5275793eaSopenharmony_ci file(NULL), 6275793eaSopenharmony_ci mode(0), 7275793eaSopenharmony_ci own_file_descriptor(0) 8275793eaSopenharmony_ci{ } 9275793eaSopenharmony_ci 10275793eaSopenharmony_cigzfilebuf::~gzfilebuf() { 11275793eaSopenharmony_ci 12275793eaSopenharmony_ci sync(); 13275793eaSopenharmony_ci if ( own_file_descriptor ) 14275793eaSopenharmony_ci close(); 15275793eaSopenharmony_ci 16275793eaSopenharmony_ci} 17275793eaSopenharmony_ci 18275793eaSopenharmony_cigzfilebuf *gzfilebuf::open( const char *name, 19275793eaSopenharmony_ci int io_mode ) { 20275793eaSopenharmony_ci 21275793eaSopenharmony_ci if ( is_open() ) 22275793eaSopenharmony_ci return NULL; 23275793eaSopenharmony_ci 24275793eaSopenharmony_ci char char_mode[10]; 25275793eaSopenharmony_ci char *p = char_mode; 26275793eaSopenharmony_ci 27275793eaSopenharmony_ci if ( io_mode & ios::in ) { 28275793eaSopenharmony_ci mode = ios::in; 29275793eaSopenharmony_ci *p++ = 'r'; 30275793eaSopenharmony_ci } else if ( io_mode & ios::app ) { 31275793eaSopenharmony_ci mode = ios::app; 32275793eaSopenharmony_ci *p++ = 'a'; 33275793eaSopenharmony_ci } else { 34275793eaSopenharmony_ci mode = ios::out; 35275793eaSopenharmony_ci *p++ = 'w'; 36275793eaSopenharmony_ci } 37275793eaSopenharmony_ci 38275793eaSopenharmony_ci if ( io_mode & ios::binary ) { 39275793eaSopenharmony_ci mode |= ios::binary; 40275793eaSopenharmony_ci *p++ = 'b'; 41275793eaSopenharmony_ci } 42275793eaSopenharmony_ci 43275793eaSopenharmony_ci // Hard code the compression level 44275793eaSopenharmony_ci if ( io_mode & (ios::out|ios::app )) { 45275793eaSopenharmony_ci *p++ = '9'; 46275793eaSopenharmony_ci } 47275793eaSopenharmony_ci 48275793eaSopenharmony_ci // Put the end-of-string indicator 49275793eaSopenharmony_ci *p = '\0'; 50275793eaSopenharmony_ci 51275793eaSopenharmony_ci if ( (file = gzopen(name, char_mode)) == NULL ) 52275793eaSopenharmony_ci return NULL; 53275793eaSopenharmony_ci 54275793eaSopenharmony_ci own_file_descriptor = 1; 55275793eaSopenharmony_ci 56275793eaSopenharmony_ci return this; 57275793eaSopenharmony_ci 58275793eaSopenharmony_ci} 59275793eaSopenharmony_ci 60275793eaSopenharmony_cigzfilebuf *gzfilebuf::attach( int file_descriptor, 61275793eaSopenharmony_ci int io_mode ) { 62275793eaSopenharmony_ci 63275793eaSopenharmony_ci if ( is_open() ) 64275793eaSopenharmony_ci return NULL; 65275793eaSopenharmony_ci 66275793eaSopenharmony_ci char char_mode[10]; 67275793eaSopenharmony_ci char *p = char_mode; 68275793eaSopenharmony_ci 69275793eaSopenharmony_ci if ( io_mode & ios::in ) { 70275793eaSopenharmony_ci mode = ios::in; 71275793eaSopenharmony_ci *p++ = 'r'; 72275793eaSopenharmony_ci } else if ( io_mode & ios::app ) { 73275793eaSopenharmony_ci mode = ios::app; 74275793eaSopenharmony_ci *p++ = 'a'; 75275793eaSopenharmony_ci } else { 76275793eaSopenharmony_ci mode = ios::out; 77275793eaSopenharmony_ci *p++ = 'w'; 78275793eaSopenharmony_ci } 79275793eaSopenharmony_ci 80275793eaSopenharmony_ci if ( io_mode & ios::binary ) { 81275793eaSopenharmony_ci mode |= ios::binary; 82275793eaSopenharmony_ci *p++ = 'b'; 83275793eaSopenharmony_ci } 84275793eaSopenharmony_ci 85275793eaSopenharmony_ci // Hard code the compression level 86275793eaSopenharmony_ci if ( io_mode & (ios::out|ios::app )) { 87275793eaSopenharmony_ci *p++ = '9'; 88275793eaSopenharmony_ci } 89275793eaSopenharmony_ci 90275793eaSopenharmony_ci // Put the end-of-string indicator 91275793eaSopenharmony_ci *p = '\0'; 92275793eaSopenharmony_ci 93275793eaSopenharmony_ci if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) 94275793eaSopenharmony_ci return NULL; 95275793eaSopenharmony_ci 96275793eaSopenharmony_ci own_file_descriptor = 0; 97275793eaSopenharmony_ci 98275793eaSopenharmony_ci return this; 99275793eaSopenharmony_ci 100275793eaSopenharmony_ci} 101275793eaSopenharmony_ci 102275793eaSopenharmony_cigzfilebuf *gzfilebuf::close() { 103275793eaSopenharmony_ci 104275793eaSopenharmony_ci if ( is_open() ) { 105275793eaSopenharmony_ci 106275793eaSopenharmony_ci sync(); 107275793eaSopenharmony_ci gzclose( file ); 108275793eaSopenharmony_ci file = NULL; 109275793eaSopenharmony_ci 110275793eaSopenharmony_ci } 111275793eaSopenharmony_ci 112275793eaSopenharmony_ci return this; 113275793eaSopenharmony_ci 114275793eaSopenharmony_ci} 115275793eaSopenharmony_ci 116275793eaSopenharmony_ciint gzfilebuf::setcompressionlevel( int comp_level ) { 117275793eaSopenharmony_ci 118275793eaSopenharmony_ci return gzsetparams(file, comp_level, -2); 119275793eaSopenharmony_ci 120275793eaSopenharmony_ci} 121275793eaSopenharmony_ci 122275793eaSopenharmony_ciint gzfilebuf::setcompressionstrategy( int comp_strategy ) { 123275793eaSopenharmony_ci 124275793eaSopenharmony_ci return gzsetparams(file, -2, comp_strategy); 125275793eaSopenharmony_ci 126275793eaSopenharmony_ci} 127275793eaSopenharmony_ci 128275793eaSopenharmony_ci 129275793eaSopenharmony_cistreampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { 130275793eaSopenharmony_ci 131275793eaSopenharmony_ci return streampos(EOF); 132275793eaSopenharmony_ci 133275793eaSopenharmony_ci} 134275793eaSopenharmony_ci 135275793eaSopenharmony_ciint gzfilebuf::underflow() { 136275793eaSopenharmony_ci 137275793eaSopenharmony_ci // If the file hasn't been opened for reading, error. 138275793eaSopenharmony_ci if ( !is_open() || !(mode & ios::in) ) 139275793eaSopenharmony_ci return EOF; 140275793eaSopenharmony_ci 141275793eaSopenharmony_ci // if a buffer doesn't exists, allocate one. 142275793eaSopenharmony_ci if ( !base() ) { 143275793eaSopenharmony_ci 144275793eaSopenharmony_ci if ( (allocate()) == EOF ) 145275793eaSopenharmony_ci return EOF; 146275793eaSopenharmony_ci setp(0,0); 147275793eaSopenharmony_ci 148275793eaSopenharmony_ci } else { 149275793eaSopenharmony_ci 150275793eaSopenharmony_ci if ( in_avail() ) 151275793eaSopenharmony_ci return (unsigned char) *gptr(); 152275793eaSopenharmony_ci 153275793eaSopenharmony_ci if ( out_waiting() ) { 154275793eaSopenharmony_ci if ( flushbuf() == EOF ) 155275793eaSopenharmony_ci return EOF; 156275793eaSopenharmony_ci } 157275793eaSopenharmony_ci 158275793eaSopenharmony_ci } 159275793eaSopenharmony_ci 160275793eaSopenharmony_ci // Attempt to fill the buffer. 161275793eaSopenharmony_ci 162275793eaSopenharmony_ci int result = fillbuf(); 163275793eaSopenharmony_ci if ( result == EOF ) { 164275793eaSopenharmony_ci // disable get area 165275793eaSopenharmony_ci setg(0,0,0); 166275793eaSopenharmony_ci return EOF; 167275793eaSopenharmony_ci } 168275793eaSopenharmony_ci 169275793eaSopenharmony_ci return (unsigned char) *gptr(); 170275793eaSopenharmony_ci 171275793eaSopenharmony_ci} 172275793eaSopenharmony_ci 173275793eaSopenharmony_ciint gzfilebuf::overflow( int c ) { 174275793eaSopenharmony_ci 175275793eaSopenharmony_ci if ( !is_open() || !(mode & ios::out) ) 176275793eaSopenharmony_ci return EOF; 177275793eaSopenharmony_ci 178275793eaSopenharmony_ci if ( !base() ) { 179275793eaSopenharmony_ci if ( allocate() == EOF ) 180275793eaSopenharmony_ci return EOF; 181275793eaSopenharmony_ci setg(0,0,0); 182275793eaSopenharmony_ci } else { 183275793eaSopenharmony_ci if (in_avail()) { 184275793eaSopenharmony_ci return EOF; 185275793eaSopenharmony_ci } 186275793eaSopenharmony_ci if (out_waiting()) { 187275793eaSopenharmony_ci if (flushbuf() == EOF) 188275793eaSopenharmony_ci return EOF; 189275793eaSopenharmony_ci } 190275793eaSopenharmony_ci } 191275793eaSopenharmony_ci 192275793eaSopenharmony_ci int bl = blen(); 193275793eaSopenharmony_ci setp( base(), base() + bl); 194275793eaSopenharmony_ci 195275793eaSopenharmony_ci if ( c != EOF ) { 196275793eaSopenharmony_ci 197275793eaSopenharmony_ci *pptr() = c; 198275793eaSopenharmony_ci pbump(1); 199275793eaSopenharmony_ci 200275793eaSopenharmony_ci } 201275793eaSopenharmony_ci 202275793eaSopenharmony_ci return 0; 203275793eaSopenharmony_ci 204275793eaSopenharmony_ci} 205275793eaSopenharmony_ci 206275793eaSopenharmony_ciint gzfilebuf::sync() { 207275793eaSopenharmony_ci 208275793eaSopenharmony_ci if ( !is_open() ) 209275793eaSopenharmony_ci return EOF; 210275793eaSopenharmony_ci 211275793eaSopenharmony_ci if ( out_waiting() ) 212275793eaSopenharmony_ci return flushbuf(); 213275793eaSopenharmony_ci 214275793eaSopenharmony_ci return 0; 215275793eaSopenharmony_ci 216275793eaSopenharmony_ci} 217275793eaSopenharmony_ci 218275793eaSopenharmony_ciint gzfilebuf::flushbuf() { 219275793eaSopenharmony_ci 220275793eaSopenharmony_ci int n; 221275793eaSopenharmony_ci char *q; 222275793eaSopenharmony_ci 223275793eaSopenharmony_ci q = pbase(); 224275793eaSopenharmony_ci n = pptr() - q; 225275793eaSopenharmony_ci 226275793eaSopenharmony_ci if ( gzwrite( file, q, n) < n ) 227275793eaSopenharmony_ci return EOF; 228275793eaSopenharmony_ci 229275793eaSopenharmony_ci setp(0,0); 230275793eaSopenharmony_ci 231275793eaSopenharmony_ci return 0; 232275793eaSopenharmony_ci 233275793eaSopenharmony_ci} 234275793eaSopenharmony_ci 235275793eaSopenharmony_ciint gzfilebuf::fillbuf() { 236275793eaSopenharmony_ci 237275793eaSopenharmony_ci int required; 238275793eaSopenharmony_ci char *p; 239275793eaSopenharmony_ci 240275793eaSopenharmony_ci p = base(); 241275793eaSopenharmony_ci 242275793eaSopenharmony_ci required = blen(); 243275793eaSopenharmony_ci 244275793eaSopenharmony_ci int t = gzread( file, p, required ); 245275793eaSopenharmony_ci 246275793eaSopenharmony_ci if ( t <= 0) return EOF; 247275793eaSopenharmony_ci 248275793eaSopenharmony_ci setg( base(), base(), base()+t); 249275793eaSopenharmony_ci 250275793eaSopenharmony_ci return t; 251275793eaSopenharmony_ci 252275793eaSopenharmony_ci} 253275793eaSopenharmony_ci 254275793eaSopenharmony_cigzfilestream_common::gzfilestream_common() : 255275793eaSopenharmony_ci ios( gzfilestream_common::rdbuf() ) 256275793eaSopenharmony_ci{ } 257275793eaSopenharmony_ci 258275793eaSopenharmony_cigzfilestream_common::~gzfilestream_common() 259275793eaSopenharmony_ci{ } 260275793eaSopenharmony_ci 261275793eaSopenharmony_civoid gzfilestream_common::attach( int fd, int io_mode ) { 262275793eaSopenharmony_ci 263275793eaSopenharmony_ci if ( !buffer.attach( fd, io_mode) ) 264275793eaSopenharmony_ci clear( ios::failbit | ios::badbit ); 265275793eaSopenharmony_ci else 266275793eaSopenharmony_ci clear(); 267275793eaSopenharmony_ci 268275793eaSopenharmony_ci} 269275793eaSopenharmony_ci 270275793eaSopenharmony_civoid gzfilestream_common::open( const char *name, int io_mode ) { 271275793eaSopenharmony_ci 272275793eaSopenharmony_ci if ( !buffer.open( name, io_mode ) ) 273275793eaSopenharmony_ci clear( ios::failbit | ios::badbit ); 274275793eaSopenharmony_ci else 275275793eaSopenharmony_ci clear(); 276275793eaSopenharmony_ci 277275793eaSopenharmony_ci} 278275793eaSopenharmony_ci 279275793eaSopenharmony_civoid gzfilestream_common::close() { 280275793eaSopenharmony_ci 281275793eaSopenharmony_ci if ( !buffer.close() ) 282275793eaSopenharmony_ci clear( ios::failbit | ios::badbit ); 283275793eaSopenharmony_ci 284275793eaSopenharmony_ci} 285275793eaSopenharmony_ci 286275793eaSopenharmony_cigzfilebuf *gzfilestream_common::rdbuf() 287275793eaSopenharmony_ci{ 288275793eaSopenharmony_ci return &buffer; 289275793eaSopenharmony_ci} 290275793eaSopenharmony_ci 291275793eaSopenharmony_cigzifstream::gzifstream() : 292275793eaSopenharmony_ci ios( gzfilestream_common::rdbuf() ) 293275793eaSopenharmony_ci{ 294275793eaSopenharmony_ci clear( ios::badbit ); 295275793eaSopenharmony_ci} 296275793eaSopenharmony_ci 297275793eaSopenharmony_cigzifstream::gzifstream( const char *name, int io_mode ) : 298275793eaSopenharmony_ci ios( gzfilestream_common::rdbuf() ) 299275793eaSopenharmony_ci{ 300275793eaSopenharmony_ci gzfilestream_common::open( name, io_mode ); 301275793eaSopenharmony_ci} 302275793eaSopenharmony_ci 303275793eaSopenharmony_cigzifstream::gzifstream( int fd, int io_mode ) : 304275793eaSopenharmony_ci ios( gzfilestream_common::rdbuf() ) 305275793eaSopenharmony_ci{ 306275793eaSopenharmony_ci gzfilestream_common::attach( fd, io_mode ); 307275793eaSopenharmony_ci} 308275793eaSopenharmony_ci 309275793eaSopenharmony_cigzifstream::~gzifstream() { } 310275793eaSopenharmony_ci 311275793eaSopenharmony_cigzofstream::gzofstream() : 312275793eaSopenharmony_ci ios( gzfilestream_common::rdbuf() ) 313275793eaSopenharmony_ci{ 314275793eaSopenharmony_ci clear( ios::badbit ); 315275793eaSopenharmony_ci} 316275793eaSopenharmony_ci 317275793eaSopenharmony_cigzofstream::gzofstream( const char *name, int io_mode ) : 318275793eaSopenharmony_ci ios( gzfilestream_common::rdbuf() ) 319275793eaSopenharmony_ci{ 320275793eaSopenharmony_ci gzfilestream_common::open( name, io_mode ); 321275793eaSopenharmony_ci} 322275793eaSopenharmony_ci 323275793eaSopenharmony_cigzofstream::gzofstream( int fd, int io_mode ) : 324275793eaSopenharmony_ci ios( gzfilestream_common::rdbuf() ) 325275793eaSopenharmony_ci{ 326275793eaSopenharmony_ci gzfilestream_common::attach( fd, io_mode ); 327275793eaSopenharmony_ci} 328275793eaSopenharmony_ci 329275793eaSopenharmony_cigzofstream::~gzofstream() { } 330