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. --- CMakeLists.txt | 3 ++ filesystem/CMakeLists.txt | 11 +++++ filesystem/include/filesystem.h | 19 +++++++++ filesystem/src/filesystem.c | 92 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 filesystem/CMakeLists.txt create mode 100644 filesystem/include/filesystem.h create mode 100644 filesystem/src/filesystem.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 4695e06..498b771 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,9 +3,12 @@ cmake_minimum_required(VERSION 3.0) project(clib) add_subdirectory(cstring) +add_subdirectory(error) +add_subdirectory(filesystem) add_subdirectory(list) add_subdirectory(listpool) add_subdirectory(log) add_subdirectory(mempool) +add_subdirectory(plugin) add_subdirectory(random) add_subdirectory(timer) diff --git a/filesystem/CMakeLists.txt b/filesystem/CMakeLists.txt new file mode 100644 index 0000000..55430e6 --- /dev/null +++ b/filesystem/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.0) + +project(filesystem) + +add_library(filesystem + src/filesystem.c) + +target_include_directories(filesystem PUBLIC + include) + +target_compile_options(filesystem PRIVATE -Wall -Wextra) diff --git a/filesystem/include/filesystem.h b/filesystem/include/filesystem.h new file mode 100644 index 0000000..62bd7f0 --- /dev/null +++ b/filesystem/include/filesystem.h @@ -0,0 +1,19 @@ +/* + * Various filesystem utilities. + */ +#pragma once + +#include +#include +#include + +/// Get the file's size. +size_t get_file_size(FILE* file); + +/// Read the entire contents of the file into memory. +void* read_file(const char* filepath); + +/// Make a path relative to the parent directory of a file. +bool make_relative_path( + size_t max_path_length, const char* filepath, const char* path, + char* relative); 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