#include "zfstream.h" gzfilebuf::gzfilebuf() : file(NULL), mode(0), own_file_descriptor(0) {} gzfilebuf::~gzfilebuf() { sync(); if (own_file_descriptor) close(); } gzfilebuf *gzfilebuf::open(const char *name, int io_mode) { if (is_open()) return NULL; char char_mode[10]; char *p = char_mode; if (io_mode & ios::in) { mode = ios::in; *p++ = 'r'; } else if (io_mode & ios::app) { mode = ios::app; *p++ = 'a'; } else { mode = ios::out; *p++ = 'w'; } if (io_mode & ios::binary) { mode |= ios::binary; *p++ = 'b'; } // Hard code the compression level if (io_mode & (ios::out | ios::app)) { *p++ = '9'; } // Put the end-of-string indicator *p = '\0'; if ((file = gzopen(name, char_mode)) == NULL) return NULL; own_file_descriptor = 1; return this; } gzfilebuf *gzfilebuf::attach(int file_descriptor, int io_mode) { if (is_open()) return NULL; char char_mode[10]; char *p = char_mode; if (io_mode & ios::in) { mode = ios::in; *p++ = 'r'; } else if (io_mode & ios::app) { mode = ios::app; *p++ = 'a'; } else { mode = ios::out; *p++ = 'w'; } if (io_mode & ios::binary) { mode |= ios::binary; *p++ = 'b'; } // Hard code the compression level if (io_mode & (ios::out | ios::app)) { *p++ = '9'; } // Put the end-of-string indicator *p = '\0'; if ((file = gzdopen(file_descriptor, char_mode)) == NULL) return NULL; own_file_descriptor = 0; return this; } gzfilebuf *gzfilebuf::close() { if (is_open()) { sync(); gzclose(file); file = NULL; } return this; } int gzfilebuf::setcompressionlevel(int comp_level) { return gzsetparams(file, comp_level, -2); } int gzfilebuf::setcompressionstrategy(int comp_strategy) { return gzsetparams(file, -2, comp_strategy); } streampos gzfilebuf::seekoff(streamoff off, ios::seek_dir dir, int which) { return streampos(EOF); } int gzfilebuf::underflow() { // If the file hasn't been opened for reading, error. if (!is_open() || !(mode & ios::in)) return EOF; // if a buffer doesn't exists, allocate one. if (!base()) { if ((allocate()) == EOF) return EOF; setp(0, 0); } else { if (in_avail()) return (unsigned char)*gptr(); if (out_waiting()) { if (flushbuf() == EOF) return EOF; } } // Attempt to fill the buffer. int result = fillbuf(); if (result == EOF) { // disable get area setg(0, 0, 0); return EOF; } return (unsigned char)*gptr(); } int gzfilebuf::overflow(int c) { if (!is_open() || !(mode & ios::out)) return EOF; if (!base()) { if (allocate() == EOF) return EOF; setg(0, 0, 0); } else { if (in_avail()) { return EOF; } if (out_waiting()) { if (flushbuf() == EOF) return EOF; } } int bl = blen(); setp(base(), base() + bl); if (c != EOF) { *pptr() = c; pbump(1); } return 0; } int gzfilebuf::sync() { if (!is_open()) return EOF; if (out_waiting()) return flushbuf(); return 0; } int gzfilebuf::flushbuf() { int n; char *q; q = pbase(); n = pptr() - q; if (gzwrite(file, q, n) < n) return EOF; setp(0, 0); return 0; } int gzfilebuf::fillbuf() { int required; char *p; p = base(); required = blen(); int t = gzread(file, p, required); if (t <= 0) return EOF; setg(base(), base(), base() + t); return t; } gzfilestream_common::gzfilestream_common() : ios(gzfilestream_common::rdbuf()) {} gzfilestream_common::~gzfilestream_common() {} void gzfilestream_common::attach(int fd, int io_mode) { if (!buffer.attach(fd, io_mode)) clear(ios::failbit | ios::badbit); else clear(); } void gzfilestream_common::open(const char *name, int io_mode) { if (!buffer.open(name, io_mode)) clear(ios::failbit | ios::badbit); else clear(); } void gzfilestream_common::close() { if (!buffer.close()) clear(ios::failbit | ios::badbit); } gzfilebuf *gzfilestream_common::rdbuf() { return &buffer; } gzifstream::gzifstream() : ios(gzfilestream_common::rdbuf()) { clear(ios::badbit); } gzifstream::gzifstream(const char *name, int io_mode) : ios(gzfilestream_common::rdbuf()) { gzfilestream_common::open(name, io_mode); } gzifstream::gzifstream(int fd, int io_mode) : ios(gzfilestream_common::rdbuf()) { gzfilestream_common::attach(fd, io_mode); } gzifstream::~gzifstream() {} gzofstream::gzofstream() : ios(gzfilestream_common::rdbuf()) { clear(ios::badbit); } gzofstream::gzofstream(const char *name, int io_mode) : ios(gzfilestream_common::rdbuf()) { gzfilestream_common::open(name, io_mode); } gzofstream::gzofstream(int fd, int io_mode) : ios(gzfilestream_common::rdbuf()) { gzfilestream_common::attach(fd, io_mode); } gzofstream::~gzofstream() {}