zlib inflate返回缓冲区错误

时间:2015-02-02 17:30:36

标签: c++ zip gzip zlib inflate

我尝试使用zlib解压缩zip文件(不使用任何扩展程序或第三方)。 最初,src_len是48756255,dest_len是49209890。 while循环中的第一次传递很好:错误是Z_OK,第二次传递开始。在第二遍,无论我做什么,我都会从膨胀中获得Z_BUF_ERROR。此时stream.total_out是49034460,所以有一点剩余,但第二遍的stream.avail_in为0.无论如何,我希望膨胀给我Z_STREAM_END。我真的不知道发生了什么,有人可以帮忙吗?

void compression::uncompress2(char* dest, unsigned dest_len, char* src, unsigned src_len) {
    TempAllocator ta;

    z_stream_s stream = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    stream.next_in = (Bytef*)src;
    stream.avail_in = (uInt)src_len;
    stream.next_out = (Bytef*)dest;
    stream.avail_out = (uInt)dest_len;
    stream.zalloc = zalloc;
    stream.zfree = zfree;
    stream.opaque = &ta;

    // no header
    int err = inflateInit2(&stream, -MAX_WBITS);
    XENSURE(err == Z_OK);

    bool done = false;
    while (!done) {    
        stream.next_out = (Bytef*)(dest + stream.total_out);
        stream.avail_out = dest_len - stream.total_out;

        err = inflate(&stream, Z_SYNC_FLUSH);
        if (err == Z_STREAM_END)
            done = true;
        else if (err != Z_OK) {
            break;
        }
    }

    err = inflateEnd(&stream);
    XENSURE(err == Z_OK);
}

1 个答案:

答案 0 :(得分:5)

inflate()将使用可用输出处理尽可能多的输入。一旦它既不能处理输入也不能产生输出,它将返回Z_BUF_ERROR

在这种情况下,处理所有输入并且有备用输出空间,但未检测到流的末尾。您没有收到Z_STREAM_END因为某些原因您没有提供完整的deflate流。

以下是对您的代码的一些其他评论。您的循环不执行任何操作,并且在循环中设置next_outavail_out并不执行任何操作。你在循环中没有提供新的输入或新的输出空间,所以没有一个循环。围绕inflate()循环的唯一目的是提供更多输入,提供更多输出空间,或两者兼而有之。此外,当inflate()返回时,next_outavail_out将更新为输出缓冲区中的下一个可用位置以及可用空间量。您在循环中设置next_outavail_out的语句会将这些语句设置为已有的值。

code with proper loops around inflate()中,Z_BUF_ERROR不是问题,处理可以继续。虽然如果您希望下次调用inflate()时得到不同的结果,则必须提供更多输入和/或更多输出空间。

无需使用零结构初始化stream。随后的作业就是您所需要的。