27 #define QUAZIO_INBUFSIZE 4096
28 #define QUAZIO_OUTBUFSIZE 4096
31 class QuaZIODevicePrivate {
34 ~QuaZIODevicePrivate();
45 int doFlush(QString &error);
48 QuaZIODevicePrivate::QuaZIODevicePrivate(
QIODevice *io):
58 zins.zalloc = (alloc_func) NULL;
59 zins.zfree = (free_func) NULL;
61 zouts.zalloc = (alloc_func) NULL;
62 zouts.zfree = (free_func) NULL;
66 #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
67 debug.setFileName(
"debug.out");
68 debug.open(QIODevice::WriteOnly);
70 #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
71 indebug.setFileName(
"debug.in");
72 indebug.open(QIODevice::WriteOnly);
76 QuaZIODevicePrivate::~QuaZIODevicePrivate()
78 #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
81 #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
90 int QuaZIODevicePrivate::doFlush(QString &error)
93 while (outBufPos < outBufSize) {
94 int more = io->write(outBuf + outBufPos, outBufSize - outBufPos);
96 error = io->errorString();
104 if (outBufPos == outBufSize) {
105 outBufPos = outBufSize = 0;
114 #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
118 #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
120 static QFile indebug;
125 d(new QuaZIODevicePrivate(io))
127 connect(io, SIGNAL(readyRead()), SIGNAL(readyRead()));
144 if ((mode & QIODevice::Append) != 0) {
145 setErrorString(trUtf8(
"QIODevice::Append is not supported for"
149 if ((mode & QIODevice::ReadWrite) == QIODevice::ReadWrite) {
150 setErrorString(trUtf8(
"QIODevice::ReadWrite is not supported for"
154 if ((mode & QIODevice::ReadOnly) != 0) {
155 if (inflateInit(&
d->zins) != Z_OK) {
156 setErrorString(
d->zins.msg);
160 if ((mode & QIODevice::WriteOnly) != 0) {
161 if (deflateInit(&
d->zouts, Z_DEFAULT_COMPRESSION) != Z_OK) {
162 setErrorString(
d->zouts.msg);
166 return QIODevice::open(mode);
171 if ((openMode() & QIODevice::ReadOnly) != 0) {
172 if (inflateEnd(&
d->zins) != Z_OK) {
173 setErrorString(
d->zins.msg);
176 if ((openMode() & QIODevice::WriteOnly) != 0) {
178 if (deflateEnd(&
d->zouts) != Z_OK) {
179 setErrorString(
d->zouts.msg);
188 while (read < maxSize) {
189 if (
d->inBufPos ==
d->inBufSize) {
192 if (
d->inBufSize == -1) {
194 setErrorString(
d->io->errorString());
197 if (
d->inBufSize == 0)
200 while (read < maxSize && d->inBufPos < d->inBufSize) {
201 d->zins.next_in = (Bytef *) (
d->inBuf +
d->inBufPos);
202 d->zins.avail_in =
d->inBufSize -
d->inBufPos;
203 d->zins.next_out = (Bytef *) (data + read);
204 d->zins.avail_out = (uInt) (maxSize - read);
206 switch (inflate(&
d->zins, Z_SYNC_FLUSH)) {
208 read = (
char *)
d->zins.next_out - data;
209 d->inBufPos = (
char *)
d->zins.next_in -
d->inBuf;
212 read = (
char *)
d->zins.next_out - data;
213 d->inBufPos = (
char *)
d->zins.next_in -
d->inBuf;
217 qWarning(
"Z_BUF_ERROR detected with %d/%d in/out, weird",
218 d->zins.avail_in,
d->zins.avail_out);
221 memmove(
d->inBuf,
d->inBuf +
d->inBufPos,
d->inBufSize -
d->inBufPos);
222 d->inBufSize -=
d->inBufPos;
226 setErrorString(
d->io->errorString());
231 d->inBufSize += more;
234 setErrorString(QString::fromLocal8Bit(
d->zins.msg));
239 #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
240 indebug.write(data, read);
249 if (
d->doFlush(error) == -1) {
250 setErrorString(error);
253 while (written < maxSize) {
255 if (
d->outBufPos <
d->outBufSize)
257 d->zouts.next_in = (Bytef *) (data + written);
258 d->zouts.avail_in = (uInt) (maxSize - written);
259 d->zouts.next_out = (Bytef *)
d->outBuf;
261 switch (deflate(&
d->zouts, Z_NO_FLUSH)) {
263 written = (
char *)
d->zouts.next_in - data;
264 d->outBufSize = (
char *)
d->zouts.next_out -
d->outBuf;
267 setErrorString(QString::fromLocal8Bit(
d->zouts.msg));
270 if (
d->doFlush(error) == -1) {
271 setErrorString(error);
275 #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
276 debug.write(data, written);
284 if (
d->doFlush(error) < 0) {
285 setErrorString(error);
289 if (
d->outBufPos <
d->outBufSize)
292 d->zouts.next_in = &c;
293 d->zouts.avail_in = 0;
295 d->zouts.next_out = (Bytef *)
d->outBuf;
297 switch (deflate(&
d->zouts, Z_SYNC_FLUSH)) {
299 d->outBufSize = (
char *)
d->zouts.next_out -
d->outBuf;
300 if (
d->doFlush(error) < 0) {
301 setErrorString(error);
304 if (
d->outBufPos <
d->outBufSize)
310 setErrorString(QString::fromLocal8Bit(
d->zouts.msg));
313 }
while (
d->zouts.avail_out == 0);
QuaZIODevice(QIODevice *io, QObject *parent=NULL)
Constructor.
virtual qint64 readData(char *data, qint64 maxSize)
Implementation of QIODevice::readData().
virtual bool flush()
Flushes data waiting to be written.
QIODevice * getIoDevice() const
Returns the underlying device.
virtual void close()
Closes this device, but not the underlying one.
#define QUAZIO_OUTBUFSIZE
~QuaZIODevice()
Destructor.
virtual bool isSequential() const
Returns true.
A class to compress/decompress QIODevice.
virtual bool open(QIODevice::OpenMode mode)
Opens the device.
virtual qint64 writeData(const char *data, qint64 maxSize)
Implementation of QIODevice::writeData().