1 /************************************************************************
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
29 #define FILE_BUFF_STEP 1024
31 static int file_extend(file_t
*file
, int min
)
36 /* load a file into memory */
37 file_t
*file_load(char* type
, char *name
)
46 path
= path_get(type
,name
,1,NULL
,0);
49 fn
= strrchr(name
,'/');
55 f
= fopen(path
, "rb");
61 ft
= malloc(sizeof(file_t
));
71 fseek(f
, 0, SEEK_END
);
73 fseek(f
, 0, SEEK_SET
);
77 ft
->data
= malloc(ft
->size
);
85 if (ft
->len
!= fread(ft
->data
, 1, ft
->len
, f
)) {
93 /* this lets us do string operations on text files */
94 ft
->data
[ft
->len
] = 0;
98 ft
->name
= strdup(fn
);
104 /* load a file into memory */
105 file_t
*file_create(char* type
, char *name
)
114 path
= path_get(type
,name
,0,NULL
,0);
117 fn
= strrchr(name
,'/');
127 ft
= malloc(sizeof(file_t
));
141 ft
->name
= strdup(fn
);
147 /* free a loaded file */
148 void file_free(file_t
*file
)
162 /* flush file data to disk */
163 void file_flush(file_t
*file
)
166 if (!file
|| !file
->modified
|| !file
->path
)
169 if (!path_exists(file
->path
)) {
170 if (!path_create(NULL
,file
->path
))
174 f
= fopen(file
->path
, "wb");
179 if (fwrite(file
->data
,1,file
->len
,f
) != file
->len
) {
189 /* find the next occurance of value from offset in file, return it's position
190 * relative to offset */
191 int file_find(file_t
*file
, int offset
, unsigned char value
)
197 for (r
=offset
; r
<file
->len
; r
++) {
198 if (file
->data
[r
] == value
)
204 /* find the next occurance of value from offset in file, return it's position
205 * relative to offset */
206 int file_strfind(file_t
*file
, int offset
, char* value
)
210 if (!file
|| file
->len
<= offset
)
213 v
= strstr((char*)(file
->data
+offset
),value
);
217 r
= (v
-(char*)file
->data
);
224 /* read from a file buffer to dst */
225 int file_read(file_t
*file
, void* dst
, int size
)
228 if (!file
|| !file
->len
)
231 len
= file
->len
- file
->pos
;
237 memcpy(dst
, file
->data
+file
->pos
, len
);
244 /* read a line from a file buffer to dst */
245 int file_readline(file_t
*file
, char* dst
, int size
)
250 if (!file
|| !file
->len
)
253 b
= (char*)(file
->data
+file
->pos
);
270 if (file
->pos
> file
->len
)
271 file
->pos
= file
->len
;
276 /* read integer from a file buffer */
277 int file_read_int(file_t
*file
)
280 file_read(file
,&r
,4);
284 /* read short integer from a file buffer */
285 int16_t file_read_short(file_t
*file
)
288 file_read(file
,&r
,2);
292 /* read char from a file buffer */
293 char file_read_char(file_t
*file
)
296 file_read(file
,&r
,1);
300 /* read unsigned integer from a file buffer */
301 uint32_t file_read_uint(file_t
*file
)
304 file_read(file
,&r
,4);
308 /* read float from a file buffer */
309 float file_read_float(file_t
*file
)
312 file_read(file
,&r
,4);
316 /* seek to a position in a file buffer */
317 int file_seek(file_t
*file
, int offset
, int origin
)
324 if (file
->len
< offset
)
331 if (file
->len
< offset
)
337 file
->pos
= file
->len
;
348 /* get the position in a file buffer */
349 int file_tell(file_t
*file
)
357 /* get the pointer to the current file position */
358 void *file_get(file_t
*file
)
360 return file
->data
+file
->pos
;
363 /* write data to a file buffer */
364 int file_write(file_t
*file
, void *buff
, int size
)
366 if (!file
|| !buff
|| size
)
369 if (file
->size
<= (file
->pos
+size
)) {
370 if (file_extend(file
,file
->pos
+size
+1) < 0)
374 if (!memcpy(file
->data
+file
->pos
,buff
,size
)) {
375 file
->data
[file
->pos
] = 0;
380 file
->data
[file
->pos
] = 0;
385 /* write a formatted string to a file buffer (printf style) */
386 int file_writef(file_t
*file
, char* fmt
, ...)
394 if (!file
->size
|| !file
->data
) {
395 if (file_extend(file
,FILE_BUFF_STEP
) < 0)
399 /* basically "keep trying till it all fits" */
402 s
= (file
->size
-1)-file
->pos
;
403 l
= vsnprintf((char*)(file
->data
+file
->pos
), s
, fmt
, ap
);
407 if (file_extend(file
,s
+FILE_BUFF_STEP
) < 0) {
409 file
->data
[file
->pos
] = 0;
415 file
->data
[file
->pos
] = 0;