【发布时间】:2010-04-22 11:30:01
【问题描述】:
我偶然发现了一个问题,但找不到解决方案。
所以我想做的是解压缩 qt 中的数据,使用 qUncompress(QByteArray),以 gzip 格式从 www 发送。我用wireshark确定这是有效的gzip流,也用zip/rar测试过,都可以解压。
到目前为止的代码是这样的:
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;
解压失败并显示:qUncompress: Z_DATA_ERROR: Input data is corrupted.
AFAIK gzip 由 10 字节头、DEFLATE peyload、12 字节尾(8 字节 CRC32 + 4 字节 ISIZE - 未压缩数据大小)组成。 条带化标头和拖尾应该给我留下 DEFLATE 数据流,qUncompress 产生相同的错误。
我检查了用 PHP 压缩的数据字符串,如下所示:
$stringData = gzcompress( "{status:false}", 1);
和 qUncompress 解压缩该数据。(虽然我没有看到和 gzip 标头,即 ID1 = 0x1f, ID2 = 0x8b ) 我用调试检查了上面的代码,错误发生在:
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 第 610 行。
我知道 qUncompress 只是 zlib 的一个包装器,所以我想它应该可以毫无问题地处理 gzip。任何 cmets 都更受欢迎。
最好的问候
【问题讨论】:
-
qCompress("{status:false}")给出什么输出,然后该数据是否与 qUncompress 一起使用?可能会对正在发生的事情提供一些额外的提示。 -
QByteArray uncomp = qUncompress( qCompress("{status:false}") );工作正常,PHP gzcompress(...) 工作正常,来自 WWW 的 gzip 不起作用。这个 {status:false} 是由 WWW 压缩的,我将它从 wireshark 转储到数组中,所以我肯定这是有效的 gzip 流。唯一的错误是 qUncomress 说这是无效的。跟踪的调试和错误发生在 ((BITS(8) > 8)) % 31) = true 并且不应该用于有效流。
-
我编写了自己的 gzip 函数来处理 QByteArrays(使用 zlib 和 GZipHelper.h)