Skip to content

Instantly share code, notes, and snippets.

@jgarzik
Created February 28, 2018 05:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jgarzik/03ff509bfe102a6699c26b3ee3276fe2 to your computer and use it in GitHub Desktop.
Save jgarzik/03ff509bfe102a6699c26b3ee3276fe2 to your computer and use it in GitHub Desktop.
Decompress gzip file to stdout
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string>
#include <vector>
#include <assert.h>
#include <zlib.h>
using namespace std;
int inflateString(const std::string& dataIn, std::string& dataOut)
{
dataOut.clear();
dataOut.reserve(dataIn.size() * 4);
z_stream strm = {0};
strm.next_in = (Bytef *) dataIn.c_str();
strm.avail_in =
strm.total_in = dataIn.size();
vector<unsigned char> outBuf(4096);
strm.next_out = &outBuf[0];
strm.avail_out = outBuf.size();
strm.total_out = 0;
//15 window bits, and the +32 tells zlib to autodetect zlib/gzip
int rc = inflateInit2(&strm, (15 + 32));
while (rc == Z_OK || rc == Z_STREAM_END) {
rc = inflate(&strm, Z_NO_FLUSH);
if (rc == Z_OK || rc == Z_STREAM_END) {
size_t outputLen = outBuf.size() - strm.avail_out;
dataOut.append((char *) &outBuf[0], outputLen);
if (rc == Z_OK) {
// reset for more reads
strm.next_out = &outBuf[0];
strm.avail_out = outBuf.size();
} else {
return Z_OK;
}
}
}
return rc;
}
int main (int argc, char *argv[])
{
string zdataIn;
char buf[1024];
size_t frc;
while ((frc = fread(buf, 1, sizeof(buf), stdin)) > 0) {
zdataIn.append(&buf[0], frc);
if (frc < sizeof(buf))
break;
}
string dataOut;
int rc = inflateString(zdataIn, dataOut);
assert(rc == Z_OK);
write(STDOUT_FILENO, dataOut.c_str(), dataOut.size());
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment