tags:

views:

519

answers:

1

Hello, 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 peyload, 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

A: 

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.

David Walthall
I didn't forgot, it's only typo here on forum and I apped it after new size calculation.Wouldn't that mean, when I strip header/trailer zlib should uncompress DEFLATE stream? Because even when you point me to write my own thing, at some point I will need to uncompress that DEFLATE stream data either with zlib or quncompress. BTW. I tried to strip data and only send DEFLATE stream, also error. I forced web to gave me answer with deflate stream also error.
I did what You suggested and It was easier then I thought It would be.Thanx.