59 lines
1.2 KiB
C++

#include <QIODevice>
#include <zlib.h>
#include "gzip.h"
#define CHUNK 16384
QByteArray Gzip::uncompress(QIODevice *device, int limit)
{
int ret = Z_STREAM_END;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
qint64 rs;
QByteArray uba;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
if (inflateInit2(&strm, MAX_WBITS + 16) != Z_OK)
return QByteArray();
do {
rs = device->read((char*)in, CHUNK);
if (rs < 0) {
(void)inflateEnd(&strm);
return QByteArray();
} else if (rs == 0)
break;
else
strm.avail_in = (uInt)rs;
strm.next_in = in;
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
Q_ASSERT(ret != Z_STREAM_ERROR);
switch (ret) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return QByteArray();
}
uba.append((char*)out, CHUNK - strm.avail_out);
if (limit && uba.size() >= limit) {
(void)inflateEnd(&strm);
return uba;
}
} while (!strm.avail_out);
} while (ret != Z_STREAM_END);
(void)inflateEnd(&strm);
return (ret == Z_STREAM_END) ? uba : QByteArray();
}