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