]>
git.proxmox.com Git - ceph.git/blob - ceph/src/zstd/examples/streaming_compression.c
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 #include <stdlib.h> // malloc, free, exit
13 #include <stdio.h> // fprintf, perror, feof, fopen, etc.
14 #include <string.h> // strlen, memset, strcat
15 #include <zstd.h> // presumes zstd library is installed
18 static void* malloc_orDie(size_t size
)
20 void* const buff
= malloc(size
);
21 if (buff
) return buff
;
27 static FILE* fopen_orDie(const char *filename
, const char *instruction
)
29 FILE* const inFile
= fopen(filename
, instruction
);
30 if (inFile
) return inFile
;
36 static size_t fread_orDie(void* buffer
, size_t sizeToRead
, FILE* file
)
38 size_t const readSize
= fread(buffer
, 1, sizeToRead
, file
);
39 if (readSize
== sizeToRead
) return readSize
; /* good */
40 if (feof(file
)) return readSize
; /* good, reached end of file */
46 static size_t fwrite_orDie(const void* buffer
, size_t sizeToWrite
, FILE* file
)
48 size_t const writtenSize
= fwrite(buffer
, 1, sizeToWrite
, file
);
49 if (writtenSize
== sizeToWrite
) return sizeToWrite
; /* good */
55 static size_t fclose_orDie(FILE* file
)
57 if (!fclose(file
)) return 0;
64 static void compressFile_orDie(const char* fname
, const char* outName
, int cLevel
)
66 FILE* const fin
= fopen_orDie(fname
, "rb");
67 FILE* const fout
= fopen_orDie(outName
, "wb");
68 size_t const buffInSize
= ZSTD_CStreamInSize(); /* can always read one full block */
69 void* const buffIn
= malloc_orDie(buffInSize
);
70 size_t const buffOutSize
= ZSTD_CStreamOutSize(); /* can always flush a full block */
71 void* const buffOut
= malloc_orDie(buffOutSize
);
73 ZSTD_CStream
* const cstream
= ZSTD_createCStream();
74 if (cstream
==NULL
) { fprintf(stderr
, "ZSTD_createCStream() error \n"); exit(10); }
75 size_t const initResult
= ZSTD_initCStream(cstream
, cLevel
);
76 if (ZSTD_isError(initResult
)) { fprintf(stderr
, "ZSTD_initCStream() error : %s \n", ZSTD_getErrorName(initResult
)); exit(11); }
78 size_t read
, toRead
= buffInSize
;
79 while( (read
= fread_orDie(buffIn
, toRead
, fin
)) ) {
80 ZSTD_inBuffer input
= { buffIn
, read
, 0 };
81 while (input
.pos
< input
.size
) {
82 ZSTD_outBuffer output
= { buffOut
, buffOutSize
, 0 };
83 toRead
= ZSTD_compressStream(cstream
, &output
, &input
); /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */
84 if (ZSTD_isError(toRead
)) { fprintf(stderr
, "ZSTD_compressStream() error : %s \n", ZSTD_getErrorName(toRead
)); exit(12); }
85 if (toRead
> buffInSize
) toRead
= buffInSize
; /* Safely handle case when `buffInSize` is manually changed to a value < ZSTD_CStreamInSize()*/
86 fwrite_orDie(buffOut
, output
.pos
, fout
);
90 ZSTD_outBuffer output
= { buffOut
, buffOutSize
, 0 };
91 size_t const remainingToFlush
= ZSTD_endStream(cstream
, &output
); /* close frame */
92 if (remainingToFlush
) { fprintf(stderr
, "not fully flushed"); exit(13); }
93 fwrite_orDie(buffOut
, output
.pos
, fout
);
95 ZSTD_freeCStream(cstream
);
103 static const char* createOutFilename_orDie(const char* filename
)
105 size_t const inL
= strlen(filename
);
106 size_t const outL
= inL
+ 5;
107 void* outSpace
= malloc_orDie(outL
);
108 memset(outSpace
, 0, outL
);
109 strcat(outSpace
, filename
);
110 strcat(outSpace
, ".zst");
111 return (const char*)outSpace
;
114 int main(int argc
, const char** argv
)
116 const char* const exeName
= argv
[0];
119 printf("wrong arguments\n");
121 printf("%s FILE\n", exeName
);
125 const char* const inFilename
= argv
[1];
127 const char* const outFilename
= createOutFilename_orDie(inFilename
);
128 compressFile_orDie(inFilename
, outFilename
, 1);