c++qtzlib

Qt quncompress gzip data


I stumble upon a problem, and can't find a solution.

So what I want to do is uncompress data in qt, using qUncompress(QByteArray), send from www in gzip format. I used wireshark to determine that this is valid gzip stream, also tested with zip/rar and both can uncompress it.

Code so far, is like this:

    static const char dat[40] = {
         0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xaa, 0x2e, 0x2e, 0x49, 0x2c, 0x29,
         0x2d, 0xb6, 0x4a, 0x4b, 0xcc, 0x29, 0x4e, 0xad, 0x05, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00,
         0x2a, 0x63, 0x18, 0xc5, 0x0e, 0x00, 0x00, 0x00
    };
//this data contains string: {status:false}, in gzip format
QByteArray data;
           data.append( dat, sizeof(dat) );

unsigned int size = 14; //expected uncompresed size, reconstruct it BigEndianes

//prepand expected uncompressed size, last 4 byte in dat 0x0e = 14
QByteArray dataPlusSize;

dataPlusSize.append( (unsigned int)((size >> 24) & 0xFF));
dataPlusSize.append( (unsigned int)((size >> 16) & 0xFF));
dataPlusSize.append( (unsigned int)((size >> 8) & 0xFF));
dataPlusSize.append( (unsigned int)((size >> 0) & 0xFF));

QByteArray uncomp = qUncompress( dataPlusSize );
qDebug() << uncomp;

And uncompression fails with: qUncompress: Z_DATA_ERROR: Input data is corrupted.

AFAIK gzip consist of 10 byte header, DEFLATE payload, 12 byte trailer ( 8 byte CRC32 + 4 byte ISIZE - uncompresed data size ). Striping header and trailer should leave me with DEFLATE data stream, qUncompress yields same error.

I checked with data string compressed in PHP, like this:

$stringData = gzcompress( "{status:false}", 1);

and qUncompress uncompress that data.(I didn't see and gzip header though i.e. ID1 = 0x1f, ID2 = 0x8b ) I checked above code with debug, and error occurs at:

        if (
        #endif
            ((BITS(8) << 8) + (hold >> 8)) % 31) { //here is error, WHY? long unsigned int hold = 35615
            strm->msg = (char *)"incorrect header check";
            state->mode = BAD;
            break;
        } 

inflate.c line 610.

I know that qUncompress is simply a wrapper to zlib, so I suppose it should handle gzip without any problem. Any comments are more then welcome.

Best regards


Solution

  • You also forgot dataPlusSize.append(data);. However, that won't solve your problem. The problem is that while gzip and zlib have the same compressed data format, their headers and trailers are different. See: http://www.zlib.net/zlib_faq.html#faq18

    qUncompress uses the zlib uncompress, so it can only handle the zlib format, not the gzip format. It would need to call the gzXXXX functions to handle the gzip format.

    The reason that qUncompress can handle output from PHP's gzcompress is that gzcompress compresses the given string using the ZLIB data format. See: http://php.net/manual/en/function.gzcompress.php

    As CiscoIPPhone mentioned, you'll need to write your own to functions to handle gzip data.