#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; }