Я распаковываю данные gzip, полученные с http-сервера, используя библиотеку zlib из Qt. Поскольку qUncompress был бесполезен, я следовал приведенному здесь совету: Qt quncompress gzip data и создал свой собственный метод для распаковки данных gzip, например:
QByteArray gzipDecompress( QByteArray compressData )
{
//strip header
compressData.remove(0, 10);
const int buffer_size = 16384;
quint8 buffer[buffer_size];
z_stream cmpr_stream;
cmpr_stream.next_in = (unsigned char *)compressData.data();
cmpr_stream.avail_in = compressData.size();
cmpr_stream.total_in = 0;
cmpr_stream.next_out = buffer;
cmpr_stream.avail_out = buffer_size;
cmpr_stream.total_out = 0;
cmpr_stream.zalloc = Z_NULL;
cmpr_stream.zfree = Z_NULL;
cmpr_stream.opaque = Z_NULL;
int status = inflateInit2( &cmpr_stream, -8 );
if (status != Z_OK) {
qDebug() << "cmpr_stream error!";
}
QByteArray uncompressed;
do {
cmpr_stream.next_out = buffer;
cmpr_stream.avail_out = buffer_size;
status = inflate( &cmpr_stream, Z_NO_FLUSH );
if (status == Z_OK || status == Z_STREAM_END)
{
QByteArray chunk = QByteArray::fromRawData((char *)buffer, buffer_size - cmpr_stream.avail_out);
uncompressed.append( chunk );
}
else
{
inflateEnd(&cmpr_stream);
break;
}
if (status == Z_STREAM_END)
{
inflateEnd(&cmpr_stream);
break;
}
}
while (cmpr_stream.avail_out == 0);
return uncompressed;
}
Кажется, что Eveything работает нормально, если распакованные данные помещаются в выходной буфер (т. Е. Меньше 16 КБ). Если этого не произойдет, второй вызов Inflate возвращает Z_DATA_ERROR. Я точно знаю, что данные верны, потому что одна и та же порция данных правильно распаковывается, если выходной буфер сделан достаточно большим.
Сервер не возвращает заголовок с размером несжатых данных (только размер сжатых данных), поэтому я следовал инструкциям по использованию в zlib: http://www.zlib.net/zlib_how.html
И они делают именно то, что я делаю. Есть идеи, чего мне не хватать? члены next_in и util_in в потоке корректно обновляются после первой итерации. О, и если это полезно, сообщение об ошибке при выдаче ошибки данных: «неверное расстояние слишком далеко назад».
Есть мысли? Спасибо.