--- /dev/null
+/*
+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;
+};