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