]>
git.proxmox.com Git - ceph.git/blob - ceph/src/zstd/examples/multiple_streaming_compression.c
e395aefbc65d997c282a0c30a0bdb15fa9ecb338
2 * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
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.
12 /* The objective of this example is to show of to compress multiple successive files
13 * while preserving memory management.
14 * All structures and buffers will be created only once,
15 * and shared across all compression operations */
17 #include <stdlib.h> // malloc, exit
18 #include <stdio.h> // fprintf, perror, feof
19 #include <string.h> // strerror
20 #include <errno.h> // errno
21 #define ZSTD_STATIC_LINKING_ONLY // streaming API defined as "experimental" for the time being
22 #include <zstd.h> // presumes zstd library is installed
25 static void* malloc_orDie(size_t size
)
27 void* const buff
= malloc(size
);
28 if (buff
) return buff
;
34 static FILE* fopen_orDie(const char *filename
, const char *instruction
)
36 FILE* const inFile
= fopen(filename
, instruction
);
37 if (inFile
) return inFile
;
43 static size_t fread_orDie(void* buffer
, size_t sizeToRead
, FILE* file
)
45 size_t const readSize
= fread(buffer
, 1, sizeToRead
, file
);
46 if (readSize
== sizeToRead
) return readSize
; /* good */
47 if (feof(file
)) return readSize
; /* good, reached end of file */
53 static size_t fwrite_orDie(const void* buffer
, size_t sizeToWrite
, FILE* file
)
55 size_t const writtenSize
= fwrite(buffer
, 1, sizeToWrite
, file
);
56 if (writtenSize
== sizeToWrite
) return sizeToWrite
; /* good */
62 static size_t fclose_orDie(FILE* file
)
64 if (!fclose(file
)) return 0;
76 ZSTD_CStream
* cstream
;
79 static resources
createResources_orDie()
82 ress
.buffInSize
= ZSTD_CStreamInSize(); /* can always read one full block */
83 ress
.buffOutSize
= ZSTD_CStreamOutSize(); /* can always flush a full block */
84 ress
.buffIn
= malloc_orDie(ress
.buffInSize
);
85 ress
.buffOut
= malloc_orDie(ress
.buffOutSize
);
86 ress
.cstream
= ZSTD_createCStream();
87 if (ress
.cstream
==NULL
) { fprintf(stderr
, "ZSTD_createCStream() error \n"); exit(10); }
91 static void freeResources(resources ress
)
93 ZSTD_freeCStream(ress
.cstream
);
99 static void compressFile_orDie(resources ress
, const char* fname
, const char* outName
, int cLevel
)
101 FILE* const fin
= fopen_orDie(fname
, "rb");
102 FILE* const fout
= fopen_orDie(outName
, "wb");
104 size_t const initResult
= ZSTD_initCStream(ress
.cstream
, cLevel
);
105 if (ZSTD_isError(initResult
)) { fprintf(stderr
, "ZSTD_initCStream() error : %s \n", ZSTD_getErrorName(initResult
)); exit(11); }
107 size_t read
, toRead
= ress
.buffInSize
;
108 while( (read
= fread_orDie(ress
.buffIn
, toRead
, fin
)) ) {
109 ZSTD_inBuffer input
= { ress
.buffIn
, read
, 0 };
110 while (input
.pos
< input
.size
) {
111 ZSTD_outBuffer output
= { ress
.buffOut
, ress
.buffOutSize
, 0 };
112 toRead
= ZSTD_compressStream(ress
.cstream
, &output
, &input
); /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */
113 if (ZSTD_isError(toRead
)) { fprintf(stderr
, "ZSTD_compressStream() error : %s \n", ZSTD_getErrorName(toRead
)); exit(12); }
114 if (toRead
> ress
.buffInSize
) toRead
= ress
.buffInSize
; /* Safely handle when `buffInSize` is manually changed to a smaller value */
115 fwrite_orDie(ress
.buffOut
, output
.pos
, fout
);
119 ZSTD_outBuffer output
= { ress
.buffOut
, ress
.buffOutSize
, 0 };
120 size_t const remainingToFlush
= ZSTD_endStream(ress
.cstream
, &output
); /* close frame */
121 if (remainingToFlush
) { fprintf(stderr
, "not fully flushed"); exit(13); }
122 fwrite_orDie(ress
.buffOut
, output
.pos
, fout
);
129 int main(int argc
, const char** argv
)
131 const char* const exeName
= argv
[0];
134 printf("wrong arguments\n");
136 printf("%s FILE(s)\n", exeName
);
140 resources
const ress
= createResources_orDie();
141 void* ofnBuffer
= NULL
;
145 for (argNb
= 1; argNb
< argc
; argNb
++) {
146 const char* const ifn
= argv
[argNb
];
147 size_t const ifnSize
= strlen(ifn
);
148 size_t const ofnSize
= ifnSize
+ 5;
149 if (ofnbSize
<= ofnSize
) {
150 ofnbSize
= ofnSize
+ 16;
152 ofnBuffer
= malloc_orDie(ofnbSize
);
154 memset(ofnBuffer
, 0, ofnSize
);
155 strcat(ofnBuffer
, ifn
);
156 strcat(ofnBuffer
, ".zst");
157 compressFile_orDie(ress
, ifn
, ofnBuffer
, 7);
162 printf("compressed %i files \n", argc
-1);