]> Sergey Matveev's repositories - tofuproxy.git/blobdiff - cmd/zstd/enzstd.c
Refactor C-code building, use pkgconf
[tofuproxy.git] / cmd / zstd / enzstd.c
diff --git a/cmd/zstd/enzstd.c b/cmd/zstd/enzstd.c
new file mode 100644 (file)
index 0000000..3655d79
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+enzstd -- .warc.zst compressor
+Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 3 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/endian.h>
+
+#include <zstd.h>
+
+int
+main(int argc, char **argv)
+{
+    ZSTD_CCtx *ctx = ZSTD_createCCtx();
+    if (ctx == NULL) {
+        fputs("can not initialize ZSTD_createCCtx\n", stderr);
+        return EXIT_FAILURE;
+    };
+    size_t zCode = ZSTD_CCtx_setParameter(ctx, ZSTD_c_checksumFlag, 1);
+    if (ZSTD_isError(zCode)) {
+        fprintf(stderr, "can not setParameter: %s\n", ZSTD_getErrorName(zCode));
+        return EXIT_FAILURE;
+    };
+    zCode = ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, ZSTD_maxCLevel());
+    if (ZSTD_isError(zCode)) {
+        fprintf(stderr, "can not setParameter: %s\n", ZSTD_getErrorName(zCode));
+        return EXIT_FAILURE;
+    };
+
+    int rc         = EXIT_FAILURE;
+    size_t srcSize = 8;
+    uint8_t *src   = malloc(srcSize);
+    if (src == NULL) {
+        fprintf(stderr, "can not allocate memory: %zu\n", srcSize);
+        goto Exit;
+    };
+    size_t dstSize     = 0;
+    uint8_t *dst       = NULL;
+    size_t srcWantSize = 0;
+    size_t dstWantSize = 0;
+    size_t n           = 0;
+    for (;;) {
+        n = fread(src, 1, 8, stdin);
+        if (n < 8) {
+            if (feof(stdin)) {
+                break;
+            };
+            perror("can not fread(stdin)");
+            goto Exit;
+        };
+        srcWantSize = (size_t)be64dec(src);
+        if (srcWantSize > srcSize) {
+            free(src);
+            srcSize = srcWantSize;
+            src     = malloc(srcSize);
+            if (src == NULL) {
+                fprintf(stderr, "can not allocate memory: %zu\n", srcSize);
+                goto Exit;
+            };
+        };
+        n = fread(src, 1, srcWantSize, stdin);
+        if (n < srcWantSize) {
+            fputs("insufficient data fed\n", stderr);
+            goto Exit;
+        };
+        dstWantSize = ZSTD_compressBound(srcWantSize);
+        if (dstWantSize > dstSize) {
+            free(dst);
+            dstSize = dstWantSize;
+            dst     = malloc(dstSize);
+            if (dst == NULL) {
+                fprintf(stderr, "can not allocate memory: %zu\n", dstSize);
+                goto Exit;
+            };
+        };
+        zCode = ZSTD_compress2(ctx, dst, dstSize, src, srcWantSize);
+        if (ZSTD_isError(zCode)) {
+            fprintf(stderr, "can not compress: %s\n", ZSTD_getErrorName(zCode));
+            goto Exit;
+        };
+        n = fwrite(dst, 1, zCode, stdout);
+        if (n < zCode) {
+            perror("can not fwrite(stdout)");
+            goto Exit;
+        };
+    };
+    rc = EXIT_SUCCESS;
+
+Exit:
+    free(dst);
+    free(src);
+    ZSTD_freeCCtx(ctx);
+    return rc;
+};