質問

My issue is that my program hangs on use of zlib's deflate() function.

I first initialize my z_stream, as follows:

int setupGzipOutputStream(z_stream zStream) {
    int zError;
    zStream.zalloc = Z_NULL;
    zStream.zfree = Z_NULL;
    zStream.opaque = Z_NULL;

    zError = deflateInit(&zStream, Z_COMPRESSION_LEVEL);

    /* error handling code to test if zError != Z_OK... */
    return EXIT_SUCCESS;
}

I attempt to write data to my z-stream with the following function:

int compressDataToGzipOutputStream(unsigned char *myData, z_stream zStream, Boolean flushZStreamFlag) {
    int zError;
    int zOutHave;
    FILE *outFp = stdout;
    unsigned char zBuffer[Z_BUFFER_MAX_LENGTH] = {0};

    zStream.next_in = myData;
    zStream.avail_in = strlen(myData); /* myData is a null-terminated string */
    do {
        zStream.avail_out = Z_BUFFER_MAX_LENGTH;
        zStream.next_out = zBuffer;

        zError = deflate(&zStream, (flushZStreamFlag == kFalse) ? Z_NO_FLUSH : Z_FINISH);

        /* error handling code to test if zError != Z_OK... */
        zOutHave = Z_BUFFER_MAX_LENGTH - zStream.avail_out;
        fwrite(zBuffer, sizeof(unsigned char), zOutHave, outFp);
        fflush(outFp);
    } while (zStream.avail_out == 0);

    return EXIT_SUCCESS;
}

I call these two functions (with simplifications for the purpose of asking this question) as follows:

z_stream zOutStream;

setupGzipOutputStream(zOutStream);

compressDataToGzipOutputStream(data, zOutStream, kFalse); 
compressDataToGzipOutputStream(data, zOutStream, kFalse);
...
compressDataToGzipOutputStream(data, zOutStream, kTrue);

I then break down the zOutStream struct with deflateEnd().

The kTrue value on the last compression step sends the Z_FINISH flag to deflate(), instead of Z_NO_FLUSH.

It hangs on the following line:

zError = deflate(&zStream, (flushZStreamFlag == kFalse) ? Z_NO_FLUSH : Z_FINISH);

I then tried using gdb. I set a break at this line, the line where the program hangs.

At this breakpoint, I can see the values of the variables zStream, flushZStreamFlag and others. The zStream variable is not NULL, which I can verify with print zStream, print zStream.next_in, etc. which are populated with my data of interest.

If I type next in gdb, then this line of code is processed and the entire process hangs, which I verify with log statements before and after this line of code. The "before" log statement shows up, but the "after" statement does not.

My question is: Why is deflate() hanging here? Am I not initializing the output stream correctly? Not using deflate() correctly? I've been banging my head on the wall trying to solve this, but no luck. Thanks for any advice you might have.

役に立ちましたか?

解決

Your functions should take a pointer to a z_stream, rather than passing the struct in. Your init function is initialising what is effectively a local copy, which will be discarded. Then your compression function will have a garbage z_stream passed to it.

e.g:

int setupGzipOutputStream(z_stream *zStream) {
    int zError;
    zStream->zalloc = Z_NULL;
    ...
}

... etc.

It also looks like your compression function is not taking into account the null on the end of the string, so that might cause you problems when you try to re-inflate your data.

zStream.avail_in = strlen(myData);

Might want to be:

zStream.avail_in = strlen(myData) + 1;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top