fixed instance loading forget to append basepath.. other path fixes (windows)
[csRadar.git] / csrIO.h
1 // Copyright (C) 2021 Harry Godden (hgn)
2
3 // Low level disk reading
4 //=======================================================================================================================
5
6 // Read binary, or text assets. _s variants also give size in bytes
7 void *csr_asset_read_s( const char *path, i64 *size );
8 void *csr_asset_read( const char *path );
9 char *csr_textasset_read_s( const char *path, i64 *size );
10 char *csr_textasset_read( const char *name );
11
12 i64 fs_file_size( FILE *fileptr );
13
14 // Path handling
15 // -------------
16
17 // Find file path extension, returns NULL if no ext (0x00) example: /test/file.jpg returns pointer to: jpg
18 char *csr_findext( char *path, char const delim );
19 char *csr_findsep( char *path ); // Same as above but operates on \ and /
20
21 // gets rid of extension on string only left with (folder)+filename
22 void csr_stripext( char *path );
23
24 int csr_path_is_abs( char const *path );
25
26 // Remove one level (nop if can't) eg: /home/harry/test.file -> /home/harry/
27 void csr_downlvl( char *path );
28
29 // Get only the file name example: /test/file.jpg returns file.jpg
30 char *csr_filename( char *path );
31
32 // Implementation
33 //=======================================================================================================================
34
35 #ifdef _WIN32
36 #define CSR_FOLDER_CHAR '\\'
37 #else
38 #define CSR_FOLDER_CHAR '/'
39 #endif
40
41 #ifdef CSR_EXECUTABLE
42
43 i64 fs_file_size( FILE *fileptr )
44 {
45 fseek( fileptr, 0, SEEK_END );
46 i64 fsize = ftell( fileptr );
47 fseek( fileptr, 0, SEEK_SET );
48
49 return fsize;
50 }
51
52 void *fs_disk_open_read( const char *path, int const reserve_end, i64 *size )
53 {
54 FILE *f = fopen( path, "rb" );
55 if( f )
56 {
57 i64 fsize = fs_file_size( f );
58 void *buf = csr_malloc( fsize + reserve_end );
59
60 if( buf )
61 {
62 // Invalid / corrupt read
63 if( fread( buf, 1, fsize, f ) != fsize )
64 {
65 free( buf );
66 buf = NULL;
67 }
68 }
69
70 *size = fsize;
71
72 fclose( f );
73 return buf;
74 }
75 else
76 {
77 return NULL;
78 }
79 }
80
81 char *fs_disk_load_text( const char *path, i64 *size )
82 {
83 char *buf;
84 i64 fsize;
85
86 if( (buf = fs_disk_open_read( path, 1, &fsize )) )
87 {
88 buf[ fsize ] = 0x00;
89 *size = fsize +1;
90
91 return buf;
92 }
93
94 return NULL;
95 }
96
97 void *csr_asset_read_s( const char *path, i64 *size )
98 {
99 return fs_disk_open_read( path, 0, size );
100 }
101
102 void *csr_asset_read( const char *path )
103 {
104 i64 size;
105 return fs_disk_open_read( path, 0, &size );
106 }
107
108 char *csr_textasset_read_s( const char *path, i64 *size )
109 {
110 return fs_disk_load_text( path, size );
111 }
112
113 char *csr_textasset_read( const char *name )
114 {
115 i64 size;
116 return fs_disk_load_text( name, &size );
117 }
118
119 char *csr_findext( char *path, char const delim )
120 {
121 char *c, *ptr;
122
123 c = path;
124 ptr = NULL;
125
126 while( *c )
127 {
128 if( *c == delim )
129 {
130 ptr = c + 1;
131 }
132
133 c ++;
134 }
135
136 return ptr;
137 }
138
139 // Find 'seperator'.. because folders can be / or \ on windows..
140 char *csr_findsep( char *path )
141 {
142 char *c, *ptr;
143
144 c = path;
145 ptr = NULL;
146
147 while( *c )
148 {
149 if( *c == '/' || *c == '\\' )
150 {
151 ptr = c + 1;
152 }
153
154 c ++;
155 }
156
157 return ptr;
158 }
159
160 void csr_stripext( char *path )
161 {
162 char *point, *start;
163
164 // Skip folders
165 if( !(start = csr_findsep( path )) )
166 {
167 start = path;
168 }
169
170 if( (point = csr_findext( start, '.' )) )
171 {
172 if( point > path )
173 {
174 *(point-1) = 0x00;
175 }
176 }
177 }
178
179 void csr_downlvl( char *path )
180 {
181 char *start_name, *c;
182
183 c = path;
184 while( *c )
185 c ++;
186 int len = c - path;
187
188 if( len )
189 path[ len -1 ] = 0x00;
190
191 if( (start_name = csr_findsep( path ) ))
192 *start_name = 0x00;
193 else
194 path[0] = 0x00;
195 }
196
197 char *csr_filename( char *path )
198 {
199 char *base_name;
200 if( (base_name = csr_findsep( path ) ))
201 return base_name;
202
203 return path;
204 }
205
206 int csr_path_is_abs( char const *path )
207 {
208 #ifdef _WIN32
209 if( strlen( path ) < 2 ) return 0;
210 return path[1] == ':';
211 #else
212 if( strlen( path ) < 1 ) return 0;
213 return path[0] == '/';
214 #endif
215 }
216
217 #endif