Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/zstd/examples/common.h
48249 views
1
/*
2
* Copyright (c) Yann Collet, Facebook, Inc.
3
* All rights reserved.
4
*
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.
9
*/
10
11
/*
12
* This header file has common utility functions used in examples.
13
*/
14
#ifndef COMMON_H
15
#define COMMON_H
16
17
#include <stdlib.h> // malloc, free, exit
18
#include <stdio.h> // fprintf, perror, fopen, etc.
19
#include <string.h> // strerror
20
#include <errno.h> // errno
21
#include <sys/stat.h> // stat
22
#include <zstd.h>
23
24
/*
25
* Define the returned error code from utility functions.
26
*/
27
typedef enum {
28
ERROR_fsize = 1,
29
ERROR_fopen = 2,
30
ERROR_fclose = 3,
31
ERROR_fread = 4,
32
ERROR_fwrite = 5,
33
ERROR_loadFile = 6,
34
ERROR_saveFile = 7,
35
ERROR_malloc = 8,
36
ERROR_largeFile = 9,
37
} COMMON_ErrorCode;
38
39
/*! CHECK
40
* Check that the condition holds. If it doesn't print a message and die.
41
*/
42
#define CHECK(cond, ...) \
43
do { \
44
if (!(cond)) { \
45
fprintf(stderr, \
46
"%s:%d CHECK(%s) failed: ", \
47
__FILE__, \
48
__LINE__, \
49
#cond); \
50
fprintf(stderr, "" __VA_ARGS__); \
51
fprintf(stderr, "\n"); \
52
exit(1); \
53
} \
54
} while (0)
55
56
/*! CHECK_ZSTD
57
* Check the zstd error code and die if an error occurred after printing a
58
* message.
59
*/
60
#define CHECK_ZSTD(fn) \
61
do { \
62
size_t const err = (fn); \
63
CHECK(!ZSTD_isError(err), "%s", ZSTD_getErrorName(err)); \
64
} while (0)
65
66
/*! fsize_orDie() :
67
* Get the size of a given file path.
68
*
69
* @return The size of a given file path.
70
*/
71
static size_t fsize_orDie(const char *filename)
72
{
73
struct stat st;
74
if (stat(filename, &st) != 0) {
75
/* error */
76
perror(filename);
77
exit(ERROR_fsize);
78
}
79
80
off_t const fileSize = st.st_size;
81
size_t const size = (size_t)fileSize;
82
/* 1. fileSize should be non-negative,
83
* 2. if off_t -> size_t type conversion results in discrepancy,
84
* the file size is too large for type size_t.
85
*/
86
if ((fileSize < 0) || (fileSize != (off_t)size)) {
87
fprintf(stderr, "%s : filesize too large \n", filename);
88
exit(ERROR_largeFile);
89
}
90
return size;
91
}
92
93
/*! fopen_orDie() :
94
* Open a file using given file path and open option.
95
*
96
* @return If successful this function will return a FILE pointer to an
97
* opened file otherwise it sends an error to stderr and exits.
98
*/
99
static FILE* fopen_orDie(const char *filename, const char *instruction)
100
{
101
FILE* const inFile = fopen(filename, instruction);
102
if (inFile) return inFile;
103
/* error */
104
perror(filename);
105
exit(ERROR_fopen);
106
}
107
108
/*! fclose_orDie() :
109
* Close an opened file using given FILE pointer.
110
*/
111
static void fclose_orDie(FILE* file)
112
{
113
if (!fclose(file)) { return; };
114
/* error */
115
perror("fclose");
116
exit(ERROR_fclose);
117
}
118
119
/*! fread_orDie() :
120
*
121
* Read sizeToRead bytes from a given file, storing them at the
122
* location given by buffer.
123
*
124
* @return The number of bytes read.
125
*/
126
static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file)
127
{
128
size_t const readSize = fread(buffer, 1, sizeToRead, file);
129
if (readSize == sizeToRead) return readSize; /* good */
130
if (feof(file)) return readSize; /* good, reached end of file */
131
/* error */
132
perror("fread");
133
exit(ERROR_fread);
134
}
135
136
/*! fwrite_orDie() :
137
*
138
* Write sizeToWrite bytes to a file pointed to by file, obtaining
139
* them from a location given by buffer.
140
*
141
* Note: This function will send an error to stderr and exit if it
142
* cannot write data to the given file pointer.
143
*
144
* @return The number of bytes written.
145
*/
146
static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file)
147
{
148
size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file);
149
if (writtenSize == sizeToWrite) return sizeToWrite; /* good */
150
/* error */
151
perror("fwrite");
152
exit(ERROR_fwrite);
153
}
154
155
/*! malloc_orDie() :
156
* Allocate memory.
157
*
158
* @return If successful this function returns a pointer to allo-
159
* cated memory. If there is an error, this function will send that
160
* error to stderr and exit.
161
*/
162
static void* malloc_orDie(size_t size)
163
{
164
void* const buff = malloc(size);
165
if (buff) return buff;
166
/* error */
167
perror("malloc");
168
exit(ERROR_malloc);
169
}
170
171
/*! loadFile_orDie() :
172
* load file into buffer (memory).
173
*
174
* Note: This function will send an error to stderr and exit if it
175
* cannot read data from the given file path.
176
*
177
* @return If successful this function will load file into buffer and
178
* return file size, otherwise it will printout an error to stderr and exit.
179
*/
180
static size_t loadFile_orDie(const char* fileName, void* buffer, size_t bufferSize)
181
{
182
size_t const fileSize = fsize_orDie(fileName);
183
CHECK(fileSize <= bufferSize, "File too large!");
184
185
FILE* const inFile = fopen_orDie(fileName, "rb");
186
size_t const readSize = fread(buffer, 1, fileSize, inFile);
187
if (readSize != (size_t)fileSize) {
188
fprintf(stderr, "fread: %s : %s \n", fileName, strerror(errno));
189
exit(ERROR_fread);
190
}
191
fclose(inFile); /* can't fail, read only */
192
return fileSize;
193
}
194
195
/*! mallocAndLoadFile_orDie() :
196
* allocate memory buffer and then load file into it.
197
*
198
* Note: This function will send an error to stderr and exit if memory allocation
199
* fails or it cannot read data from the given file path.
200
*
201
* @return If successful this function will return buffer and bufferSize(=fileSize),
202
* otherwise it will printout an error to stderr and exit.
203
*/
204
static void* mallocAndLoadFile_orDie(const char* fileName, size_t* bufferSize) {
205
size_t const fileSize = fsize_orDie(fileName);
206
*bufferSize = fileSize;
207
void* const buffer = malloc_orDie(*bufferSize);
208
loadFile_orDie(fileName, buffer, *bufferSize);
209
return buffer;
210
}
211
212
/*! saveFile_orDie() :
213
*
214
* Save buffSize bytes to a given file path, obtaining them from a location pointed
215
* to by buff.
216
*
217
* Note: This function will send an error to stderr and exit if it
218
* cannot write to a given file.
219
*/
220
static void saveFile_orDie(const char* fileName, const void* buff, size_t buffSize)
221
{
222
FILE* const oFile = fopen_orDie(fileName, "wb");
223
size_t const wSize = fwrite(buff, 1, buffSize, oFile);
224
if (wSize != (size_t)buffSize) {
225
fprintf(stderr, "fwrite: %s : %s \n", fileName, strerror(errno));
226
exit(ERROR_fwrite);
227
}
228
if (fclose(oFile)) {
229
perror(fileName);
230
exit(ERROR_fclose);
231
}
232
}
233
234
#endif
235
236