Path: blob/main/sys/contrib/zstd/examples/common.h
48249 views
/*1* Copyright (c) Yann Collet, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under both the BSD-style license (found in the5* LICENSE file in the root directory of this source tree) and the GPLv2 (found6* in the COPYING file in the root directory of this source tree).7* You may select, at your option, one of the above-listed licenses.8*/910/*11* This header file has common utility functions used in examples.12*/13#ifndef COMMON_H14#define COMMON_H1516#include <stdlib.h> // malloc, free, exit17#include <stdio.h> // fprintf, perror, fopen, etc.18#include <string.h> // strerror19#include <errno.h> // errno20#include <sys/stat.h> // stat21#include <zstd.h>2223/*24* Define the returned error code from utility functions.25*/26typedef enum {27ERROR_fsize = 1,28ERROR_fopen = 2,29ERROR_fclose = 3,30ERROR_fread = 4,31ERROR_fwrite = 5,32ERROR_loadFile = 6,33ERROR_saveFile = 7,34ERROR_malloc = 8,35ERROR_largeFile = 9,36} COMMON_ErrorCode;3738/*! CHECK39* Check that the condition holds. If it doesn't print a message and die.40*/41#define CHECK(cond, ...) \42do { \43if (!(cond)) { \44fprintf(stderr, \45"%s:%d CHECK(%s) failed: ", \46__FILE__, \47__LINE__, \48#cond); \49fprintf(stderr, "" __VA_ARGS__); \50fprintf(stderr, "\n"); \51exit(1); \52} \53} while (0)5455/*! CHECK_ZSTD56* Check the zstd error code and die if an error occurred after printing a57* message.58*/59#define CHECK_ZSTD(fn) \60do { \61size_t const err = (fn); \62CHECK(!ZSTD_isError(err), "%s", ZSTD_getErrorName(err)); \63} while (0)6465/*! fsize_orDie() :66* Get the size of a given file path.67*68* @return The size of a given file path.69*/70static size_t fsize_orDie(const char *filename)71{72struct stat st;73if (stat(filename, &st) != 0) {74/* error */75perror(filename);76exit(ERROR_fsize);77}7879off_t const fileSize = st.st_size;80size_t const size = (size_t)fileSize;81/* 1. fileSize should be non-negative,82* 2. if off_t -> size_t type conversion results in discrepancy,83* the file size is too large for type size_t.84*/85if ((fileSize < 0) || (fileSize != (off_t)size)) {86fprintf(stderr, "%s : filesize too large \n", filename);87exit(ERROR_largeFile);88}89return size;90}9192/*! fopen_orDie() :93* Open a file using given file path and open option.94*95* @return If successful this function will return a FILE pointer to an96* opened file otherwise it sends an error to stderr and exits.97*/98static FILE* fopen_orDie(const char *filename, const char *instruction)99{100FILE* const inFile = fopen(filename, instruction);101if (inFile) return inFile;102/* error */103perror(filename);104exit(ERROR_fopen);105}106107/*! fclose_orDie() :108* Close an opened file using given FILE pointer.109*/110static void fclose_orDie(FILE* file)111{112if (!fclose(file)) { return; };113/* error */114perror("fclose");115exit(ERROR_fclose);116}117118/*! fread_orDie() :119*120* Read sizeToRead bytes from a given file, storing them at the121* location given by buffer.122*123* @return The number of bytes read.124*/125static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file)126{127size_t const readSize = fread(buffer, 1, sizeToRead, file);128if (readSize == sizeToRead) return readSize; /* good */129if (feof(file)) return readSize; /* good, reached end of file */130/* error */131perror("fread");132exit(ERROR_fread);133}134135/*! fwrite_orDie() :136*137* Write sizeToWrite bytes to a file pointed to by file, obtaining138* them from a location given by buffer.139*140* Note: This function will send an error to stderr and exit if it141* cannot write data to the given file pointer.142*143* @return The number of bytes written.144*/145static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file)146{147size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file);148if (writtenSize == sizeToWrite) return sizeToWrite; /* good */149/* error */150perror("fwrite");151exit(ERROR_fwrite);152}153154/*! malloc_orDie() :155* Allocate memory.156*157* @return If successful this function returns a pointer to allo-158* cated memory. If there is an error, this function will send that159* error to stderr and exit.160*/161static void* malloc_orDie(size_t size)162{163void* const buff = malloc(size);164if (buff) return buff;165/* error */166perror("malloc");167exit(ERROR_malloc);168}169170/*! loadFile_orDie() :171* load file into buffer (memory).172*173* Note: This function will send an error to stderr and exit if it174* cannot read data from the given file path.175*176* @return If successful this function will load file into buffer and177* return file size, otherwise it will printout an error to stderr and exit.178*/179static size_t loadFile_orDie(const char* fileName, void* buffer, size_t bufferSize)180{181size_t const fileSize = fsize_orDie(fileName);182CHECK(fileSize <= bufferSize, "File too large!");183184FILE* const inFile = fopen_orDie(fileName, "rb");185size_t const readSize = fread(buffer, 1, fileSize, inFile);186if (readSize != (size_t)fileSize) {187fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno));188exit(ERROR_fread);189}190fclose(inFile); /* can't fail, read only */191return fileSize;192}193194/*! mallocAndLoadFile_orDie() :195* allocate memory buffer and then load file into it.196*197* Note: This function will send an error to stderr and exit if memory allocation198* fails or it cannot read data from the given file path.199*200* @return If successful this function will return buffer and bufferSize(=fileSize),201* otherwise it will printout an error to stderr and exit.202*/203static void* mallocAndLoadFile_orDie(const char* fileName, size_t* bufferSize) {204size_t const fileSize = fsize_orDie(fileName);205*bufferSize = fileSize;206void* const buffer = malloc_orDie(*bufferSize);207loadFile_orDie(fileName, buffer, *bufferSize);208return buffer;209}210211/*! saveFile_orDie() :212*213* Save buffSize bytes to a given file path, obtaining them from a location pointed214* to by buff.215*216* Note: This function will send an error to stderr and exit if it217* cannot write to a given file.218*/219static void saveFile_orDie(const char* fileName, const void* buff, size_t buffSize)220{221FILE* const oFile = fopen_orDie(fileName, "wb");222size_t const wSize = fwrite(buff, 1, buffSize, oFile);223if (wSize != (size_t)buffSize) {224fprintf(stderr, "fwrite: %s : %s \n", fileName, strerror(errno));225exit(ERROR_fwrite);226}227if (fclose(oFile)) {228perror(fileName);229exit(ERROR_fclose);230}231}232233#endif234235236