From 0f52b0caadde23a4876c87c6ba053116d237fb09 Mon Sep 17 00:00:00 2001 From: Hung Dang Date: Thu, 6 Dec 2018 22:42:19 -0500 Subject: [PATCH] Refactor examples to avoid code duplication. --- examples/dictionary_compression.c | 60 +------ examples/dictionary_decompression.c | 45 +----- examples/multiple_streaming_compression.c | 50 +----- examples/simple_compression.c | 68 +------- examples/simple_decompression.c | 46 +----- examples/streaming_compression.c | 51 +----- examples/streaming_decompression.c | 48 +----- examples/utils.h | 181 ++++++++++++++++++++++ 8 files changed, 189 insertions(+), 360 deletions(-) create mode 100644 examples/utils.h diff --git a/examples/dictionary_compression.c b/examples/dictionary_compression.c index 97bf8cb5e..511b35676 100644 --- a/examples/dictionary_compression.c +++ b/examples/dictionary_compression.c @@ -7,71 +7,13 @@ * in the COPYING file in the root directory of this source tree). * You may select, at your option, one of the above-listed licenses. */ - - #include // malloc, exit #include // printf #include // strerror #include // errno #include // stat #include // presumes zstd library is installed - - -static off_t fsize_orDie(const char *filename) -{ - struct stat st; - if (stat(filename, &st) == 0) return st.st_size; - /* error */ - perror(filename); - exit(1); -} - -static FILE* fopen_orDie(const char *filename, const char *instruction) -{ - FILE* const inFile = fopen(filename, instruction); - if (inFile) return inFile; - /* error */ - perror(filename); - exit(2); -} - -static void* malloc_orDie(size_t size) -{ - void* const buff = malloc(size); - if (buff) return buff; - /* error */ - perror("malloc"); - exit(3); -} - -static void* loadFile_orDie(const char* fileName, size_t* size) -{ - off_t const buffSize = fsize_orDie(fileName); - FILE* const inFile = fopen_orDie(fileName, "rb"); - void* const buffer = malloc_orDie(buffSize); - size_t const readSize = fread(buffer, 1, buffSize, inFile); - if (readSize != (size_t)buffSize) { - fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno)); - exit(4); - } - fclose(inFile); - *size = buffSize; - return buffer; -} - -static void saveFile_orDie(const char* fileName, const void* buff, size_t buffSize) -{ - FILE* const oFile = fopen_orDie(fileName, "wb"); - size_t const wSize = fwrite(buff, 1, buffSize, oFile); - if (wSize != (size_t)buffSize) { - fprintf(stderr, "fwrite: %s : %s \n", fileName, strerror(errno)); - exit(5); - } - if (fclose(oFile)) { - perror(fileName); - exit(6); - } -} +#include "utils.h" /* createDict() : `dictFileName` is supposed to have been created using `zstd --train` */ diff --git a/examples/dictionary_decompression.c b/examples/dictionary_decompression.c index 07e6e24c6..69f56d56b 100644 --- a/examples/dictionary_decompression.c +++ b/examples/dictionary_decompression.c @@ -17,49 +17,7 @@ #include // stat #define ZSTD_STATIC_LINKING_ONLY // ZSTD_findDecompressedSize #include // presumes zstd library is installed - - -static off_t fsize_orDie(const char *filename) -{ - struct stat st; - if (stat(filename, &st) == 0) return st.st_size; - /* error */ - perror(filename); - exit(1); -} - -static FILE* fopen_orDie(const char *filename, const char *instruction) -{ - FILE* const inFile = fopen(filename, instruction); - if (inFile) return inFile; - /* error */ - perror(filename); - exit(2); -} - -static void* malloc_orDie(size_t size) -{ - void* const buff = malloc(size); - if (buff) return buff; - /* error */ - perror("malloc"); - exit(3); -} - -static void* loadFile_orDie(const char* fileName, size_t* size) -{ - off_t const buffSize = fsize_orDie(fileName); - FILE* const inFile = fopen_orDie(fileName, "rb"); - void* const buffer = malloc_orDie(buffSize); - size_t const readSize = fread(buffer, 1, buffSize, inFile); - if (readSize != (size_t)buffSize) { - fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno)); - exit(4); - } - fclose(inFile); - *size = buffSize; - return buffer; -} +#include "utils.h" /* createDict() : `dictFileName` is supposed to have been created using `zstd --train` */ @@ -74,7 +32,6 @@ static ZSTD_DDict* createDict_orDie(const char* dictFileName) return ddict; } - static void decompress(const char* fname, const ZSTD_DDict* ddict) { size_t cSize; diff --git a/examples/multiple_streaming_compression.c b/examples/multiple_streaming_compression.c index 4308a2e4d..442ff40ae 100644 --- a/examples/multiple_streaming_compression.c +++ b/examples/multiple_streaming_compression.c @@ -20,53 +20,7 @@ #include // errno #define ZSTD_STATIC_LINKING_ONLY // streaming API defined as "experimental" for the time being #include // presumes zstd library is installed - - -static void* malloc_orDie(size_t size) -{ - void* const buff = malloc(size); - if (buff) return buff; - /* error */ - perror("malloc:"); - exit(1); -} - -static FILE* fopen_orDie(const char *filename, const char *instruction) -{ - FILE* const inFile = fopen(filename, instruction); - if (inFile) return inFile; - /* error */ - perror(filename); - exit(3); -} - -static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) -{ - size_t const readSize = fread(buffer, 1, sizeToRead, file); - if (readSize == sizeToRead) return readSize; /* good */ - if (feof(file)) return readSize; /* good, reached end of file */ - /* error */ - perror("fread"); - 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; - /* error */ - perror("fclose"); - exit(6); -} - +#include "utils.h" typedef struct { void* buffIn; @@ -95,7 +49,6 @@ static void freeResources(resources ress) free(ress.buffOut); } - static void compressFile_orDie(resources ress, const char* fname, const char* outName, int cLevel) { FILE* const fin = fopen_orDie(fname, "rb"); @@ -125,7 +78,6 @@ static void compressFile_orDie(resources ress, const char* fname, const char* ou fclose_orDie(fin); } - int main(int argc, const char** argv) { const char* const exeName = argv[0]; diff --git a/examples/simple_compression.c b/examples/simple_compression.c index 9ade424a2..0193dd40f 100644 --- a/examples/simple_compression.c +++ b/examples/simple_compression.c @@ -8,78 +8,13 @@ * You may select, at your option, one of the above-listed licenses. */ - - #include // malloc, free, exit #include // fprintf, perror, fopen, etc. #include // strlen, strcat, memset, strerror #include // errno #include // stat #include // presumes zstd library is installed - - -static off_t fsize_orDie(const char *filename) -{ - struct stat st; - if (stat(filename, &st) == 0) return st.st_size; - /* error */ - perror(filename); - exit(1); -} - -static FILE* fopen_orDie(const char *filename, const char *instruction) -{ - FILE* const inFile = fopen(filename, instruction); - if (inFile) return inFile; - /* error */ - perror(filename); - exit(2); -} - -static void* malloc_orDie(size_t size) -{ - void* const buff = malloc(size); - if (buff) return buff; - /* error */ - perror(NULL); - exit(3); -} - -static void* loadFile_orDie(const char* fileName, size_t* size) -{ - off_t const fileSize = fsize_orDie(fileName); - size_t const buffSize = (size_t)fileSize; - if ((off_t)buffSize < fileSize) { /* narrowcast overflow */ - fprintf(stderr, "%s : filesize too large \n", fileName); - exit(4); - } - FILE* const inFile = fopen_orDie(fileName, "rb"); - void* const buffer = malloc_orDie(buffSize); - size_t const readSize = fread(buffer, 1, buffSize, inFile); - if (readSize != (size_t)buffSize) { - fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno)); - exit(5); - } - fclose(inFile); /* can't fail, read only */ - *size = buffSize; - return buffer; -} - - -static void saveFile_orDie(const char* fileName, const void* buff, size_t buffSize) -{ - FILE* const oFile = fopen_orDie(fileName, "wb"); - size_t const wSize = fwrite(buff, 1, buffSize, oFile); - if (wSize != (size_t)buffSize) { - fprintf(stderr, "fwrite: %s : %s \n", fileName, strerror(errno)); - exit(6); - } - if (fclose(oFile)) { - perror(fileName); - exit(7); - } -} - +#include "utils.h" static void compress_orDie(const char* fname, const char* oname) { @@ -103,7 +38,6 @@ static void compress_orDie(const char* fname, const char* oname) free(cBuff); } - static char* createOutFilename_orDie(const char* filename) { size_t const inL = strlen(filename); diff --git a/examples/simple_decompression.c b/examples/simple_decompression.c index c1818a95c..ee055dd67 100644 --- a/examples/simple_decompression.c +++ b/examples/simple_decompression.c @@ -15,50 +15,7 @@ #include // stat #define ZSTD_STATIC_LINKING_ONLY // ZSTD_findDecompressedSize #include // presumes zstd library is installed - - -static off_t fsize_orDie(const char *filename) -{ - struct stat st; - if (stat(filename, &st) == 0) return st.st_size; - /* error */ - fprintf(stderr, "stat: %s : %s \n", filename, strerror(errno)); - exit(1); -} - -static FILE* fopen_orDie(const char *filename, const char *instruction) -{ - FILE* const inFile = fopen(filename, instruction); - if (inFile) return inFile; - /* error */ - fprintf(stderr, "fopen: %s : %s \n", filename, strerror(errno)); - exit(2); -} - -static void* malloc_orDie(size_t size) -{ - void* const buff = malloc(size + !size); /* avoid allocating size of 0 : may return NULL (implementation dependent) */ - if (buff) return buff; - /* error */ - fprintf(stderr, "malloc: %s \n", strerror(errno)); - exit(3); -} - -static void* loadFile_orDie(const char* fileName, size_t* size) -{ - off_t const buffSize = fsize_orDie(fileName); - FILE* const inFile = fopen_orDie(fileName, "rb"); - void* const buffer = malloc_orDie(buffSize); - size_t const readSize = fread(buffer, 1, buffSize, inFile); - if (readSize != (size_t)buffSize) { - fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno)); - exit(4); - } - fclose(inFile); /* can't fail (read only) */ - *size = buffSize; - return buffer; -} - +#include "utils.h" static void decompress(const char* fname) { @@ -90,7 +47,6 @@ static void decompress(const char* fname) free(cBuff); } - int main(int argc, const char** argv) { const char* const exeName = argv[0]; diff --git a/examples/streaming_compression.c b/examples/streaming_compression.c index 9287ff398..e056f86f0 100644 --- a/examples/streaming_compression.c +++ b/examples/streaming_compression.c @@ -13,53 +13,7 @@ #include // fprintf, perror, feof, fopen, etc. #include // strlen, memset, strcat #include // presumes zstd library is installed - - -static void* malloc_orDie(size_t size) -{ - void* const buff = malloc(size); - if (buff) return buff; - /* error */ - perror("malloc:"); - exit(1); -} - -static FILE* fopen_orDie(const char *filename, const char *instruction) -{ - FILE* const inFile = fopen(filename, instruction); - if (inFile) return inFile; - /* error */ - perror(filename); - exit(3); -} - -static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) -{ - size_t const readSize = fread(buffer, 1, sizeToRead, file); - if (readSize == sizeToRead) return readSize; /* good */ - if (feof(file)) return readSize; /* good, reached end of file */ - /* error */ - perror("fread"); - 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; - /* error */ - perror("fclose"); - exit(6); -} - +#include "utils.h" static void compressFile_orDie(const char* fname, const char* outName, int cLevel) { @@ -102,8 +56,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve ZSTD_freeCStream(cstream); fclose_orDie(fout); - fclose_orDie(fin); - free(buffIn); + fclose_orDie(fin); free(buffIn); free(buffOut); } diff --git a/examples/streaming_decompression.c b/examples/streaming_decompression.c index 504a5e316..13c3c509e 100644 --- a/examples/streaming_decompression.c +++ b/examples/streaming_decompression.c @@ -14,53 +14,7 @@ #include // strerror #include // errno #include // presumes zstd library is installed - - -static void* malloc_orDie(size_t size) -{ - void* const buff = malloc(size); - if (buff) return buff; - /* error */ - perror("malloc:"); - exit(1); -} - -static FILE* fopen_orDie(const char *filename, const char *instruction) -{ - FILE* const inFile = fopen(filename, instruction); - if (inFile) return inFile; - /* error */ - perror(filename); - exit(3); -} - -static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) -{ - size_t const readSize = fread(buffer, 1, sizeToRead, file); - if (readSize == sizeToRead) return readSize; /* good */ - if (feof(file)) return readSize; /* good, reached end of file */ - /* error */ - perror("fread"); - 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; - /* error */ - perror("fclose"); - exit(6); -} - +#include "utils.h" static void decompressFile_orDie(const char* fname) { diff --git a/examples/utils.h b/examples/utils.h new file mode 100644 index 000000000..55a329e23 --- /dev/null +++ b/examples/utils.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* + * This header file has common utility functions used in examples. + */ +#ifndef UTILS_H +#define UTILS_H + +#include // malloc, free, exit +#include // fprintf, perror, fopen, etc. +#include // strlen, strcat, memset, strerror +#include // errno +#include // stat + +/* + * Define the returned error code from utility functions. + */ +typedef enum { + ERROR_fsize = 1, + ERROR_fopen = 2, + ERROR_fclose = 3, + ERROR_fread = 4, + ERROR_fwrite = 5, + ERROR_loadFile = 6, + ERROR_saveFile = 7, + ERROR_malloc = 8, + ERROR_largeFile = 9, +} UTILS_ErrorCode; + +/*! fsize_orDie() : + * Get the size of a given file path. + * + * @return The size of a given file path. + */ +static off_t fsize_orDie(const char *filename) +{ + struct stat st; + if (stat(filename, &st) == 0) return st.st_size; + /* error */ + perror(filename); + exit(ERROR_fsize); +} + +/*! fopen_orDie() : + * Open a file using given file path and open option. + * + * @return If successful this function will return a FILE pointer to an + * opened file otherwise it sends an error to stderr and exits. + */ +static FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(ERROR_fopen); +} + +/*! fclose_orDie() : + * Close an opened file using given FILE pointer. + */ +static void fclose_orDie(FILE* file) +{ + if (!fclose(file)) { return; }; + /* error */ + perror("fclose"); + exit(ERROR_fclose); +} + +/*! fread_orDie() : + * + * Read sizeToRead bytes from a given file, storing them at the + * location given by buffer. + * + * @return The number of bytes read. + */ +static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(ERROR_fread); +} + +/*! fwrite_orDie() : + * + * Write sizeToWrite bytes to a file pointed to by file, obtaining + * them from a location given by buffer. + * + * Note: This function will send an error to stderr and exit if it + * cannot write data to the given file pointer. + * + * @return The number of bytes written. + */ +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(ERROR_fwrite); +} + +/*! malloc_orDie() : + * Allocate memory. + * + * @return If successful this function returns a pointer to allo- + * cated memory. If there is an error, this function will send that + * error to stderr and exit. + */ +static void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc"); + exit(ERROR_malloc); +} + +/*! loadFile_orDie() : + * Read size bytes from a file. + * + * Note: This function will send an error to stderr and exit if it + * cannot read data from the given file path. + * + * @return If successful this function will return a pointer to read + * data otherwise it will printout an error to stderr and exit. + */ +static void* loadFile_orDie(const char* fileName, size_t* size) +{ + off_t const fileSize = fsize_orDie(fileName); + size_t const buffSize = (size_t)fileSize; + if ((off_t)buffSize < fileSize) { /* narrowcast overflow */ + fprintf(stderr, "%s : filesize too large \n", fileName); + exit(ERROR_largeFile); + } + FILE* const inFile = fopen_orDie(fileName, "rb"); + void* const buffer = malloc_orDie(buffSize); + size_t const readSize = fread(buffer, 1, buffSize, inFile); + if (readSize != (size_t)buffSize) { + fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno)); + exit(ERROR_fread); + } + fclose(inFile); /* can't fail, read only */ + *size = buffSize; + return buffer; +} + +/*! saveFile_orDie() : + * + * Save buffSize bytes to a given file path, obtaining them from a location pointed + * to by buff. + * + * Note: This function will send an error to stderr and exit if it + * cannot write to a given file. + */ +static void saveFile_orDie(const char* fileName, const void* buff, size_t buffSize) +{ + FILE* const oFile = fopen_orDie(fileName, "wb"); + size_t const wSize = fwrite(buff, 1, buffSize, oFile); + if (wSize != (size_t)buffSize) { + fprintf(stderr, "fwrite: %s : %s \n", fileName, strerror(errno)); + exit(ERROR_fwrite); + } + if (fclose(oFile)) { + perror(fileName); + exit(ERROR_fclose); + } +} + +#endif