From fc5886c75ab2626acbc0d7b3db475d17d2cbe01f Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Tue, 11 Jul 2023 18:37:45 -0700 Subject: Add filesystem library. --- filesystem/src/filesystem.c | 92 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 filesystem/src/filesystem.c (limited to 'filesystem/src/filesystem.c') diff --git a/filesystem/src/filesystem.c b/filesystem/src/filesystem.c new file mode 100644 index 0000000..6c0dcfb --- /dev/null +++ b/filesystem/src/filesystem.c @@ -0,0 +1,92 @@ +#include + +#include +#include +#include + +size_t get_file_size(FILE* file) { + assert(file); + const long int starting_pos = ftell(file); + if (starting_pos == -1) { + return (size_t)-1; + } + if (fseek(file, 0, SEEK_END) != 0) { + return (size_t)-1; + } + const size_t file_size = ftell(file); + if (file_size == (size_t)-1) { + return (size_t)-1; + } + if (fseek(file, starting_pos, SEEK_SET) != 0) { + return (size_t)-1; + } + return file_size; +} + +void* read_file(const char* filepath) { + assert(filepath); + + void* data = 0; + + FILE* file = fopen(filepath, "rb"); + if (!file) { + return 0; + } + const size_t file_size = get_file_size(file); + if (file_size == (size_t)-1) { + goto cleanup; + } + + data = calloc(1, file_size); + if (!data) { + goto cleanup; + } + if (fread(data, 1, file_size, file) != file_size) { + goto cleanup; + } + + return data; + +cleanup: + fclose(file); + if (data) { + free(data); + } + return 0; +} + +bool make_relative_path( + size_t max_path_length, const char* filepath, const char* path, + char* relative) { + assert(filepath); + assert(path); + assert(relative); + + // Handle empty filepath. + const size_t filepath_len = strlen(filepath); + if (filepath_len == 0) { + memcpy(relative, path, max_path_length); + return true; + } + + memcpy(relative, filepath, max_path_length); + // Search for the last / in the tile map file path to get its parent + // directory. + assert(filepath_len > 0); + size_t tm_dir_len = 0; + for (tm_dir_len = strlen(filepath) - 1; tm_dir_len > 0; --tm_dir_len) { + if (filepath[tm_dir_len] == '/') { + break; + } + } + tm_dir_len++; // Preserve the backslash. + + // Copy the tile set file path where the parent dir ends. + // Make sure there is enough space in the output. + const size_t path_len = strlen(path); + if ((tm_dir_len + path_len + 1) >= max_path_length) { + return false; + } + memcpy(&relative[tm_dir_len], path, path_len); + return true; +} -- cgit v1.2.3