aboutsummaryrefslogtreecommitdiff
path: root/filesystem
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-07-19 09:29:54 -0700
committer3gg <3gg@shellblade.net>2025-07-19 09:29:54 -0700
commit75705ca3d91930a730743b5319268087fc7bc56e (patch)
tree266fe906020a01559e1f5ca19f41b1e4c7252100 /filesystem
parentff565e8d422c5e58558d1f7682ba0c9756e5be27 (diff)
New filesystem API
Diffstat (limited to 'filesystem')
-rw-r--r--filesystem/include/filesystem.h20
-rw-r--r--filesystem/src/filesystem.c65
2 files changed, 58 insertions, 27 deletions
diff --git a/filesystem/include/filesystem.h b/filesystem/include/filesystem.h
index 1c354b7..bc7f953 100644
--- a/filesystem/include/filesystem.h
+++ b/filesystem/include/filesystem.h
@@ -6,8 +6,26 @@
6#include <stddef.h> 6#include <stddef.h>
7#include <stdio.h> 7#include <stdio.h>
8 8
9#define WITH_FILE(FILEPATH, BODY) \
10 { \
11 assert(FILEPATH); \
12 FILE* file = fopen(FILEPATH, "rb"); \
13 if (file) { \
14 BODY; \
15 fclose(file); \
16 } \
17 }
18
19/// Get the file's size.
20size_t get_file_size(const char* filename);
21
9/// Get the file's size. 22/// Get the file's size.
10size_t get_file_size(FILE* file); 23size_t get_file_size_f(FILE* file);
11 24
12/// Read the entire contents of the file into memory. 25/// Read the entire contents of the file into memory.
13void* read_file(const char* filepath); 26void* read_file(const char* filepath);
27
28/// Read the entire contents of the file into memory.
29///
30/// The given buffer must be large enough to hold the file's contents.
31bool read_file_f(FILE*, void* buffer);
diff --git a/filesystem/src/filesystem.c b/filesystem/src/filesystem.c
index b0c207a..b30c072 100644
--- a/filesystem/src/filesystem.c
+++ b/filesystem/src/filesystem.c
@@ -5,21 +5,27 @@
5#include <stdlib.h> 5#include <stdlib.h>
6#include <string.h> 6#include <string.h>
7 7
8size_t get_file_size(FILE* file) { 8size_t get_file_size(const char* filename) {
9 size_t size = 0;
10 WITH_FILE(filename, size = get_file_size_f(file));
11 return size;
12}
13
14size_t get_file_size_f(FILE* file) {
9 assert(file); 15 assert(file);
10 const long int starting_pos = ftell(file); 16 const long int starting_pos = ftell(file);
11 if (starting_pos == -1) { 17 if (starting_pos == -1) {
12 return (size_t)-1; 18 return 0;
13 } 19 }
14 if (fseek(file, 0, SEEK_END) != 0) { 20 if (fseek(file, 0, SEEK_END) != 0) {
15 return (size_t)-1; 21 return 0;
16 } 22 }
17 const size_t file_size = ftell(file); 23 const size_t file_size = ftell(file);
18 if (file_size == (size_t)-1) { 24 if (file_size == (size_t)-1) {
19 return (size_t)-1; 25 return 0;
20 } 26 }
21 if (fseek(file, starting_pos, SEEK_SET) != 0) { 27 if (fseek(file, starting_pos, SEEK_SET) != 0) {
22 return (size_t)-1; 28 return 0;
23 } 29 }
24 return file_size; 30 return file_size;
25} 31}
@@ -27,31 +33,38 @@ size_t get_file_size(FILE* file) {
27void* read_file(const char* filepath) { 33void* read_file(const char* filepath) {
28 assert(filepath); 34 assert(filepath);
29 35
30 void* data = nullptr; 36 void* data = nullptr;
37 bool success = false;
31 38
32 FILE* file = fopen(filepath, "rb"); 39 WITH_FILE(filepath, {
33 if (!file) { 40 const size_t file_size = get_file_size_f(file);
34 return nullptr; 41 if (file_size > 0) {
35 } 42 data = calloc(1, file_size);
36 const size_t file_size = get_file_size(file); 43 if (data != nullptr) {
37 if (file_size == (size_t)-1) { 44 if (fread(data, 1, file_size, file) == file_size) {
38 goto cleanup; 45 success = true;
39 } 46 }
47 }
48 }
49 });
40 50
41 data = calloc(1, file_size); 51 if (!success) {
42 if (!data) { 52 free(data);
43 goto cleanup; 53 data = nullptr;
44 }
45 if (fread(data, 1, file_size, file) != file_size) {
46 goto cleanup;
47 } 54 }
48
49 return data; 55 return data;
56}
50 57
51cleanup: 58bool read_file_f(FILE* file, void* buffer) {
52 fclose(file); 59 assert(file);
53 if (data) { 60 assert(buffer);
54 free(data); 61
62 bool success = false;
63 const size_t file_size = get_file_size_f(file);
64 if (file_size > 0) {
65 if (fread(buffer, 1, file_size, file) == file_size) {
66 success = true;
67 }
55 } 68 }
56 return nullptr; 69 return success;
57} 70}