the asumptions were of course, incorrect
[convexer.git] / cxr / cxr_io.h
1 #ifndef CXR_IO_H
2 #define CXR_IO_H
3
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include "cxr_types.h"
8
9 /* Read binary or text assets in full from file */
10 static void *cxr_asset_read_s( const char *path, i64 *size );
11 static void *cxr_asset_read( const char *path );
12 static char *cxr_textasset_read_s( const char *path, i64 *size );
13 static char *cxr_textasset_read( const char *name );
14
15 static i64 cxr_file_size( FILE *fileptr );
16
17 /* Path utilities */
18 /* Returns pointer to the extension in path */
19 static char *cxr_findext( char *path, char const delim );
20 static char *cxr_findsep( char *path );
21
22 static char *cxr_stripext( char *path );
23 static int cxr_path_is_abs( char const *path );
24 static char *cxr_filename( char *path );
25
26 /* Remove one level (nop if can't) eg: /home/harry/test.file -> /home/harry/ */
27 static void cxr_downlvl( char *path );
28
29 #ifdef _WIN32
30 #define CXR_FOLDER_CHAR '\\'
31 #else
32 #define CXR_FOLDER_CHAR '/'
33 #endif
34
35 static i64 cxr_file_size( FILE *fileptr )
36 {
37 fseek( fileptr, 0, SEEK_END );
38 i64 fsize = ftell( fileptr );
39 fseek( fileptr, 0, SEEK_SET );
40
41 return fsize;
42 }
43
44 static int cxr_file_exists( const char *path )
45 {
46 FILE *fp;
47 if( (fp=fopen( path, "rb" )) )
48 {
49 fclose(fp);
50 return 1;
51 }
52
53 return 0;
54 }
55
56 static void *fs_disk_open_read( const char *path, int reserve_end, i64 *size )
57 {
58 FILE *f = fopen( path, "rb" );
59 if( f )
60 {
61 printf( "fs_open_read (%s)\n", path );
62
63 i64 fsize = cxr_file_size( f );
64 void *buf = malloc( fsize + reserve_end );
65
66 if( buf )
67 {
68 if( fread( buf, 1, fsize, f ) != fsize )
69 {
70 free( buf );
71 buf = NULL;
72 }
73 }
74
75 *size = fsize;
76
77 fclose( f );
78 return buf;
79 }
80 else
81 {
82 return NULL;
83 }
84 }
85
86 static char *fs_disk_load_text( const char *path, i64 *size )
87 {
88 char *buf;
89 i64 fsize;
90
91 if( (buf = fs_disk_open_read( path, 1, &fsize )) )
92 {
93 buf[ fsize ] = 0x00;
94 *size = fsize +1;
95
96 return buf;
97 }
98
99 return NULL;
100 }
101
102 static void *cxr_asset_read_s( const char *path, i64 *size )
103 {
104 return fs_disk_open_read( path, 0, size );
105 }
106
107 static void *cxr_asset_read( const char *path )
108 {
109 i64 size;
110 return fs_disk_open_read( path, 0, &size );
111 }
112
113 static char *cxr_textasset_read_s( const char *path, i64 *size )
114 {
115 return fs_disk_load_text( path, size );
116 }
117
118 static char *cxr_textasset_read( const char *name )
119 {
120 i64 size;
121 return fs_disk_load_text( name, &size );
122 }
123
124 static char *cxr_findext( char *path, char const delim )
125 {
126 char *c, *ptr;
127
128 c = path;
129 ptr = NULL;
130
131 while( *c )
132 {
133 if( *c == delim )
134 {
135 ptr = c + 1;
136 }
137
138 c ++;
139 }
140
141 return ptr;
142 }
143
144 static char *cxr_findsep( char *path )
145 {
146 char *c, *ptr;
147
148 c = path;
149 ptr = NULL;
150
151 while( *c )
152 {
153 if( *c == '/' || *c == '\\' )
154 {
155 ptr = c + 1;
156 }
157
158 c ++;
159 }
160
161 return ptr;
162 }
163
164 static char *cxr_stripext( char *path )
165 {
166 char *point, *start, *ret = NULL;
167
168 /* Skip any folders */
169 if( !(start = cxr_findsep( path )) )
170 {
171 start = path;
172 }
173
174 if( (point = cxr_findext( start, '.' )) )
175 {
176 if( point > path )
177 {
178 ret = point-1;
179 *(ret) = 0x00;
180 }
181 }
182
183 return ret;
184 }
185
186 static void cxr_downlvl( char *path )
187 {
188 char *start_name, *c;
189
190 c = path;
191 while( *c )
192 c ++;
193 int len = c - path;
194
195 if( len )
196 path[ len -1 ] = 0x00;
197
198 if( (start_name = cxr_findsep( path ) ))
199 *start_name = 0x00;
200 else
201 path[0] = 0x00;
202 }
203
204 static char *cxr_filename( char *path )
205 {
206 char *base_name;
207 if( (base_name = cxr_findsep( path ) ))
208 return base_name;
209
210 return path;
211 }
212
213 static int cxr_path_is_abs( char const *path )
214 {
215 #ifdef _WIN32
216 if( strlen( path ) < 2 ) return 0;
217 return path[1] == ':';
218 #else
219 if( strlen( path ) < 1 ) return 0;
220 return path[0] == '/';
221 #endif
222 }
223
224 static void cxr_lowercase( char *str )
225 {
226 char *c = str;
227 while( *c )
228 {
229 int val = (int)*c;
230 if( val >= (int)'A' && val <= (int)'Z' )
231 {
232 val = (int)'a' + (val - (int)'A');
233 *c = (char)val;
234 }
235
236 c ++;
237 }
238 }
239
240 static void cxr_unixpath( char *path )
241 {
242 char *c = path;
243 while( *c )
244 {
245 if( *c == '\\' )
246 *c = '/';
247
248 c ++;
249 }
250 }
251
252 static char *cxr_str_clone( char const *str, int extra )
253 {
254 if( !str )
255 return NULL;
256
257 char *newstr = malloc(strlen(str)+1+extra);
258 strcpy( newstr, str );
259
260 return newstr;
261 }
262
263 #endif /* CXR_IO_H */