Decompressing a gzip stream with zlib
Decompressing a gzip stream with zlib
Contents
Introduction
Download
Source
Related Links
Introduction
This C ++ program reads a file named input.txt.gz into memory, then uses the zlib library to decompress and print the data. after uncompression, the lyrics to Rick Astley's never gonna give you up will be printed.
Some things to note:
The input.txt.gz file was generated using 7-zip by compressing input.txt (this file is also encoded in the download ).
The zipped file supplied contains a code: blocks project file and was written and tested under Windows using mingw only.
The necessary zlib files are encoded. They were obtained from the official zlib website. zdll. Lib was renamed to libzdll. A in order to make it work with mingw.
Download
You may download the source code and code: blocks project files here.
Download Source
Source
Here is the source code listing for the program.
View plaincopy to clipboardprint?
/*
This C ++ program uses zlib to read then decompress a gzipped file in memory.
Author: Andrew Lim Chong Liang
Http://windrealm.org
*/
# Include <cstdio>
# Include <string>
# Include <cstring>
# Include <cstdlib>
# Include "zlib. H"
# Include "zconf. H"
Using namespace STD;
Bool gzipinflate (const STD: string & compressedbytes, STD: string & uncompressedbytes ){
If (compressedbytes. Size () = 0 ){
Uncompressedbytes = compressedbytes;
Return true;
}
Uncompressedbytes. Clear ();
Unsigned full_length = compressedbytes. Size ();
Unsigned half_length = compressedbytes. Size ()/2;
Unsigned uncomplength = full_length;
Char * uncomp = (char *) calloc (sizeof (char), uncomplength );
Z_stream STRM;
STRM. next_in = (bytef *) compressedbytes. c_str ();
STRM. avail_in = compressedbytes. Size ();
STRM. total_out = 0;
STRM. zarloc = z_null;
STRM. zfree = z_null;
Bool done = false;
If (inflateinit2 (& STRM, (16 + max_wbits ))! = Z_ OK ){
Free (uncomp );
Return false;
}
While (! Done ){
// If our output buffer is too small
If (STRM. total_out> = uncomplength ){
// Increase size of output buffer
Char * uncomp2 = (char *) calloc (sizeof (char), uncomplength + half_length );
Memcpy (uncomp2, uncomp, uncomplength );
Uncomplength + = half_length;
Free (uncomp );
Uncomp = uncomp2;
}
STRM. next_out = (bytef *) (uncomp + STRM. total_out );
STRM. avail_out = uncomplength-STRM. total_out;
// Inflate another chunk.
Int err = inflate (& STRM, z_sync_flush );
If (ERR = z_stream_end) done = true;
Else if (Err! = Z_ OK ){
Break;
}
}
If (inflateend (& STRM )! = Z_ OK ){
Free (uncomp );
Return false;
}
For (size_t I = 0; I <STRM. total_out; ++ I ){
Uncompressedbytes + = uncomp [I];
}
Free (uncomp );
Return true;
}
/* Reads a file into memory .*/
Bool loadbinaryfile (const STD: string & filename, STD: string & contents ){
// Open the GZIP file in binary mode
File * f = fopen (filename. c_str (), "rb ");
If (F = NULL)
Return false;
// Clear existing bytes in output vector
Contents. Clear ();
// Read all the bytes in the file
Int c = fgetc (f );
While (C! = EOF ){
Contents ++ = (char) C;
C = fgetc (f );
}
Fclose (f );
Return true;
}
Int main (){
// Read the GZIP file data into memory
STD: String filedata;
If (! Loadbinaryfile ("input.txt.gz", filedata )){
Printf ("error loading input file .");
Return 0;
}
// Uncompress the file data
STD: String data;
If (! Gzipinflate (filedata, data )){
Printf ("error decompressing file .");
Return 0;
}
// Print the data
Printf ("data :\"");
For (size_t I = 0; I <data. Size (); ++ I ){
Printf ("% C", data [I]);
}
Printf ("\" \ n ");
Return 0;
}
Related Links
Deusty gzip compression/decompression-objective-C version
Stackoverflow: How can I decompress a gzip stream with zlib?