KGzipFilter::Result KGzipFilter::uncompress_()
{
#ifndef NDEBUG
    if (d->mode == 0) {
        //qWarning() << "mode==0; KGzipFilter::init was not called!";
        return KFilterBase::Error;
    } else if (d->mode == QIODevice::WriteOnly) {
        //qWarning() << "uncompress called but the filter was opened for writing!";
        return KFilterBase::Error;
    }
    Q_ASSERT(d->mode == QIODevice::ReadOnly);
#endif

    if (d->compressed) {
#ifdef DEBUG_GZIP
        qDebug() << "Calling inflate with avail_in=" << inBufferAvailable() << " avail_out=" << outBufferAvailable();
        qDebug() << "    next_in=" << d->zStream.next_in;
#endif
        int result = inflate(&d->zStream, Z_SYNC_FLUSH);
#ifdef DEBUG_GZIP
        qDebug() << " -> inflate returned " << result;
        qDebug() << " now avail_in=" << inBufferAvailable() << " avail_out=" << outBufferAvailable();
        qDebug() << "     next_in=" << d->zStream.next_in;
#else
        if (result != Z_OK && result != Z_STREAM_END) {
            //qDebug() << "Warning: inflate() returned " << result;
        }
#endif
        return (result == Z_OK ? KFilterBase::Ok : (result == Z_STREAM_END ? KFilterBase::End : KFilterBase::Error));
    } else {
        return uncompress_noop();
    }
}
KGzipFilter::Result KGzipFilter::compress_(bool finish)
{
    Q_ASSERT(d->compressed);
    Q_ASSERT(d->mode == QIODevice::WriteOnly);

    Bytef *p = d->zStream.next_in;
    ulong len = d->zStream.avail_in;
#ifdef DEBUG_GZIP
    qDebug() << "  calling deflate with avail_in=" << inBufferAvailable() << " avail_out=" << outBufferAvailable();
#endif
    const int result = deflate(&d->zStream, finish ? Z_FINISH : Z_NO_FLUSH);
    if (result != Z_OK && result != Z_STREAM_END) {
        //qDebug() << "  deflate returned " << result;
    }
    if (d->headerWritten) {
        //qDebug() << "Computing CRC for the next " << len - d->zStream.avail_in << " bytes";
        d->crc = crc32(d->crc, p, len - d->zStream.avail_in);
    }
    KGzipFilter::Result callerResult = result == Z_OK ? KFilterBase::Ok : (Z_STREAM_END ? KFilterBase::End : KFilterBase::Error);

    if (result == Z_STREAM_END && d->headerWritten && !d->footerWritten) {
        if (d->zStream.avail_out >= 8 /*footer size*/) {
            //qDebug() << "finished, write footer";
            writeFooter();
        } else {
            // No room to write the footer (#157706/#188415), we'll have to do it on the next pass.
            //qDebug() << "finished, but no room for footer yet";
            callerResult = KFilterBase::Ok;
        }
    }
    return callerResult;
}
Beispiel #3
0
KGzipFilter::Result KGzipFilter::uncompress()
{
#ifndef NDEBUG
    if (d->mode == 0) {
        //qWarning() << "mode==0; KGzipFilter::init was not called!";
        return KFilterBase::Error;
    } else if (d->mode == QIODevice::WriteOnly) {
        //qWarning() << "uncompress called but the filter was opened for writing!";
        return KFilterBase::Error;
    }
    Q_ASSERT(d->mode == QIODevice::ReadOnly);
#endif

    if (!d->compressed) {
        return uncompress_noop();
    }

#ifdef DEBUG_GZIP
    qDebug() << "Calling inflate with avail_in=" << inBufferAvailable() << " avail_out=" << outBufferAvailable();
    qDebug() << "    next_in=" << d->zStream.next_in;
#endif

    while (d->zStream.avail_in > 0) {
        int result = inflate(&d->zStream, Z_SYNC_FLUSH);

#ifdef DEBUG_GZIP
        qDebug() << " -> inflate returned " << result;
        qDebug() << " now avail_in=" << inBufferAvailable() << " avail_out=" << outBufferAvailable();
        qDebug() << "     next_in=" << d->zStream.next_in;
#endif

        if (result == Z_OK) {
            return KFilterBase::Ok;
        }

        // We can't handle any other results
        if (result != Z_STREAM_END) {
            return KFilterBase::Error;
        }

        // It really was the end
        if (d->zStream.avail_in == 0) {
            return KFilterBase::End;
        }

        // Store before resetting
        Bytef *data = d->zStream.next_in; // This is increased appropriately by zlib beforehand
        uInt size = d->zStream.avail_in;

        // Reset the stream, if that fails we assume we're at the end
        if (!init(d->mode)) {
            return KFilterBase::End;
        }

        // Reset the data to where we left off
        d->zStream.next_in = data;
        d->zStream.avail_in = size;
    }

    return KFilterBase::End;
}
bool KoFilterBase::inBufferEmpty() const
{
    return inBufferAvailable() == 0;
}