2022-05-15 04:13:45 +00:00
|
|
|
#if 0
|
|
|
|
/*─────────────────────────────────────────────────────────────────╗
|
|
|
|
│ To the extent possible under law, Justine Tunney has waived │
|
|
|
|
│ all copyright and related or neighboring rights to this file, │
|
|
|
|
│ as it is written in the following disclaimers: │
|
|
|
|
│ • http://unlicense.org/ │
|
|
|
|
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
|
|
|
╚─────────────────────────────────────────────────────────────────*/
|
|
|
|
#endif
|
|
|
|
#include "libc/assert.h"
|
2022-09-08 09:33:01 +00:00
|
|
|
#include "libc/calls/calls.h"
|
2022-05-15 04:13:45 +00:00
|
|
|
#include "libc/errno.h"
|
2022-09-13 06:10:38 +00:00
|
|
|
#include "libc/mem/gc.internal.h"
|
2023-05-15 08:51:29 +00:00
|
|
|
#include "libc/mem/mem.h"
|
2022-05-15 04:13:45 +00:00
|
|
|
#include "libc/stdio/stdio.h"
|
2022-08-11 07:15:29 +00:00
|
|
|
#include "libc/str/str.h"
|
2022-05-15 04:13:45 +00:00
|
|
|
#include "third_party/zlib/zlib.h"
|
|
|
|
|
2022-05-19 23:57:49 +00:00
|
|
|
#define CHUNK 32768
|
2022-05-15 04:13:45 +00:00
|
|
|
|
|
|
|
int decompressor(int infd, int outfd) {
|
|
|
|
int rc;
|
|
|
|
unsigned have;
|
|
|
|
z_stream zs;
|
|
|
|
unsigned char *inbuf;
|
|
|
|
unsigned char *outbuf;
|
|
|
|
inbuf = gc(valloc(CHUNK));
|
|
|
|
outbuf = gc(valloc(CHUNK));
|
|
|
|
zs.zalloc = Z_NULL;
|
|
|
|
zs.zfree = Z_NULL;
|
|
|
|
zs.opaque = Z_NULL;
|
|
|
|
zs.avail_in = 0;
|
|
|
|
zs.next_in = Z_NULL;
|
|
|
|
rc = inflateInit(&zs);
|
|
|
|
if (rc != Z_OK) return rc;
|
|
|
|
do {
|
|
|
|
rc = read(infd, inbuf, CHUNK);
|
|
|
|
if (rc == -1) {
|
|
|
|
inflateEnd(&zs);
|
|
|
|
return Z_ERRNO;
|
|
|
|
}
|
|
|
|
if (!rc) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
zs.avail_in = rc;
|
|
|
|
zs.next_in = inbuf;
|
|
|
|
do {
|
|
|
|
zs.avail_out = CHUNK;
|
|
|
|
zs.next_out = outbuf;
|
|
|
|
rc = inflate(&zs, Z_SYNC_FLUSH);
|
|
|
|
assert(rc != Z_STREAM_ERROR);
|
|
|
|
switch (rc) {
|
|
|
|
case Z_NEED_DICT:
|
|
|
|
rc = Z_DATA_ERROR;
|
|
|
|
// fallthrough
|
|
|
|
case Z_DATA_ERROR:
|
|
|
|
case Z_MEM_ERROR:
|
|
|
|
inflateEnd(&zs);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
have = CHUNK - zs.avail_out;
|
|
|
|
if (write(outfd, outbuf, have) != have) {
|
|
|
|
inflateEnd(&zs);
|
|
|
|
return Z_ERRNO;
|
|
|
|
}
|
|
|
|
} while (!zs.avail_out);
|
|
|
|
} while (rc != Z_STREAM_END);
|
|
|
|
inflateEnd(&zs);
|
|
|
|
return rc == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *zerr(int rc) {
|
|
|
|
switch (rc) {
|
|
|
|
case Z_ERRNO:
|
|
|
|
return strerror(errno);
|
|
|
|
case Z_STREAM_ERROR:
|
|
|
|
return "invalid compression level";
|
|
|
|
case Z_DATA_ERROR:
|
|
|
|
return "invalid or incomplete deflate data";
|
|
|
|
case Z_MEM_ERROR:
|
|
|
|
return "out of memory";
|
|
|
|
case Z_VERSION_ERROR:
|
|
|
|
return "zlib version mismatch!";
|
|
|
|
default:
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-05-15 04:13:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
int rc;
|
|
|
|
rc = decompressor(0, 1);
|
|
|
|
if (rc == Z_OK) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "error: decompressor: %s\n", zerr(rc));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|