How to determine the compressed size from zlib for gzipped data?

I am using zlib to do gzip compression. zlib writes data directly to the open TCP socket after compression.

/* socket_fd is a file descriptor for an open TCP socket */ gzFile gzf = gzdopen(socket_fd, "wb"); int uncompressed_bytes_consumed = gzwrite(gzf, buffer, 1024); 

(of course, all error handling is removed)

Question: how do you determine how many bytes were written to the socket? All gz * functions in zlib deal with bytes / offsets in an uncompressed domain and say (look up) don't work for sockets.

The zlib.h header says: "This library can optionally read and write gzip streams to memory." Writing to the buffer will work (then I can write the buffer to the socket later), but I do not see how to do this with the interface.

+4
source share
2 answers

zlib can essentially write formatted gzip data to a buffer in memory.

This zlib faq entry sends comments to zlib.h. In the comment header file for deflateInit2 () it is mentioned that you must (optionally?) Add 16 to the 4th parameter (windowBits) to force the library to format the deflation stream using the gzip format (instead of the default "zlib" ").

This code gets the correct zlib state to encode gzip to the buffer:

 #include <zlib.h> z_stream stream; stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; int level = Z_DEFAULT_COMPRESSION; int method = Z_DEFLATED; /* mandatory */ int windowBits = 15 + 16; /* 15 is default as if deflateInit */ /* were used, add 16 to enable gzip format */ int memLevel = 8; /* default */ int strategy = Z_DEFAULT_STRATEGY; if(deflateInit2(&stream, level, method, windowBits, memLevel, strategy) != Z_OK) { fprintf(stderr, "deflateInit failed\n"); exit(EXIT_FAILURE); } /* now use the deflate function as usual to gzip compress */ /* from one buffer to another. */ 

I have confirmed that this procedure gives the same binary output as the gzopen / gzwrite / gzclose interface.

0
source

You can do this with a series of deflate* calls. I'm not going to show you everything, but this sample program (which I called "test.c" in my directory) should help you get started:

 #include <zlib.h> #include <stdlib.h> #include <stdio.h> char InputBufferA[4096]; char OutputBufferA[4096]; int main(int argc, char *argv[]) { z_stream Stream; int InputSize; FILE *FileP; Stream.zalloc = malloc; Stream.zfree = free; /* initialize compression */ deflateInit(&Stream, 3); FileP = fopen("test.c", "rb"); InputSize = fread((void *) InputBufferA, 1, sizeof(InputBufferA), FileP); fclose(FileP); Stream.next_in = InputBufferA; Stream.avail_in = InputSize; Stream.next_out = OutputBufferA; Stream.avail_out = sizeof(OutputBufferA); deflate(&Stream, Z_SYNC_FLUSH); /* OutputBufferA is now filled in with the compressed data. */ printf("%d bytes input compressed to %d bytes\n", Stream.total_in, Stream.total_out); exit(0); } 

See the deflate documentation from zlib.h

0
source