7#include "kgzipfilter.h"
8#include "loggingcategory.h"
21static_assert(Z_NULL == 0,
"zlib API has changed. We no longer can use nullptr or zero instead of Z_NULL.");
27 : headerWritten(false)
28 , footerWritten(false)
32 , isInitialized(false)
34 zStream.zalloc =
static_cast<alloc_func
>(
nullptr);
35 zStream.zfree =
static_cast<free_func
>(
nullptr);
36 zStream.opaque =
static_cast<voidpf
>(
nullptr);
48KGzipFilter::KGzipFilter()
53KGzipFilter::~KGzipFilter()
60 switch (filterFlags()) {
73 if (d->isInitialized) {
76 d->zStream.next_in =
nullptr;
77 d->zStream.avail_in = 0;
79 const int windowBits = (flag == RawDeflate) ? -MAX_WBITS
80 : (flag == GZipHeader) ? MAX_WBITS + 32
82 const int result = inflateInit2(&d->zStream, windowBits);
88 int result = deflateInit2(&d->zStream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
99 d->headerWritten =
false;
100 d->footerWritten =
false;
101 d->isInitialized =
true;
113 int result = inflateEnd(&d->zStream);
114 if (result != Z_OK) {
119 int result = deflateEnd(&d->zStream);
120 if (result != Z_OK) {
125 d->isInitialized =
false;
132 int result = inflateReset(&d->zStream);
133 if (result != Z_OK) {
138 int result = deflateReset(&d->zStream);
139 if (result != Z_OK) {
143 d->headerWritten =
false;
144 d->footerWritten =
false;
154 qCDebug(KArchiveLog) <<
"avail=" << d->zStream.avail_in;
157 d->compressed =
false;
158 const Bytef *p = d->zStream.next_in;
159 int i = d->zStream.avail_in;
176 d->compressed =
true;
178 qCDebug(KArchiveLog) <<
"header OK";
184#define put_short(w) \
185 *p++ = uchar((w)&0xff); \
186 *p++ = uchar(ushort(w) >> 8);
190 put_short((n)&0xffff); \
191 put_short((ulong(n)) >> 16);
195 Bytef *p = d->zStream.next_out;
196 int i = d->zStream.avail_out;
201 put_long(time(
nullptr));
205 uint len = fileName.
length();
206 for (uint j = 0; j < len; ++j) {
210 int headerSize = p - d->zStream.next_out;
213 d->crc = crc32(0L,
nullptr, 0);
214 d->zStream.next_out = p;
215 d->zStream.avail_out = i;
216 d->headerWritten =
true;
220void KGzipFilter::writeFooter()
222 Q_ASSERT(d->headerWritten);
223 Q_ASSERT(!d->footerWritten);
224 Bytef *p = d->zStream.next_out;
225 int i = d->zStream.avail_out;
229 put_long(d->zStream.total_in);
230 i -= p - d->zStream.next_out;
231 d->zStream.next_out = p;
232 d->zStream.avail_out = i;
233 d->footerWritten =
true;
238 d->zStream.avail_out = maxlen;
239 d->zStream.next_out =
reinterpret_cast<Bytef *
>(data);
244 qCDebug(KArchiveLog) <<
"avail_in=" << size;
246 d->zStream.avail_in = size;
247 d->zStream.next_in =
reinterpret_cast<Bytef *
>(
const_cast<char *
>(data));
251 return d->zStream.avail_in;
255 return d->zStream.avail_out;
263 if (d->zStream.avail_in > 0) {
264 int n = (d->zStream.avail_in < d->zStream.avail_out) ? d->zStream.avail_in : d->zStream.avail_out;
265 memcpy(d->zStream.next_out, d->zStream.next_in, n);
266 d->zStream.avail_out -= n;
267 d->zStream.next_in += n;
268 d->zStream.avail_in -= n;
269 return KFilterBase::Ok;
271 return KFilterBase::End;
280 return KFilterBase::Error;
283 return KFilterBase::Error;
288 if (!d->compressed) {
289 return uncompress_noop();
294 qCDebug(KArchiveLog) <<
" next_in=" << d->zStream.next_in;
297 while (d->zStream.avail_in > 0) {
298 int result = inflate(&d->zStream, Z_SYNC_FLUSH);
301 qCDebug(KArchiveLog) <<
" -> inflate returned " << result;
303 qCDebug(KArchiveLog) <<
" next_in=" << d->zStream.next_in;
306 if (result == Z_OK) {
307 return KFilterBase::Ok;
311 if (result != Z_STREAM_END) {
312 return KFilterBase::Error;
316 if (d->zStream.avail_in == 0) {
317 return KFilterBase::End;
321 Bytef *data = d->zStream.next_in;
322 uInt size = d->zStream.avail_in;
325 if (!
init(d->mode)) {
326 return KFilterBase::End;
330 d->zStream.next_in = data;
331 d->zStream.avail_in = size;
334 return KFilterBase::End;
339 Q_ASSERT(d->compressed);
342 const Bytef *p = d->zStream.next_in;
343 ulong len = d->zStream.avail_in;
347 const int result = deflate(&d->zStream, finish ? Z_FINISH : Z_NO_FLUSH);
348 if (result != Z_OK && result != Z_STREAM_END) {
351 if (d->headerWritten) {
353 d->crc = crc32(d->crc, p, len - d->zStream.avail_in);
355 KGzipFilter::Result callerResult = result == Z_OK ? KFilterBase::Ok : (Z_STREAM_END ? KFilterBase::End : KFilterBase::Error);
357 if (result == Z_STREAM_END && d->headerWritten && !d->footerWritten) {
358 if (d->zStream.avail_out >= 8 ) {
364 callerResult = KFilterBase::Ok;
Internal class used by KCompressionDevice.
bool writeHeader(const QByteArray &fileName) override
void setInBuffer(const char *data, uint size) override
Result compress(bool finish) override
int inBufferAvailable() const override
void setOutBuffer(char *data, uint maxlen) override
int outBufferAvailable() const override
bool readHeader() override
int mode() const override
bool terminate() override
bool init(int mode) override
Result uncompress() override
qsizetype length() const const
QString number(double n, char format, int precision)