minix/common/dist/zlib/contrib/iostream/zfstream.cpp
2025-05-30 22:49:42 -07:00

293 lines
4.8 KiB
C++

#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() {}