ed28bb8716018632481cc10a6e402f1bcc60485a
[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 void 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 void *fs_disk_open_read( const char *path, int reserve_end, i64 *size )
45 {
46 FILE *f = fopen( path, "rb" );
47 if( f )
48 {
49 i64 fsize = cxr_file_size( f );
50 void *buf = malloc( fsize + reserve_end );
51
52 if( buf )
53 {
54 if( fread( buf, 1, fsize, f ) != fsize )
55 {
56 free( buf );
57 buf = NULL;
58 }
59 }
60
61 *size = fsize;
62
63 fclose( f );
64 return buf;
65 }
66 else
67 {
68 return NULL;
69 }
70 }
71
72 static char *fs_disk_load_text( const char *path, i64 *size )
73 {
74 char *buf;
75 i64 fsize;
76
77 if( (buf = fs_disk_open_read( path, 1, &fsize )) )
78 {
79 buf[ fsize ] = 0x00;
80 *size = fsize +1;
81
82 return buf;
83 }
84
85 return NULL;
86 }
87
88 static void *cxr_asset_read_s( const char *path, i64 *size )
89 {
90 return fs_disk_open_read( path, 0, size );
91 }
92
93 static void *cxr_asset_read( const char *path )
94 {
95 i64 size;
96 return fs_disk_open_read( path, 0, &size );
97 }
98
99 static char *cxr_textasset_read_s( const char *path, i64 *size )
100 {
101 return fs_disk_load_text( path, size );
102 }
103
104 static char *cxr_textasset_read( const char *name )
105 {
106 i64 size;
107 return fs_disk_load_text( name, &size );
108 }
109
110 static char *cxr_findext( char *path, char const delim )
111 {
112 char *c, *ptr;
113
114 c = path;
115 ptr = NULL;
116
117 while( *c )
118 {
119 if( *c == delim )
120 {
121 ptr = c + 1;
122 }
123
124 c ++;
125 }
126
127 return ptr;
128 }
129
130 static char *cxr_findsep( char *path )
131 {
132 char *c, *ptr;
133
134 c = path;
135 ptr = NULL;
136
137 while( *c )
138 {
139 if( *c == '/' || *c == '\\' )
140 {
141 ptr = c + 1;
142 }
143
144 c ++;
145 }
146
147 return ptr;
148 }
149
150 static void cxr_stripext( char *path )
151 {
152 char *point, *start;
153
154 // Skip folders
155 if( !(start = cxr_findsep( path )) )
156 {
157 start = path;
158 }
159
160 if( (point = cxr_findext( start, '.' )) )
161 {
162 if( point > path )
163 {
164 *(point-1) = 0x00;
165 }
166 }
167 }
168
169 static void cxr_downlvl( char *path )
170 {
171 char *start_name, *c;
172
173 c = path;
174 while( *c )
175 c ++;
176 int len = c - path;
177
178 if( len )
179 path[ len -1 ] = 0x00;
180
181 if( (start_name = cxr_findsep( path ) ))
182 *start_name = 0x00;
183 else
184 path[0] = 0x00;
185 }
186
187 static char *cxr_filename( char *path )
188 {
189 char *base_name;
190 if( (base_name = cxr_findsep( path ) ))
191 return base_name;
192
193 return path;
194 }
195
196 static int cxr_path_is_abs( char const *path )
197 {
198 #ifdef _WIN32
199 if( strlen( path ) < 2 ) return 0;
200 return path[1] == ':';
201 #else
202 if( strlen( path ) < 1 ) return 0;
203 return path[0] == '/';
204 #endif
205 }
206
207 static char *cxr_str_clone( char const *str, int extra )
208 {
209 char *newstr = malloc(strlen(str)+1+extra);
210 strcpy( newstr, str );
211
212 return newstr;
213 }
214
215 #endif /* CXR_IO_H */