2011-04-21 21 views
2

Qtのzlibライブラリを使用して、httpサーバから受信したgzipデータを解凍しています。 qUncompressはダメだったので、私はここに与えられたアドバイスに続く:Qt quncompress gzip dataをとgzipデータを解凍するために自分自身のメソッドを作成し、このような:Qtを使用して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は、解凍されたデータは、出力バッファ(に収まる場合は正常に動作するようですすなわち16Kbより小さい)。そうでない場合、2回目のinflate呼び出しはZ_DATA_ERRORを返します。私は出力バッファが十分に大きくされている場合、データの同じチャンクが正しく解凍されるので、データが正しいことを知っています。

サーバーは、非圧縮データのサイズ(圧縮された1のサイズのみ)でヘッダーを返さないので、私はzlibの中の使用説明書に従っ:http://www.zlib.net/zlib_how.html

そして、彼らは私が正確に何をすべきかやって私は何が欠けているかもしれないか?ストリームのnext_inメンバーとavail_inメンバーは、最初の繰り返しの後で正しく更新されているようです。ああ、それが役に立つならば、データエラーが発行されたときのエラーメッセージは、 "無効な距離が遠すぎます"です。

どのような考えですか?ありがとう。

答えて

3

Deflate/Inflate圧縮/圧縮解除アルゴリズムでは、32Kbの循環バッファが使用されます。したがって、圧縮解除されたデータが16Kbより大きい場合、16Kbバッファは動作しません。 (データがブロックに分割されることが許可されているので、厳密には真ではありませんが、そこに32Kbのブロックがあると仮定する必要があります)。buffer_size = 32768と設定するだけでOKです。

+0

私は同じ問題があり、私はfolowingメソッドを使ってこれを解決しました – pranavjayadev

関連する問題