Skip to content

Instantly share code, notes, and snippets.

@lattera
Created August 25, 2014 19:41
Show Gist options
  • Save lattera/abf488c7fd25823d6583 to your computer and use it in GitHub Desktop.
Save lattera/abf488c7fd25823d6583 to your computer and use it in GitHub Desktop.
[de/in]flate stream
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <zlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#define BUFSZ 1024
void deflate_file(char *filename)
{
int fd, ofd;
void *map;
struct stat sb;
z_stream strm;
int ret, flush;
size_t nread=0;
unsigned char outbuf[BUFSZ];
char outfile[100];
fd = open(filename, O_RDONLY);
if (fd < 0)
return;
if (fstat(fd, &sb)) {
close(fd);
return;
}
sprintf(outfile, "/tmp/inflate-XXXX");
ofd = mkstemp(outfile);
if (ofd < 0) {
fprintf(stderr, "Could not create outfile\n");
close(fd);
return;
}
map = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (map == MAP_FAILED && errno) {
perror("mmap");
close(fd);
close(ofd);
unlink(outfile);
return;
}
memset(&strm, 0x00, sizeof(z_stream));
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = sb.st_size;
strm.next_in = map;
ret = deflateInit(&strm, 9);
if (ret != Z_OK) {
fprintf(stderr, "Could not initialize zlib\n");
munmap(map, sb.st_size);
close(fd);
close(ofd);
return;
}
do {
if (strm.avail_in == 0)
break;
strm.next_in = map+(sb.st_size - strm.avail_in);
flush = (strm.avail_in == 0 ? Z_FINISH : Z_SYNC_FLUSH);
do {
strm.avail_out = BUFSZ;
strm.next_out = outbuf;
ret = deflate(&strm, flush);
if (ret == Z_STREAM_ERROR) {
fprintf(stderr, "Stream received an error. Bailing. Outfile is %s\n", outfile);
deflateEnd(&strm);
munmap(map, sb.st_size);
close(fd);
close(ofd);
return;
}
write(ofd, outbuf, BUFSZ - strm.avail_out);
} while (strm.avail_out == 0);
} while (flush != Z_FINISH);
printf("%s decoded to %s\n", filename, outfile);
deflateEnd(&strm);
munmap(map, sb.st_size);
close(fd);
close(ofd);
}
void inflate_file(char *filename)
{
int fd, ofd;
void *map;
struct stat sb;
z_stream strm;
int ret;
size_t nread=0;
unsigned char outbuf[BUFSZ];
char outfile[100];
fd = open(filename, O_RDONLY);
if (fd < 0)
return;
if (fstat(fd, &sb)) {
close(fd);
return;
}
sprintf(outfile, "/tmp/inflate-XXXX");
ofd = mkstemp(outfile);
if (ofd < 0) {
fprintf(stderr, "Could not create outfile\n");
close(fd);
return;
}
map = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (map == MAP_FAILED && errno) {
perror("mmap");
close(fd);
close(ofd);
unlink(outfile);
return;
}
memset(&strm, 0x00, sizeof(z_stream));
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = sb.st_size;
strm.next_in = map;
ret = inflateInit(&strm);
if (ret != Z_OK) {
fprintf(stderr, "Could not initialize zlib\n");
munmap(map, sb.st_size);
close(fd);
close(ofd);
return;
}
do {
if (strm.avail_in == 0)
break;
strm.next_in = map+(sb.st_size - strm.avail_in);
do {
strm.avail_out = BUFSZ;
strm.next_out = outbuf;
ret = inflate(&strm, Z_SYNC_FLUSH);
if (ret == Z_STREAM_ERROR) {
fprintf(stderr, "Stream received an error. Bailing. Outfile is %s\n", outfile);
inflateEnd(&strm);
munmap(map, sb.st_size);
close(fd);
close(ofd);
return;
}
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
fprintf(stderr, "inflate got a dict error. Outfile is %s\n", outfile);
case Z_DATA_ERROR:
fprintf(stderr, "inflate got a data error. Outfile is %s\n", outfile);
case Z_MEM_ERROR:
fprintf(stderr, "inflate got an error. Outfile is %s\n", outfile);
inflateEnd(&strm);
munmap(map, sb.st_size);
close(ofd);
return;
}
write(ofd, outbuf, BUFSZ - strm.avail_out);
} while (strm.avail_out == 0);
} while (ret != Z_STREAM_END && strm.avail_in > 0);
printf("%s decoded to %s\n", filename, outfile);
inflateEnd(&strm);
munmap(map, sb.st_size);
close(fd);
close(ofd);
}
int main(int argc, char *argv[])
{
int ch;
while ((ch = getopt(argc, argv, "d:i:")) != -1) {
switch (ch) {
case 'i':
inflate_file(optarg);
break;
case 'd':
deflate_file(optarg);
break;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment