diff options
| author | 3gg <3gg@shellblade.net> | 2025-07-19 09:29:54 -0700 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-07-19 09:29:54 -0700 |
| commit | 75705ca3d91930a730743b5319268087fc7bc56e (patch) | |
| tree | 266fe906020a01559e1f5ca19f41b1e4c7252100 | |
| parent | ff565e8d422c5e58558d1f7682ba0c9756e5be27 (diff) | |
New filesystem API
| -rw-r--r-- | filesystem/include/filesystem.h | 20 | ||||
| -rw-r--r-- | filesystem/src/filesystem.c | 65 |
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. | ||
| 20 | size_t get_file_size(const char* filename); | ||
| 21 | |||
| 9 | /// Get the file's size. | 22 | /// Get the file's size. |
| 10 | size_t get_file_size(FILE* file); | 23 | size_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. |
| 13 | void* read_file(const char* filepath); | 26 | void* 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. | ||
| 31 | bool 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 | ||
| 8 | size_t get_file_size(FILE* file) { | 8 | size_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 | |||
| 14 | size_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) { | |||
| 27 | void* read_file(const char* filepath) { | 33 | void* 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 | ||
| 51 | cleanup: | 58 | bool 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 | } |
