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