#include "compressioncontext.h"
#include <QByteArray>
#include <QDebug>
#include <zlib.h>
CompressionContext::CompressionContext()
{
    zlib_stream = (z_stream*) malloc(sizeof(z_stream));
    zlib_stream->next_in = NULL;
    zlib_stream->avail_in = 0;
    zlib_stream->total_in = 0;
    zlib_stream->next_out = NULL;
    zlib_stream->avail_out = 0;
    zlib_stream->total_out = 0;
    zlib_stream->msg = NULL;
    zlib_stream->state = NULL;
    zlib_stream->zalloc = Z_NULL;
    zlib_stream->zfree = Z_NULL;
    zlib_stream->opaque = Z_NULL;
    zlib_stream->data_type = Z_BINARY;
    zlib_stream->adler = 0;
    zlib_stream->reserved = 0;

    int result = inflateInit2(zlib_stream,MAX_WBITS);
    if (result != Z_OK)
    {
        qWarning() << QString("inflateInit failed (%1)").arg(result);
        free(zlib_stream);
    }
}

CompressionContext::~CompressionContext()
{
    int result = inflateEnd(zlib_stream);
    if (result != Z_OK)
        qWarning() << QString("inflateEnd failed (%1)").arg(result);

    free(zlib_stream);
}

QByteArray CompressionContext::inflateBytes( const QByteArray &input )
{
    zlib_stream->avail_in = input.size();
    zlib_stream->next_in = (Bytef*) input.constData();
    QByteArray output;

    int output_position = 0;
    int result = 0;
    do {
        output.resize(output_position + 1024);
        zlib_stream->avail_out = 1024;
        zlib_stream->next_out = (Bytef*) (output.data() + output_position);

        result = inflate(zlib_stream,Z_SYNC_FLUSH);
        if (result == Z_STREAM_ERROR)
        {
            qWarning() << QString("Error ('%1')").arg(zlib_stream->msg);
            return QByteArray();
        }
        output_position += 1024;
    } while (zlib_stream->avail_out == 0);

    if (zlib_stream->avail_in != 0)
    {
        qWarning() << "Unexpected state: avail_in=" << zlib_stream->avail_in << ",avail_out=" << zlib_stream->avail_out << ",result=" << result;
        return QByteArray();
    }

    output_position -= zlib_stream->avail_out;
    output.resize(output_position);

    return output;
}

