aboutsummaryrefslogtreecommitdiff
path: root/filesystem/src
diff options
context:
space:
mode:
Diffstat (limited to 'filesystem/src')
-rw-r--r--filesystem/src/filesystem.c92
1 files changed, 92 insertions, 0 deletions
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 @@
1#include <filesystem.h>
2
3#include <assert.h>
4#include <stdlib.h>
5#include <string.h>
6
7size_t get_file_size(FILE* file) {
8 assert(file);
9 const long int starting_pos = ftell(file);
10 if (starting_pos == -1) {
11 return (size_t)-1;
12 }
13 if (fseek(file, 0, SEEK_END) != 0) {
14 return (size_t)-1;
15 }
16 const size_t file_size = ftell(file);
17 if (file_size == (size_t)-1) {
18 return (size_t)-1;
19 }
20 if (fseek(file, starting_pos, SEEK_SET) != 0) {
21 return (size_t)-1;
22 }
23 return file_size;
24}
25
26void* read_file(const char* filepath) {
27 assert(filepath);
28
29 void* data = 0;
30
31 FILE* file = fopen(filepath, "rb");
32 if (!file) {
33 return 0;
34 }
35 const size_t file_size = get_file_size(file);
36 if (file_size == (size_t)-1) {
37 goto cleanup;
38 }
39
40 data = calloc(1, file_size);
41 if (!data) {
42 goto cleanup;
43 }
44 if (fread(data, 1, file_size, file) != file_size) {
45 goto cleanup;
46 }
47
48 return data;
49
50cleanup:
51 fclose(file);
52 if (data) {
53 free(data);
54 }
55 return 0;
56}
57
58bool make_relative_path(
59 size_t max_path_length, const char* filepath, const char* path,
60 char* relative) {
61 assert(filepath);
62 assert(path);
63 assert(relative);
64
65 // Handle empty filepath.
66 const size_t filepath_len = strlen(filepath);
67 if (filepath_len == 0) {
68 memcpy(relative, path, max_path_length);
69 return true;
70 }
71
72 memcpy(relative, filepath, max_path_length);
73 // Search for the last / in the tile map file path to get its parent
74 // directory.
75 assert(filepath_len > 0);
76 size_t tm_dir_len = 0;
77 for (tm_dir_len = strlen(filepath) - 1; tm_dir_len > 0; --tm_dir_len) {
78 if (filepath[tm_dir_len] == '/') {
79 break;
80 }
81 }
82 tm_dir_len++; // Preserve the backslash.
83
84 // Copy the tile set file path where the parent dir ends.
85 // Make sure there is enough space in the output.
86 const size_t path_len = strlen(path);
87 if ((tm_dir_len + path_len + 1) >= max_path_length) {
88 return false;
89 }
90 memcpy(&relative[tm_dir_len], path, path_len);
91 return true;
92}