648db22b |
1 | /* |
2 | * Copyright (c) Yann Collet, Meta Platforms, Inc. |
3 | * All rights reserved. |
4 | * |
5 | * This source code is licensed under both the BSD-style license (found in the |
6 | * LICENSE file in the root directory of this source tree) and the GPLv2 (found |
7 | * in the COPYING file in the root directory of this source tree). |
8 | * You may select, at your option, one of the above-listed licenses. |
9 | */ |
10 | |
11 | #include <stdio.h> |
12 | #include <stdlib.h> |
13 | #include <string.h> |
14 | #include <assert.h> |
15 | |
16 | #define ZSTD_STATIC_LINKING_ONLY |
17 | #include "zstd.h" |
18 | #include "zstd_errors.h" |
19 | #include "sequence_producer.h" // simpleSequenceProducer |
20 | |
21 | #define CHECK(res) \ |
22 | do { \ |
23 | if (ZSTD_isError(res)) { \ |
24 | printf("ERROR: %s\n", ZSTD_getErrorName(res)); \ |
25 | return 1; \ |
26 | } \ |
27 | } while (0) \ |
28 | |
29 | int main(int argc, char *argv[]) { |
30 | if (argc != 2) { |
31 | printf("Usage: externalSequenceProducer <file>\n"); |
32 | return 1; |
33 | } |
34 | |
35 | ZSTD_CCtx* const zc = ZSTD_createCCtx(); |
36 | |
37 | int simpleSequenceProducerState = 0xdeadbeef; |
38 | |
39 | // Here is the crucial bit of code! |
40 | ZSTD_registerSequenceProducer( |
41 | zc, |
42 | &simpleSequenceProducerState, |
43 | simpleSequenceProducer |
44 | ); |
45 | |
46 | { |
47 | size_t const res = ZSTD_CCtx_setParameter(zc, ZSTD_c_enableSeqProducerFallback, 1); |
48 | CHECK(res); |
49 | } |
50 | |
51 | FILE *f = fopen(argv[1], "rb"); |
52 | assert(f); |
53 | { |
54 | int const ret = fseek(f, 0, SEEK_END); |
55 | assert(ret == 0); |
56 | } |
57 | size_t const srcSize = ftell(f); |
58 | { |
59 | int const ret = fseek(f, 0, SEEK_SET); |
60 | assert(ret == 0); |
61 | } |
62 | |
63 | char* const src = malloc(srcSize + 1); |
64 | assert(src); |
65 | { |
66 | size_t const ret = fread(src, srcSize, 1, f); |
67 | assert(ret == 1); |
68 | int const ret2 = fclose(f); |
69 | assert(ret2 == 0); |
70 | } |
71 | |
72 | size_t const dstSize = ZSTD_compressBound(srcSize); |
73 | char* const dst = malloc(dstSize); |
74 | assert(dst); |
75 | |
76 | size_t const cSize = ZSTD_compress2(zc, dst, dstSize, src, srcSize); |
77 | CHECK(cSize); |
78 | |
79 | char* const val = malloc(srcSize); |
80 | assert(val); |
81 | |
82 | { |
83 | size_t const res = ZSTD_decompress(val, srcSize, dst, cSize); |
84 | CHECK(res); |
85 | } |
86 | |
87 | if (memcmp(src, val, srcSize) == 0) { |
88 | printf("Compression and decompression were successful!\n"); |
89 | printf("Original size: %lu\n", srcSize); |
90 | printf("Compressed size: %lu\n", cSize); |
91 | } else { |
92 | printf("ERROR: input and validation buffers don't match!\n"); |
93 | for (size_t i = 0; i < srcSize; i++) { |
94 | if (src[i] != val[i]) { |
95 | printf("First bad index: %zu\n", i); |
96 | break; |
97 | } |
98 | } |
99 | return 1; |
100 | } |
101 | |
102 | ZSTD_freeCCtx(zc); |
103 | free(src); |
104 | free(dst); |
105 | free(val); |
106 | return 0; |
107 | } |