1
#include <QtCore> // for qWarning()
9
#define CHUNK_SIZE 1024
11
Compressor::Compressor(QIODevice* device, int compression) : device_(device)
13
zlib_stream_ = (z_stream*) malloc(sizeof(z_stream));
14
zlib_stream_->zalloc = Z_NULL;
15
zlib_stream_->zfree = Z_NULL;
16
zlib_stream_->opaque = Z_NULL;
17
int result = deflateInit(zlib_stream_, compression);
18
Q_ASSERT(result == Z_OK);
20
connect(device, SIGNAL(aboutToClose()), this, SLOT(flush()));
24
Compressor::~Compressor()
29
void Compressor::flush()
35
write(QByteArray(),true);
36
int result = deflateEnd(zlib_stream_);
38
qWarning("compressor.c: deflateEnd failed (%d)", result);
43
int Compressor::write(const QByteArray& input)
45
return write(input,false);
48
int Compressor::write(const QByteArray& input, bool flush)
51
zlib_stream_->avail_in = input.size();
52
zlib_stream_->next_in = (Bytef*) input.data();
56
int output_position = 0;
58
output.resize(output_position + CHUNK_SIZE);
59
zlib_stream_->avail_out = CHUNK_SIZE;
60
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
61
result = deflate(zlib_stream_,(flush ? Z_FINISH : Z_NO_FLUSH));
62
if (result == Z_STREAM_ERROR) {
63
qWarning("compressor.cpp: Error ('%s')", zlib_stream_->msg);
66
output_position += CHUNK_SIZE;
68
while (zlib_stream_->avail_out == 0);
69
if (zlib_stream_->avail_in != 0) {
70
qWarning("Compressor: avail_in != 0");
72
output_position -= zlib_stream_->avail_out;
77
output.resize(output_position + CHUNK_SIZE);
78
zlib_stream_->avail_out = CHUNK_SIZE;
79
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
80
result = deflate(zlib_stream_,Z_SYNC_FLUSH);
81
if (result == Z_STREAM_ERROR) {
82
qWarning("compressor.cpp: Error ('%s')", zlib_stream_->msg);
85
output_position += CHUNK_SIZE;
87
while (zlib_stream_->avail_out == 0);
88
output_position -= zlib_stream_->avail_out;
90
output.resize(output_position);
92
// Write the compressed data
93
device_->write(output);
97
// -----------------------------------------------------------------------------
99
Decompressor::Decompressor(QIODevice* device) : device_(device)
101
zlib_stream_ = (z_stream*) malloc(sizeof(z_stream));
102
zlib_stream_->zalloc = Z_NULL;
103
zlib_stream_->zfree = Z_NULL;
104
zlib_stream_->opaque = Z_NULL;
105
int result = inflateInit(zlib_stream_);
106
Q_ASSERT(result == Z_OK);
108
connect(device, SIGNAL(aboutToClose()), this, SLOT(flush()));
112
Decompressor::~Decompressor()
117
void Decompressor::flush()
123
write(QByteArray(),true);
124
int result = inflateEnd(zlib_stream_);
126
qWarning("compressor.c: inflateEnd failed (%d)", result);
131
int Decompressor::write(const QByteArray& input)
133
return write(input,false);
136
int Decompressor::write(const QByteArray& input, bool flush)
139
zlib_stream_->avail_in = input.size();
140
zlib_stream_->next_in = (Bytef*) input.data();
144
int output_position = 0;
146
output.resize(output_position + CHUNK_SIZE);
147
zlib_stream_->avail_out = CHUNK_SIZE;
148
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
149
result = inflate(zlib_stream_,(flush ? Z_FINISH : Z_NO_FLUSH));
150
if (result == Z_STREAM_ERROR) {
151
qWarning("compressor.cpp: Error ('%s')", zlib_stream_->msg);
154
output_position += CHUNK_SIZE;
156
while (zlib_stream_->avail_out == 0);
157
//Q_ASSERT(zlib_stream_->avail_in == 0);
158
if (zlib_stream_->avail_in != 0) {
159
qWarning() << "Decompressor: Unexpected state: avail_in=" << zlib_stream_->avail_in << ",avail_out=" << zlib_stream_->avail_out << ",result=" << result;
160
return Z_STREAM_ERROR; // FIXME: Should probably return 'result'
162
output_position -= zlib_stream_->avail_out;
167
output.resize(output_position + CHUNK_SIZE);
168
zlib_stream_->avail_out = CHUNK_SIZE;
169
zlib_stream_->next_out = (Bytef*) (output.data() + output_position);
170
result = inflate(zlib_stream_,Z_SYNC_FLUSH);
171
if (result == Z_STREAM_ERROR) {
172
qWarning("compressor.cpp: Error ('%s')", zlib_stream_->msg);
175
output_position += CHUNK_SIZE;
177
while (zlib_stream_->avail_out == 0);
178
output_position -= zlib_stream_->avail_out;
180
output.resize(output_position);
182
// Write the compressed data
183
device_->write(output);