1275793eaSopenharmony_ci/* 2275793eaSopenharmony_ci * A C++ I/O streams interface to the zlib gz* functions 3275793eaSopenharmony_ci * 4275793eaSopenharmony_ci * by Ludwig Schwardt <schwardt@sun.ac.za> 5275793eaSopenharmony_ci * original version by Kevin Ruland <kevin@rodin.wustl.edu> 6275793eaSopenharmony_ci * 7275793eaSopenharmony_ci * This version is standard-compliant and compatible with gcc 3.x. 8275793eaSopenharmony_ci */ 9275793eaSopenharmony_ci 10275793eaSopenharmony_ci#include "zfstream.h" 11275793eaSopenharmony_ci#include <cstring> // for strcpy, strcat, strlen (mode strings) 12275793eaSopenharmony_ci#include <cstdio> // for BUFSIZ 13275793eaSopenharmony_ci 14275793eaSopenharmony_ci// Internal buffer sizes (default and "unbuffered" versions) 15275793eaSopenharmony_ci#define BIGBUFSIZE BUFSIZ 16275793eaSopenharmony_ci#define SMALLBUFSIZE 1 17275793eaSopenharmony_ci 18275793eaSopenharmony_ci/*****************************************************************************/ 19275793eaSopenharmony_ci 20275793eaSopenharmony_ci// Default constructor 21275793eaSopenharmony_cigzfilebuf::gzfilebuf() 22275793eaSopenharmony_ci: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false), 23275793eaSopenharmony_ci buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true) 24275793eaSopenharmony_ci{ 25275793eaSopenharmony_ci // No buffers to start with 26275793eaSopenharmony_ci this->disable_buffer(); 27275793eaSopenharmony_ci} 28275793eaSopenharmony_ci 29275793eaSopenharmony_ci// Destructor 30275793eaSopenharmony_cigzfilebuf::~gzfilebuf() 31275793eaSopenharmony_ci{ 32275793eaSopenharmony_ci // Sync output buffer and close only if responsible for file 33275793eaSopenharmony_ci // (i.e. attached streams should be left open at this stage) 34275793eaSopenharmony_ci this->sync(); 35275793eaSopenharmony_ci if (own_fd) 36275793eaSopenharmony_ci this->close(); 37275793eaSopenharmony_ci // Make sure internal buffer is deallocated 38275793eaSopenharmony_ci this->disable_buffer(); 39275793eaSopenharmony_ci} 40275793eaSopenharmony_ci 41275793eaSopenharmony_ci// Set compression level and strategy 42275793eaSopenharmony_ciint 43275793eaSopenharmony_cigzfilebuf::setcompression(int comp_level, 44275793eaSopenharmony_ci int comp_strategy) 45275793eaSopenharmony_ci{ 46275793eaSopenharmony_ci return gzsetparams(file, comp_level, comp_strategy); 47275793eaSopenharmony_ci} 48275793eaSopenharmony_ci 49275793eaSopenharmony_ci// Open gzipped file 50275793eaSopenharmony_cigzfilebuf* 51275793eaSopenharmony_cigzfilebuf::open(const char *name, 52275793eaSopenharmony_ci std::ios_base::openmode mode) 53275793eaSopenharmony_ci{ 54275793eaSopenharmony_ci // Fail if file already open 55275793eaSopenharmony_ci if (this->is_open()) 56275793eaSopenharmony_ci return NULL; 57275793eaSopenharmony_ci // Don't support simultaneous read/write access (yet) 58275793eaSopenharmony_ci if ((mode & std::ios_base::in) && (mode & std::ios_base::out)) 59275793eaSopenharmony_ci return NULL; 60275793eaSopenharmony_ci 61275793eaSopenharmony_ci // Build mode string for gzopen and check it [27.8.1.3.2] 62275793eaSopenharmony_ci char char_mode[6] = "\0\0\0\0\0"; 63275793eaSopenharmony_ci if (!this->open_mode(mode, char_mode)) 64275793eaSopenharmony_ci return NULL; 65275793eaSopenharmony_ci 66275793eaSopenharmony_ci // Attempt to open file 67275793eaSopenharmony_ci if ((file = gzopen(name, char_mode)) == NULL) 68275793eaSopenharmony_ci return NULL; 69275793eaSopenharmony_ci 70275793eaSopenharmony_ci // On success, allocate internal buffer and set flags 71275793eaSopenharmony_ci this->enable_buffer(); 72275793eaSopenharmony_ci io_mode = mode; 73275793eaSopenharmony_ci own_fd = true; 74275793eaSopenharmony_ci return this; 75275793eaSopenharmony_ci} 76275793eaSopenharmony_ci 77275793eaSopenharmony_ci// Attach to gzipped file 78275793eaSopenharmony_cigzfilebuf* 79275793eaSopenharmony_cigzfilebuf::attach(int fd, 80275793eaSopenharmony_ci std::ios_base::openmode mode) 81275793eaSopenharmony_ci{ 82275793eaSopenharmony_ci // Fail if file already open 83275793eaSopenharmony_ci if (this->is_open()) 84275793eaSopenharmony_ci return NULL; 85275793eaSopenharmony_ci // Don't support simultaneous read/write access (yet) 86275793eaSopenharmony_ci if ((mode & std::ios_base::in) && (mode & std::ios_base::out)) 87275793eaSopenharmony_ci return NULL; 88275793eaSopenharmony_ci 89275793eaSopenharmony_ci // Build mode string for gzdopen and check it [27.8.1.3.2] 90275793eaSopenharmony_ci char char_mode[6] = "\0\0\0\0\0"; 91275793eaSopenharmony_ci if (!this->open_mode(mode, char_mode)) 92275793eaSopenharmony_ci return NULL; 93275793eaSopenharmony_ci 94275793eaSopenharmony_ci // Attempt to attach to file 95275793eaSopenharmony_ci if ((file = gzdopen(fd, char_mode)) == NULL) 96275793eaSopenharmony_ci return NULL; 97275793eaSopenharmony_ci 98275793eaSopenharmony_ci // On success, allocate internal buffer and set flags 99275793eaSopenharmony_ci this->enable_buffer(); 100275793eaSopenharmony_ci io_mode = mode; 101275793eaSopenharmony_ci own_fd = false; 102275793eaSopenharmony_ci return this; 103275793eaSopenharmony_ci} 104275793eaSopenharmony_ci 105275793eaSopenharmony_ci// Close gzipped file 106275793eaSopenharmony_cigzfilebuf* 107275793eaSopenharmony_cigzfilebuf::close() 108275793eaSopenharmony_ci{ 109275793eaSopenharmony_ci // Fail immediately if no file is open 110275793eaSopenharmony_ci if (!this->is_open()) 111275793eaSopenharmony_ci return NULL; 112275793eaSopenharmony_ci // Assume success 113275793eaSopenharmony_ci gzfilebuf* retval = this; 114275793eaSopenharmony_ci // Attempt to sync and close gzipped file 115275793eaSopenharmony_ci if (this->sync() == -1) 116275793eaSopenharmony_ci retval = NULL; 117275793eaSopenharmony_ci if (gzclose(file) < 0) 118275793eaSopenharmony_ci retval = NULL; 119275793eaSopenharmony_ci // File is now gone anyway (postcondition [27.8.1.3.8]) 120275793eaSopenharmony_ci file = NULL; 121275793eaSopenharmony_ci own_fd = false; 122275793eaSopenharmony_ci // Destroy internal buffer if it exists 123275793eaSopenharmony_ci this->disable_buffer(); 124275793eaSopenharmony_ci return retval; 125275793eaSopenharmony_ci} 126275793eaSopenharmony_ci 127275793eaSopenharmony_ci/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 128275793eaSopenharmony_ci 129275793eaSopenharmony_ci// Convert int open mode to mode string 130275793eaSopenharmony_cibool 131275793eaSopenharmony_cigzfilebuf::open_mode(std::ios_base::openmode mode, 132275793eaSopenharmony_ci char* c_mode) const 133275793eaSopenharmony_ci{ 134275793eaSopenharmony_ci bool testb = mode & std::ios_base::binary; 135275793eaSopenharmony_ci bool testi = mode & std::ios_base::in; 136275793eaSopenharmony_ci bool testo = mode & std::ios_base::out; 137275793eaSopenharmony_ci bool testt = mode & std::ios_base::trunc; 138275793eaSopenharmony_ci bool testa = mode & std::ios_base::app; 139275793eaSopenharmony_ci 140275793eaSopenharmony_ci // Check for valid flag combinations - see [27.8.1.3.2] (Table 92) 141275793eaSopenharmony_ci // Original zfstream hardcoded the compression level to maximum here... 142275793eaSopenharmony_ci // Double the time for less than 1% size improvement seems 143275793eaSopenharmony_ci // excessive though - keeping it at the default level 144275793eaSopenharmony_ci // To change back, just append "9" to the next three mode strings 145275793eaSopenharmony_ci if (!testi && testo && !testt && !testa) 146275793eaSopenharmony_ci strcpy(c_mode, "w"); 147275793eaSopenharmony_ci if (!testi && testo && !testt && testa) 148275793eaSopenharmony_ci strcpy(c_mode, "a"); 149275793eaSopenharmony_ci if (!testi && testo && testt && !testa) 150275793eaSopenharmony_ci strcpy(c_mode, "w"); 151275793eaSopenharmony_ci if (testi && !testo && !testt && !testa) 152275793eaSopenharmony_ci strcpy(c_mode, "r"); 153275793eaSopenharmony_ci // No read/write mode yet 154275793eaSopenharmony_ci// if (testi && testo && !testt && !testa) 155275793eaSopenharmony_ci// strcpy(c_mode, "r+"); 156275793eaSopenharmony_ci// if (testi && testo && testt && !testa) 157275793eaSopenharmony_ci// strcpy(c_mode, "w+"); 158275793eaSopenharmony_ci 159275793eaSopenharmony_ci // Mode string should be empty for invalid combination of flags 160275793eaSopenharmony_ci if (strlen(c_mode) == 0) 161275793eaSopenharmony_ci return false; 162275793eaSopenharmony_ci if (testb) 163275793eaSopenharmony_ci strcat(c_mode, "b"); 164275793eaSopenharmony_ci return true; 165275793eaSopenharmony_ci} 166275793eaSopenharmony_ci 167275793eaSopenharmony_ci// Determine number of characters in internal get buffer 168275793eaSopenharmony_cistd::streamsize 169275793eaSopenharmony_cigzfilebuf::showmanyc() 170275793eaSopenharmony_ci{ 171275793eaSopenharmony_ci // Calls to underflow will fail if file not opened for reading 172275793eaSopenharmony_ci if (!this->is_open() || !(io_mode & std::ios_base::in)) 173275793eaSopenharmony_ci return -1; 174275793eaSopenharmony_ci // Make sure get area is in use 175275793eaSopenharmony_ci if (this->gptr() && (this->gptr() < this->egptr())) 176275793eaSopenharmony_ci return std::streamsize(this->egptr() - this->gptr()); 177275793eaSopenharmony_ci else 178275793eaSopenharmony_ci return 0; 179275793eaSopenharmony_ci} 180275793eaSopenharmony_ci 181275793eaSopenharmony_ci// Fill get area from gzipped file 182275793eaSopenharmony_cigzfilebuf::int_type 183275793eaSopenharmony_cigzfilebuf::underflow() 184275793eaSopenharmony_ci{ 185275793eaSopenharmony_ci // If something is left in the get area by chance, return it 186275793eaSopenharmony_ci // (this shouldn't normally happen, as underflow is only supposed 187275793eaSopenharmony_ci // to be called when gptr >= egptr, but it serves as error check) 188275793eaSopenharmony_ci if (this->gptr() && (this->gptr() < this->egptr())) 189275793eaSopenharmony_ci return traits_type::to_int_type(*(this->gptr())); 190275793eaSopenharmony_ci 191275793eaSopenharmony_ci // If the file hasn't been opened for reading, produce error 192275793eaSopenharmony_ci if (!this->is_open() || !(io_mode & std::ios_base::in)) 193275793eaSopenharmony_ci return traits_type::eof(); 194275793eaSopenharmony_ci 195275793eaSopenharmony_ci // Attempt to fill internal buffer from gzipped file 196275793eaSopenharmony_ci // (buffer must be guaranteed to exist...) 197275793eaSopenharmony_ci int bytes_read = gzread(file, buffer, buffer_size); 198275793eaSopenharmony_ci // Indicates error or EOF 199275793eaSopenharmony_ci if (bytes_read <= 0) 200275793eaSopenharmony_ci { 201275793eaSopenharmony_ci // Reset get area 202275793eaSopenharmony_ci this->setg(buffer, buffer, buffer); 203275793eaSopenharmony_ci return traits_type::eof(); 204275793eaSopenharmony_ci } 205275793eaSopenharmony_ci // Make all bytes read from file available as get area 206275793eaSopenharmony_ci this->setg(buffer, buffer, buffer + bytes_read); 207275793eaSopenharmony_ci 208275793eaSopenharmony_ci // Return next character in get area 209275793eaSopenharmony_ci return traits_type::to_int_type(*(this->gptr())); 210275793eaSopenharmony_ci} 211275793eaSopenharmony_ci 212275793eaSopenharmony_ci// Write put area to gzipped file 213275793eaSopenharmony_cigzfilebuf::int_type 214275793eaSopenharmony_cigzfilebuf::overflow(int_type c) 215275793eaSopenharmony_ci{ 216275793eaSopenharmony_ci // Determine whether put area is in use 217275793eaSopenharmony_ci if (this->pbase()) 218275793eaSopenharmony_ci { 219275793eaSopenharmony_ci // Double-check pointer range 220275793eaSopenharmony_ci if (this->pptr() > this->epptr() || this->pptr() < this->pbase()) 221275793eaSopenharmony_ci return traits_type::eof(); 222275793eaSopenharmony_ci // Add extra character to buffer if not EOF 223275793eaSopenharmony_ci if (!traits_type::eq_int_type(c, traits_type::eof())) 224275793eaSopenharmony_ci { 225275793eaSopenharmony_ci *(this->pptr()) = traits_type::to_char_type(c); 226275793eaSopenharmony_ci this->pbump(1); 227275793eaSopenharmony_ci } 228275793eaSopenharmony_ci // Number of characters to write to file 229275793eaSopenharmony_ci int bytes_to_write = this->pptr() - this->pbase(); 230275793eaSopenharmony_ci // Overflow doesn't fail if nothing is to be written 231275793eaSopenharmony_ci if (bytes_to_write > 0) 232275793eaSopenharmony_ci { 233275793eaSopenharmony_ci // If the file hasn't been opened for writing, produce error 234275793eaSopenharmony_ci if (!this->is_open() || !(io_mode & std::ios_base::out)) 235275793eaSopenharmony_ci return traits_type::eof(); 236275793eaSopenharmony_ci // If gzipped file won't accept all bytes written to it, fail 237275793eaSopenharmony_ci if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write) 238275793eaSopenharmony_ci return traits_type::eof(); 239275793eaSopenharmony_ci // Reset next pointer to point to pbase on success 240275793eaSopenharmony_ci this->pbump(-bytes_to_write); 241275793eaSopenharmony_ci } 242275793eaSopenharmony_ci } 243275793eaSopenharmony_ci // Write extra character to file if not EOF 244275793eaSopenharmony_ci else if (!traits_type::eq_int_type(c, traits_type::eof())) 245275793eaSopenharmony_ci { 246275793eaSopenharmony_ci // If the file hasn't been opened for writing, produce error 247275793eaSopenharmony_ci if (!this->is_open() || !(io_mode & std::ios_base::out)) 248275793eaSopenharmony_ci return traits_type::eof(); 249275793eaSopenharmony_ci // Impromptu char buffer (allows "unbuffered" output) 250275793eaSopenharmony_ci char_type last_char = traits_type::to_char_type(c); 251275793eaSopenharmony_ci // If gzipped file won't accept this character, fail 252275793eaSopenharmony_ci if (gzwrite(file, &last_char, 1) != 1) 253275793eaSopenharmony_ci return traits_type::eof(); 254275793eaSopenharmony_ci } 255275793eaSopenharmony_ci 256275793eaSopenharmony_ci // If you got here, you have succeeded (even if c was EOF) 257275793eaSopenharmony_ci // The return value should therefore be non-EOF 258275793eaSopenharmony_ci if (traits_type::eq_int_type(c, traits_type::eof())) 259275793eaSopenharmony_ci return traits_type::not_eof(c); 260275793eaSopenharmony_ci else 261275793eaSopenharmony_ci return c; 262275793eaSopenharmony_ci} 263275793eaSopenharmony_ci 264275793eaSopenharmony_ci// Assign new buffer 265275793eaSopenharmony_cistd::streambuf* 266275793eaSopenharmony_cigzfilebuf::setbuf(char_type* p, 267275793eaSopenharmony_ci std::streamsize n) 268275793eaSopenharmony_ci{ 269275793eaSopenharmony_ci // First make sure stuff is sync'ed, for safety 270275793eaSopenharmony_ci if (this->sync() == -1) 271275793eaSopenharmony_ci return NULL; 272275793eaSopenharmony_ci // If buffering is turned off on purpose via setbuf(0,0), still allocate one... 273275793eaSopenharmony_ci // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at 274275793eaSopenharmony_ci // least a buffer of size 1 (very inefficient though, therefore make it bigger?) 275275793eaSopenharmony_ci // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems) 276275793eaSopenharmony_ci if (!p || !n) 277275793eaSopenharmony_ci { 278275793eaSopenharmony_ci // Replace existing buffer (if any) with small internal buffer 279275793eaSopenharmony_ci this->disable_buffer(); 280275793eaSopenharmony_ci buffer = NULL; 281275793eaSopenharmony_ci buffer_size = 0; 282275793eaSopenharmony_ci own_buffer = true; 283275793eaSopenharmony_ci this->enable_buffer(); 284275793eaSopenharmony_ci } 285275793eaSopenharmony_ci else 286275793eaSopenharmony_ci { 287275793eaSopenharmony_ci // Replace existing buffer (if any) with external buffer 288275793eaSopenharmony_ci this->disable_buffer(); 289275793eaSopenharmony_ci buffer = p; 290275793eaSopenharmony_ci buffer_size = n; 291275793eaSopenharmony_ci own_buffer = false; 292275793eaSopenharmony_ci this->enable_buffer(); 293275793eaSopenharmony_ci } 294275793eaSopenharmony_ci return this; 295275793eaSopenharmony_ci} 296275793eaSopenharmony_ci 297275793eaSopenharmony_ci// Write put area to gzipped file (i.e. ensures that put area is empty) 298275793eaSopenharmony_ciint 299275793eaSopenharmony_cigzfilebuf::sync() 300275793eaSopenharmony_ci{ 301275793eaSopenharmony_ci return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0; 302275793eaSopenharmony_ci} 303275793eaSopenharmony_ci 304275793eaSopenharmony_ci/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 305275793eaSopenharmony_ci 306275793eaSopenharmony_ci// Allocate internal buffer 307275793eaSopenharmony_civoid 308275793eaSopenharmony_cigzfilebuf::enable_buffer() 309275793eaSopenharmony_ci{ 310275793eaSopenharmony_ci // If internal buffer required, allocate one 311275793eaSopenharmony_ci if (own_buffer && !buffer) 312275793eaSopenharmony_ci { 313275793eaSopenharmony_ci // Check for buffered vs. "unbuffered" 314275793eaSopenharmony_ci if (buffer_size > 0) 315275793eaSopenharmony_ci { 316275793eaSopenharmony_ci // Allocate internal buffer 317275793eaSopenharmony_ci buffer = new char_type[buffer_size]; 318275793eaSopenharmony_ci // Get area starts empty and will be expanded by underflow as need arises 319275793eaSopenharmony_ci this->setg(buffer, buffer, buffer); 320275793eaSopenharmony_ci // Setup entire internal buffer as put area. 321275793eaSopenharmony_ci // The one-past-end pointer actually points to the last element of the buffer, 322275793eaSopenharmony_ci // so that overflow(c) can safely add the extra character c to the sequence. 323275793eaSopenharmony_ci // These pointers remain in place for the duration of the buffer 324275793eaSopenharmony_ci this->setp(buffer, buffer + buffer_size - 1); 325275793eaSopenharmony_ci } 326275793eaSopenharmony_ci else 327275793eaSopenharmony_ci { 328275793eaSopenharmony_ci // Even in "unbuffered" case, (small?) get buffer is still required 329275793eaSopenharmony_ci buffer_size = SMALLBUFSIZE; 330275793eaSopenharmony_ci buffer = new char_type[buffer_size]; 331275793eaSopenharmony_ci this->setg(buffer, buffer, buffer); 332275793eaSopenharmony_ci // "Unbuffered" means no put buffer 333275793eaSopenharmony_ci this->setp(0, 0); 334275793eaSopenharmony_ci } 335275793eaSopenharmony_ci } 336275793eaSopenharmony_ci else 337275793eaSopenharmony_ci { 338275793eaSopenharmony_ci // If buffer already allocated, reset buffer pointers just to make sure no 339275793eaSopenharmony_ci // stale chars are lying around 340275793eaSopenharmony_ci this->setg(buffer, buffer, buffer); 341275793eaSopenharmony_ci this->setp(buffer, buffer + buffer_size - 1); 342275793eaSopenharmony_ci } 343275793eaSopenharmony_ci} 344275793eaSopenharmony_ci 345275793eaSopenharmony_ci// Destroy internal buffer 346275793eaSopenharmony_civoid 347275793eaSopenharmony_cigzfilebuf::disable_buffer() 348275793eaSopenharmony_ci{ 349275793eaSopenharmony_ci // If internal buffer exists, deallocate it 350275793eaSopenharmony_ci if (own_buffer && buffer) 351275793eaSopenharmony_ci { 352275793eaSopenharmony_ci // Preserve unbuffered status by zeroing size 353275793eaSopenharmony_ci if (!this->pbase()) 354275793eaSopenharmony_ci buffer_size = 0; 355275793eaSopenharmony_ci delete[] buffer; 356275793eaSopenharmony_ci buffer = NULL; 357275793eaSopenharmony_ci this->setg(0, 0, 0); 358275793eaSopenharmony_ci this->setp(0, 0); 359275793eaSopenharmony_ci } 360275793eaSopenharmony_ci else 361275793eaSopenharmony_ci { 362275793eaSopenharmony_ci // Reset buffer pointers to initial state if external buffer exists 363275793eaSopenharmony_ci this->setg(buffer, buffer, buffer); 364275793eaSopenharmony_ci if (buffer) 365275793eaSopenharmony_ci this->setp(buffer, buffer + buffer_size - 1); 366275793eaSopenharmony_ci else 367275793eaSopenharmony_ci this->setp(0, 0); 368275793eaSopenharmony_ci } 369275793eaSopenharmony_ci} 370275793eaSopenharmony_ci 371275793eaSopenharmony_ci/*****************************************************************************/ 372275793eaSopenharmony_ci 373275793eaSopenharmony_ci// Default constructor initializes stream buffer 374275793eaSopenharmony_cigzifstream::gzifstream() 375275793eaSopenharmony_ci: std::istream(NULL), sb() 376275793eaSopenharmony_ci{ this->init(&sb); } 377275793eaSopenharmony_ci 378275793eaSopenharmony_ci// Initialize stream buffer and open file 379275793eaSopenharmony_cigzifstream::gzifstream(const char* name, 380275793eaSopenharmony_ci std::ios_base::openmode mode) 381275793eaSopenharmony_ci: std::istream(NULL), sb() 382275793eaSopenharmony_ci{ 383275793eaSopenharmony_ci this->init(&sb); 384275793eaSopenharmony_ci this->open(name, mode); 385275793eaSopenharmony_ci} 386275793eaSopenharmony_ci 387275793eaSopenharmony_ci// Initialize stream buffer and attach to file 388275793eaSopenharmony_cigzifstream::gzifstream(int fd, 389275793eaSopenharmony_ci std::ios_base::openmode mode) 390275793eaSopenharmony_ci: std::istream(NULL), sb() 391275793eaSopenharmony_ci{ 392275793eaSopenharmony_ci this->init(&sb); 393275793eaSopenharmony_ci this->attach(fd, mode); 394275793eaSopenharmony_ci} 395275793eaSopenharmony_ci 396275793eaSopenharmony_ci// Open file and go into fail() state if unsuccessful 397275793eaSopenharmony_civoid 398275793eaSopenharmony_cigzifstream::open(const char* name, 399275793eaSopenharmony_ci std::ios_base::openmode mode) 400275793eaSopenharmony_ci{ 401275793eaSopenharmony_ci if (!sb.open(name, mode | std::ios_base::in)) 402275793eaSopenharmony_ci this->setstate(std::ios_base::failbit); 403275793eaSopenharmony_ci else 404275793eaSopenharmony_ci this->clear(); 405275793eaSopenharmony_ci} 406275793eaSopenharmony_ci 407275793eaSopenharmony_ci// Attach to file and go into fail() state if unsuccessful 408275793eaSopenharmony_civoid 409275793eaSopenharmony_cigzifstream::attach(int fd, 410275793eaSopenharmony_ci std::ios_base::openmode mode) 411275793eaSopenharmony_ci{ 412275793eaSopenharmony_ci if (!sb.attach(fd, mode | std::ios_base::in)) 413275793eaSopenharmony_ci this->setstate(std::ios_base::failbit); 414275793eaSopenharmony_ci else 415275793eaSopenharmony_ci this->clear(); 416275793eaSopenharmony_ci} 417275793eaSopenharmony_ci 418275793eaSopenharmony_ci// Close file 419275793eaSopenharmony_civoid 420275793eaSopenharmony_cigzifstream::close() 421275793eaSopenharmony_ci{ 422275793eaSopenharmony_ci if (!sb.close()) 423275793eaSopenharmony_ci this->setstate(std::ios_base::failbit); 424275793eaSopenharmony_ci} 425275793eaSopenharmony_ci 426275793eaSopenharmony_ci/*****************************************************************************/ 427275793eaSopenharmony_ci 428275793eaSopenharmony_ci// Default constructor initializes stream buffer 429275793eaSopenharmony_cigzofstream::gzofstream() 430275793eaSopenharmony_ci: std::ostream(NULL), sb() 431275793eaSopenharmony_ci{ this->init(&sb); } 432275793eaSopenharmony_ci 433275793eaSopenharmony_ci// Initialize stream buffer and open file 434275793eaSopenharmony_cigzofstream::gzofstream(const char* name, 435275793eaSopenharmony_ci std::ios_base::openmode mode) 436275793eaSopenharmony_ci: std::ostream(NULL), sb() 437275793eaSopenharmony_ci{ 438275793eaSopenharmony_ci this->init(&sb); 439275793eaSopenharmony_ci this->open(name, mode); 440275793eaSopenharmony_ci} 441275793eaSopenharmony_ci 442275793eaSopenharmony_ci// Initialize stream buffer and attach to file 443275793eaSopenharmony_cigzofstream::gzofstream(int fd, 444275793eaSopenharmony_ci std::ios_base::openmode mode) 445275793eaSopenharmony_ci: std::ostream(NULL), sb() 446275793eaSopenharmony_ci{ 447275793eaSopenharmony_ci this->init(&sb); 448275793eaSopenharmony_ci this->attach(fd, mode); 449275793eaSopenharmony_ci} 450275793eaSopenharmony_ci 451275793eaSopenharmony_ci// Open file and go into fail() state if unsuccessful 452275793eaSopenharmony_civoid 453275793eaSopenharmony_cigzofstream::open(const char* name, 454275793eaSopenharmony_ci std::ios_base::openmode mode) 455275793eaSopenharmony_ci{ 456275793eaSopenharmony_ci if (!sb.open(name, mode | std::ios_base::out)) 457275793eaSopenharmony_ci this->setstate(std::ios_base::failbit); 458275793eaSopenharmony_ci else 459275793eaSopenharmony_ci this->clear(); 460275793eaSopenharmony_ci} 461275793eaSopenharmony_ci 462275793eaSopenharmony_ci// Attach to file and go into fail() state if unsuccessful 463275793eaSopenharmony_civoid 464275793eaSopenharmony_cigzofstream::attach(int fd, 465275793eaSopenharmony_ci std::ios_base::openmode mode) 466275793eaSopenharmony_ci{ 467275793eaSopenharmony_ci if (!sb.attach(fd, mode | std::ios_base::out)) 468275793eaSopenharmony_ci this->setstate(std::ios_base::failbit); 469275793eaSopenharmony_ci else 470275793eaSopenharmony_ci this->clear(); 471275793eaSopenharmony_ci} 472275793eaSopenharmony_ci 473275793eaSopenharmony_ci// Close file 474275793eaSopenharmony_civoid 475275793eaSopenharmony_cigzofstream::close() 476275793eaSopenharmony_ci{ 477275793eaSopenharmony_ci if (!sb.close()) 478275793eaSopenharmony_ci this->setstate(std::ios_base::failbit); 479275793eaSopenharmony_ci} 480