1
#include <QtCore> // for qWarning()
8
#define CHUNK_SIZE 1024
10
Compressor::Compressor(QIODevice* device, int compression) : device_(device)
12
zlib_stream_ = (z_stream*) malloc(sizeof(z_stream));
13
zlib_stream_->zalloc = Z_NULL;
14
zlib_stream_->zfree = Z_NULL;
15
zlib_stream_->opaque = Z_NULL;
16
int result = deflateInit(zlib_stream_, compression);
17
Q_ASSERT(result == Z_OK);
19
connect(device, SIGNAL(aboutToClose()), this, SLOT(flush()));
23
Compressor::~Compressor()
28
void Compressor::flush()
34
write(QByteArray(),true);
35
int result = deflateEnd(zlib_stream_);
37
qWarning(QString("compressor.c: deflateEnd failed (%1)").arg(result).toAscii());
42
int Compressor::write(const QByteArray& input)
44
return write(input,false);
47
int Compressor::write(const QByteArray& input, bool flush)
50
zlib_stream_->avail_in = input.size();
51
zlib_stream_->next_in = (Bytef*) input.data();
55
int output_position = 0;
57
output.resize(output_position + CHUNK_SIZE);
58
zlib_stream_->avail_out = CHUNK_SIZE;
59
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
60
result = deflate(zlib_stream_,(flush ? Z_FINISH : Z_NO_FLUSH));
61
if (result == Z_STREAM_ERROR) {
62
qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
65
output_position += CHUNK_SIZE;
67
while (zlib_stream_->avail_out == 0);
68
if (zlib_stream_->avail_in != 0) {
69
qWarning("Compressor: avail_in != 0");
71
output_position -= zlib_stream_->avail_out;
76
output.resize(output_position + CHUNK_SIZE);
77
zlib_stream_->avail_out = CHUNK_SIZE;
78
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
79
result = deflate(zlib_stream_,Z_SYNC_FLUSH);
80
if (result == Z_STREAM_ERROR) {
81
qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
84
output_position += CHUNK_SIZE;
86
while (zlib_stream_->avail_out == 0);
87
output_position -= zlib_stream_->avail_out;
89
output.resize(output_position);
91
// Write the compressed data
92
device_->write(output);
96
// -----------------------------------------------------------------------------
98
Decompressor::Decompressor(QIODevice* device) : device_(device)
100
zlib_stream_ = (z_stream*) malloc(sizeof(z_stream));
101
zlib_stream_->zalloc = Z_NULL;
102
zlib_stream_->zfree = Z_NULL;
103
zlib_stream_->opaque = Z_NULL;
104
int result = inflateInit(zlib_stream_);
105
Q_ASSERT(result == Z_OK);
107
connect(device, SIGNAL(aboutToClose()), this, SLOT(flush()));
111
Decompressor::~Decompressor()
116
void Decompressor::flush()
122
write(QByteArray(),true);
123
int result = inflateEnd(zlib_stream_);
125
qWarning(QString("compressor.c: inflateEnd failed (%1)").arg(result).toAscii());
130
int Decompressor::write(const QByteArray& input)
132
return write(input,false);
135
int Decompressor::write(const QByteArray& input, bool flush)
138
zlib_stream_->avail_in = input.size();
139
zlib_stream_->next_in = (Bytef*) input.data();
143
int output_position = 0;
145
output.resize(output_position + CHUNK_SIZE);
146
zlib_stream_->avail_out = CHUNK_SIZE;
147
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
148
result = inflate(zlib_stream_,(flush ? Z_FINISH : Z_NO_FLUSH));
149
if (result == Z_STREAM_ERROR) {
150
qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
153
output_position += CHUNK_SIZE;
155
while (zlib_stream_->avail_out == 0);
156
//Q_ASSERT(zlib_stream_->avail_in == 0);
157
if (zlib_stream_->avail_in != 0) {
158
qWarning() << "Decompressor: Unexpected state: avail_in=" << zlib_stream_->avail_in << ",avail_out=" << zlib_stream_->avail_out << ",result=" << result;
159
return Z_STREAM_ERROR; // FIXME: Should probably return 'result'
161
output_position -= zlib_stream_->avail_out;
166
output.resize(output_position + CHUNK_SIZE);
167
zlib_stream_->avail_out = CHUNK_SIZE;
168
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
169
result = inflate(zlib_stream_,Z_SYNC_FLUSH);
170
if (result == Z_STREAM_ERROR) {
171
qWarning(QString("compressor.cpp: Error ('%1')").arg(zlib_stream_->msg).toAscii());
174
output_position += CHUNK_SIZE;
176
while (zlib_stream_->avail_out == 0);
177
output_position -= zlib_stream_->avail_out;
179
output.resize(output_position);
181
// Write the compressed data
182
device_->write(output);