Port things from MSN to WLM plugin:
[kdenetwork.git] / kopete / protocols / groupwise / libgroupwise / compress.cpp
blob41c741ea2eccb612f78a113f06322375756bc393
1 #include <QtCore> // for qWarning()
2 #include <QObject>
3 #include <QIODevice>
4 #include <zlib.h>
5 #include <stdlib.h>
7 #include "compress.h"
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);
19 Q_UNUSED(result);
20 connect(device, SIGNAL(aboutToClose()), this, SLOT(flush()));
21 flushed_ = false;
24 Compressor::~Compressor()
26 flush();
29 void Compressor::flush()
31 if (flushed_)
32 return;
34 // Flush
35 write(QByteArray(),true);
36 int result = deflateEnd(zlib_stream_);
37 if (result != Z_OK)
38 qWarning("compressor.c: deflateEnd failed (%d)", result);
40 flushed_ = true;
43 int Compressor::write(const QByteArray& input)
45 return write(input,false);
48 int Compressor::write(const QByteArray& input, bool flush)
50 int result;
51 zlib_stream_->avail_in = input.size();
52 zlib_stream_->next_in = (Bytef*) input.data();
53 QByteArray output;
55 // Write the data
56 int output_position = 0;
57 do {
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);
64 return result;
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;
74 // Flush the data
75 if (!flush) {
76 do {
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);
83 return result;
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);
94 return 0;
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);
107 Q_UNUSED(result);
108 connect(device, SIGNAL(aboutToClose()), this, SLOT(flush()));
109 flushed_ = false;
112 Decompressor::~Decompressor()
114 flush();
117 void Decompressor::flush()
119 if (flushed_)
120 return;
122 // Flush
123 write(QByteArray(),true);
124 int result = inflateEnd(zlib_stream_);
125 if (result != Z_OK)
126 qWarning("compressor.c: inflateEnd failed (%d)", result);
128 flushed_ = true;
131 int Decompressor::write(const QByteArray& input)
133 return write(input,false);
136 int Decompressor::write(const QByteArray& input, bool flush)
138 int result;
139 zlib_stream_->avail_in = input.size();
140 zlib_stream_->next_in = (Bytef*) input.data();
141 QByteArray output;
143 // Write the data
144 int output_position = 0;
145 do {
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);
152 return result;
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;
164 // Flush the data
165 if (!flush) {
166 do {
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);
173 return result;
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);
184 return 0;