]> Sergey Matveev's repositories - tofuproxy.git/blob - cmd/zstd/enzstd.c
243f6683a8b0471c516919b478798e52a30fdaa1
[tofuproxy.git] / cmd / zstd / enzstd.c
1 /*
2 enzstd -- .warc.zst compressor
3 Copyright (C) 2021-2023 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <inttypes.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include <zstd.h>
23
24 #ifdef __FreeBSD__
25 #include "capsicum.c.in"
26 #endif // __FreeBSD__
27
28 int
29 main(int argc, char **argv)
30 {
31 #ifdef __FreeBSD__
32     capsicum_start();
33 #endif // __FreeBSD__
34     ZSTD_CCtx *ctx = ZSTD_createCCtx();
35     if (ctx == NULL) {
36         fputs("can not initialize ZSTD_createCCtx\n", stderr);
37         return EXIT_FAILURE;
38     }
39     size_t zCode = ZSTD_CCtx_setParameter(ctx, ZSTD_c_checksumFlag, 1);
40     if (ZSTD_isError(zCode)) {
41         fprintf(stderr, "can not setParameter: %s\n", ZSTD_getErrorName(zCode));
42         return EXIT_FAILURE;
43     }
44     zCode = ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, ZSTD_maxCLevel());
45     if (ZSTD_isError(zCode)) {
46         fprintf(stderr, "can not setParameter: %s\n", ZSTD_getErrorName(zCode));
47         return EXIT_FAILURE;
48     }
49
50     unsigned char *src = NULL;
51     unsigned char *dst = NULL;
52     int rc = EXIT_FAILURE;
53     size_t srcSize = 8;
54     src = malloc(srcSize);
55     if (src == NULL) {
56         fprintf(stderr, "can not allocate memory: %zu\n", srcSize);
57         goto Exit;
58     }
59     size_t dstSize = 0;
60     size_t srcWantSize = 0;
61     size_t dstWantSize = 0;
62     size_t n = 0;
63     for (;;) {
64         n = fread(src, 1, 8, stdin);
65         if (n < 8) {
66             if (feof(stdin)) {
67                 break;
68             }
69             perror("can not fread(stdin)");
70             goto Exit;
71         }
72         srcWantSize = ((uint64_t)(src[0]) << 56) | ((uint64_t)(src[1]) << 48) |
73                       ((uint64_t)(src[2]) << 40) | ((uint64_t)(src[3]) << 32) |
74                       ((uint64_t)(src[4]) << 24) | ((uint64_t)(src[5]) << 16) |
75                       ((uint64_t)(src[6]) << 8) | (uint64_t)(src[7]);
76         if (srcWantSize > srcSize) {
77             free(src);
78             srcSize = srcWantSize;
79             src = malloc(srcSize);
80             if (src == NULL) {
81                 fprintf(stderr, "can not allocate memory: %zu\n", srcSize);
82                 goto Exit;
83             }
84         }
85         n = fread(src, 1, srcWantSize, stdin);
86         if (n < srcWantSize) {
87             fputs("insufficient data fed\n", stderr);
88             goto Exit;
89         }
90         dstWantSize = ZSTD_compressBound(srcWantSize);
91         if (dstWantSize > dstSize) {
92             free(dst);
93             dstSize = dstWantSize;
94             dst = malloc(dstSize);
95             if (dst == NULL) {
96                 fprintf(stderr, "can not allocate memory: %zu\n", dstSize);
97                 goto Exit;
98             }
99         }
100         zCode = ZSTD_compress2(ctx, dst, dstSize, src, srcWantSize);
101         if (ZSTD_isError(zCode)) {
102             fprintf(stderr, "can not compress: %s\n", ZSTD_getErrorName(zCode));
103             goto Exit;
104         }
105         n = fwrite(dst, 1, zCode, stdout);
106         if (n < zCode) {
107             perror("can not fwrite(stdout)");
108             goto Exit;
109         }
110     }
111     rc = EXIT_SUCCESS;
112
113 Exit:
114     free(dst);
115     free(src);
116     ZSTD_freeCCtx(ctx);
117     return rc;
118 }