diff --git a/examples/Makefile b/examples/Makefile index a9d608778..fa7328fbd 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -55,8 +55,8 @@ streaming_decompression : streaming_decompression.c clean: @rm -f core *.o tmp* result* *.zst \ simple_compression simple_decompression \ - dictionary_compression dictionary_decompression \ - streaming_compression streaming_decompression + dictionary_compression dictionary_decompression \ + streaming_compression streaming_decompression @echo Cleaning completed test: all @@ -64,7 +64,7 @@ test: all @echo starting simple compression ./simple_compression tmp ./simple_decompression tmp.zst - ./streaming_decompression tmp.zst + ./streaming_decompression tmp.zst > /dev/null @echo starting streaming compression ./streaming_compression tmp ./streaming_decompression tmp.zst diff --git a/examples/streaming_decompression.c b/examples/streaming_decompression.c index d4dfacb2d..62c780267 100644 --- a/examples/streaming_decompression.c +++ b/examples/streaming_decompression.c @@ -42,6 +42,16 @@ static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) exit(4); } +static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(5); +} + + static size_t fclose_orDie(FILE* file) { if (!fclose(file)) return 0; @@ -54,28 +64,30 @@ static size_t fclose_orDie(FILE* file) static void decompressFile_orDie(const char* fname) { FILE* const fin = fopen_orDie(fname, "rb"); - size_t const buffInSize = ZSTD_DStreamInSize();; + size_t const buffInSize = ZSTD_DStreamInSize(); void* const buffIn = malloc_orDie(buffInSize); - size_t const buffOutSize = ZSTD_DStreamOutSize();; + size_t const buffOutSize = ZSTD_DStreamOutSize(); /* Guarantee to successfully flush at least one complete compressed block in all circumstances. */ void* const buffOut = malloc_orDie(buffOutSize); - size_t read, toRead = buffInSize; + FILE* const fout = stdout; ZSTD_DStream* const dstream = ZSTD_createDStream(); if (dstream==NULL) { fprintf(stderr, "ZSTD_createDStream() error \n"); exit(10); } size_t const initResult = ZSTD_initDStream(dstream); if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_initDStream() error \n"); exit(11); } + size_t toRead = initResult; - while( (read = fread_orDie(buffIn, toRead, fin)) ) { + size_t read; + while ( (read = fread_orDie(buffIn, toRead, fin)) ) { ZSTD_inBuffer input = { buffIn, read, 0 }; while (input.pos < input.size) { ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; - toRead = ZSTD_decompressStream(dstream, &output , &input); - /* note : data is just "sinked" into buffOut - a more complete example would write it to disk or stdout */ + toRead = ZSTD_decompressStream(dstream, &output , &input); /* toRead : size of next compressed block */ + fwrite_orDie(buffOut, output.pos, fout); } } fclose_orDie(fin); + fclose_orDie(fout); free(buffIn); free(buffOut); } diff --git a/lib/zstd.h b/lib/zstd.h index e05fc2936..10312fe81 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -229,7 +229,7 @@ ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void); ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs); ZSTDLIB_API size_t ZSTD_CStreamInSize(void); /**< recommended size for input buffer */ -ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer */ +ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */ ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel); ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input); @@ -268,7 +268,7 @@ ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void); ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds); ZSTDLIB_API size_t ZSTD_DStreamInSize(void); /*!< recommended size for input buffer */ -ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer */ +ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */ ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds); ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);