1
#include <QtCore> // for qWarning()
8
#define CHUNK_SIZE 1024
10
static void initZStream(z_stream* z)
23
z->data_type = Z_BINARY;
28
Compressor::Compressor(QIODevice* device, int compression) : device_(device)
30
zlib_stream_ = (z_stream*) malloc(sizeof(z_stream));
31
initZStream(zlib_stream_);
32
int result = deflateInit(zlib_stream_, compression);
33
Q_ASSERT(result == Z_OK);
35
connect(device, SIGNAL(aboutToClose()), this, SLOT(flush()));
39
Compressor::~Compressor()
45
void Compressor::flush()
51
write(QByteArray(),true);
52
int result = deflateEnd(zlib_stream_);
54
qWarning(QString("compressor.c: deflateEnd failed (%1)").arg(result).toAscii());
59
int Compressor::write(const QByteArray& input)
61
return write(input,false);
64
int Compressor::write(const QByteArray& input, bool flush)
67
zlib_stream_->avail_in = input.size();
68
zlib_stream_->next_in = (Bytef*) input.data();
72
int output_position = 0;
74
output.resize(output_position + CHUNK_SIZE);
75
zlib_stream_->avail_out = CHUNK_SIZE;
76
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
77
result = deflate(zlib_stream_,(flush ? Z_FINISH : Z_NO_FLUSH));
78
if (result == Z_STREAM_ERROR) {
79
qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
82
output_position += CHUNK_SIZE;
84
while (zlib_stream_->avail_out == 0);
85
if (zlib_stream_->avail_in != 0) {
86
qWarning("Compressor: avail_in != 0");
88
output_position -= zlib_stream_->avail_out;
93
output.resize(output_position + CHUNK_SIZE);
94
zlib_stream_->avail_out = CHUNK_SIZE;
95
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
96
result = deflate(zlib_stream_,Z_SYNC_FLUSH);
97
if (result == Z_STREAM_ERROR) {
98
qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
101
output_position += CHUNK_SIZE;
103
while (zlib_stream_->avail_out == 0);
104
output_position -= zlib_stream_->avail_out;
106
output.resize(output_position);
108
// Write the compressed data
109
device_->write(output);
113
// -----------------------------------------------------------------------------
115
Decompressor::Decompressor(QIODevice* device) : device_(device)
117
zlib_stream_ = (z_stream*) malloc(sizeof(z_stream));
118
initZStream(zlib_stream_);
119
int result = inflateInit(zlib_stream_);
120
Q_ASSERT(result == Z_OK);
122
connect(device, SIGNAL(aboutToClose()), this, SLOT(flush()));
126
Decompressor::~Decompressor()
132
void Decompressor::flush()
138
write(QByteArray(),true);
139
int result = inflateEnd(zlib_stream_);
141
qWarning(QString("compressor.c: inflateEnd failed (%1)").arg(result).toAscii());
146
int Decompressor::write(const QByteArray& input)
148
return write(input,false);
151
int Decompressor::write(const QByteArray& input, bool flush)
154
zlib_stream_->avail_in = input.size();
155
zlib_stream_->next_in = (Bytef*) input.data();
159
int output_position = 0;
161
output.resize(output_position + CHUNK_SIZE);
162
zlib_stream_->avail_out = CHUNK_SIZE;
163
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
164
result = inflate(zlib_stream_,(flush ? Z_FINISH : Z_NO_FLUSH));
165
if (result == Z_STREAM_ERROR) {
166
qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
169
output_position += CHUNK_SIZE;
171
while (zlib_stream_->avail_out == 0);
172
//Q_ASSERT(zlib_stream_->avail_in == 0);
173
if (zlib_stream_->avail_in != 0) {
174
qWarning() << "Decompressor: Unexpected state: avail_in=" << zlib_stream_->avail_in << ",avail_out=" << zlib_stream_->avail_out << ",result=" << result;
175
return Z_STREAM_ERROR; // FIXME: Should probably return 'result'
177
output_position -= zlib_stream_->avail_out;
182
output.resize(output_position + CHUNK_SIZE);
183
zlib_stream_->avail_out = CHUNK_SIZE;
184
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
185
result = inflate(zlib_stream_,Z_SYNC_FLUSH);
186
if (result == Z_STREAM_ERROR) {
187
qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
190
output_position += CHUNK_SIZE;
192
while (zlib_stream_->avail_out == 0);
193
output_position -= zlib_stream_->avail_out;
195
output.resize(output_position);
197
// Write the compressed data
198
device_->write(output);