1

2048 を超えるサイズのデータ​​を圧縮解除しようとすると、zlib uncompress 呼び出しが Z_OK を返します。したがって、サイズ 2980 のデータを解凍すると、最大 2048 (2 ループ) まで解凍され、Z_OK が返されることを明確にします。私は何が欠けていますか?

Bytes は vector< unsigned char > です。

   Bytes uncompressIt( const Bytes& data )
   {
       size_t buffer_length = 1024;

       Byte* buffer = nullptr;

       int status = 0;

       do
       {
           buffer = ( Byte* ) calloc( buffer_length + 1, sizeof( Byte ) );

           int status = uncompress( buffer, &buffer_length, &data[ 0 ], data.size( ) );  

           if ( status == Z_OK )
           {
              break;
           }
           else if ( status == Z_MEM_ERROR )
           {
              throw runtime_error( "GZip decompress ran out of memory." );
           }
           else if ( status == Z_DATA_ERROR )
           {
              throw runtime_error( "GZip decompress input data was corrupted or incomplete." );
           }
           else //if ( status == Z_BUF_ERROR )
           {
              free( buffer );

              buffer_length *= 2;
           }
       } while ( status == Z_BUF_ERROR ); //then the output buffer wasn't large enough

       Bytes result;

       for( size_t index = 0; index != buffer_length; index++ )
       {
          result.push_back( buffer[ index ] );
       }

       return result;
    }

編集:

reallocをキャッチしてくれた@Michaelに感謝します。私は実装をいじっていて、それを見逃していました。それを投稿する前にまだ言い訳はありません。

4

3 に答える 3

0

あなたのコードに問題があることは明らかではありません。非圧縮データの長さを誤って予測している可能性があります。 完全な zlib ストリームを解凍し、解凍されたデータのチェック値がストリームの最後のチェック値と一致した場合にuncompress()のみ返されます。Z_OK

于 2012-07-26T03:58:23.880 に答える
0

zlib マニュアルから: 「十分なスペースがない場合、uncompress() は、その時点までの圧縮されていないデータで出力バッファーを埋めます。」

つまり、最大 1024 バイトが既に圧縮解除されている場合Z_BUF_ERROR、バッファ サイズを 2 倍にして 2048 バイトのスペースを確保し、2 回目に圧縮解除すると、合計で最大 3072 バイトの非圧縮データが得られます。

また、を取得したcalloc直後に不必要に実行しているように見えます。reallocZ_BUF_ERROR

于 2012-07-25T20:44:28.710 に答える