1

当我尝试解压缩大小大于 2048 的数据时,zlib 解压缩调用返回 Z_OK。因此,为了澄清如果我解压缩大小为 2980 的数据,它将解压缩到 2048(两个循环),然后返回 Z_OK。我错过了什么?

字节是一个向量< 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;
    }

编辑:

感谢@Michael 赶上 realloc。我一直在搞砸实施并错过了它;在发布之前仍然没有任何借口。

4

3 回答 3

1

我得到了它。

int status

在循环的内部和外部定义。这里的教训是永远不要喝酒和发展。

于 2012-07-26T17:32:56.497 回答
0

来自 zlib 手册:“在没有足够空间的情况下, uncompress() 将使用未压缩的数据填充输出缓冲区直到该点。”

即,多达 1024 个字节已经被解压缩,然后您获得Z_BUF_ERROR并加倍缓冲区大小,为您提供 2048 个字节的空间,并且一旦您第二次解压缩,您总共获得了多达 3072 个字节的未压缩数据。

此外,看起来你callocrealloc得到Z_BUF_ERROR.

于 2012-07-25T20:44:28.710 回答
0

我发现您的代码没有明显的问题。您可能错误地预测了未压缩数据的长度。 仅当它已解压完整的 zlib 流并且未压缩数据的校验值与流末尾的校验值匹配uncompress()时才会返回。Z_OK

于 2012-07-26T03:58:23.880 回答