X-Git-Url: https://harrygodden.com/git/?p=convexer.git;a=blobdiff_plain;f=cxr%2Fcxr_io.h;fp=cxr%2Fcxr_io.h;h=ed28bb8716018632481cc10a6e402f1bcc60485a;hp=0000000000000000000000000000000000000000;hb=dbd379f76bcb2139fdb5740232511fa789018e10;hpb=8e1b6889db7ce10f8d594539ef74dc4390e8e891 diff --git a/cxr/cxr_io.h b/cxr/cxr_io.h new file mode 100644 index 0000000..ed28bb8 --- /dev/null +++ b/cxr/cxr_io.h @@ -0,0 +1,215 @@ +#ifndef CXR_IO_H +#define CXR_IO_H + +#include +#include +#include +#include "cxr_types.h" + +/* Read binary or text assets in full from file */ +static void *cxr_asset_read_s( const char *path, i64 *size ); +static void *cxr_asset_read( const char *path ); +static char *cxr_textasset_read_s( const char *path, i64 *size ); +static char *cxr_textasset_read( const char *name ); + +static i64 cxr_file_size( FILE *fileptr ); + +/* Path utilities */ +/* Returns pointer to the extension in path */ +static char *cxr_findext( char *path, char const delim ); +static char *cxr_findsep( char *path ); + +static void cxr_stripext( char *path ); +static int cxr_path_is_abs( char const *path ); +static char *cxr_filename( char *path ); + +/* Remove one level (nop if can't) eg: /home/harry/test.file -> /home/harry/ */ +static void cxr_downlvl( char *path ); + +#ifdef _WIN32 + #define CXR_FOLDER_CHAR '\\' +#else + #define CXR_FOLDER_CHAR '/' +#endif + +static i64 cxr_file_size( FILE *fileptr ) +{ + fseek( fileptr, 0, SEEK_END ); + i64 fsize = ftell( fileptr ); + fseek( fileptr, 0, SEEK_SET ); + + return fsize; +} + +static void *fs_disk_open_read( const char *path, int reserve_end, i64 *size ) +{ + FILE *f = fopen( path, "rb" ); + if( f ) + { + i64 fsize = cxr_file_size( f ); + void *buf = malloc( fsize + reserve_end ); + + if( buf ) + { + if( fread( buf, 1, fsize, f ) != fsize ) + { + free( buf ); + buf = NULL; + } + } + + *size = fsize; + + fclose( f ); + return buf; + } + else + { + return NULL; + } +} + +static char *fs_disk_load_text( const char *path, i64 *size ) +{ + char *buf; + i64 fsize; + + if( (buf = fs_disk_open_read( path, 1, &fsize )) ) + { + buf[ fsize ] = 0x00; + *size = fsize +1; + + return buf; + } + + return NULL; +} + +static void *cxr_asset_read_s( const char *path, i64 *size ) +{ + return fs_disk_open_read( path, 0, size ); +} + +static void *cxr_asset_read( const char *path ) +{ + i64 size; + return fs_disk_open_read( path, 0, &size ); +} + +static char *cxr_textasset_read_s( const char *path, i64 *size ) +{ + return fs_disk_load_text( path, size ); +} + +static char *cxr_textasset_read( const char *name ) +{ + i64 size; + return fs_disk_load_text( name, &size ); +} + +static char *cxr_findext( char *path, char const delim ) +{ + char *c, *ptr; + + c = path; + ptr = NULL; + + while( *c ) + { + if( *c == delim ) + { + ptr = c + 1; + } + + c ++; + } + + return ptr; +} + +static char *cxr_findsep( char *path ) +{ + char *c, *ptr; + + c = path; + ptr = NULL; + + while( *c ) + { + if( *c == '/' || *c == '\\' ) + { + ptr = c + 1; + } + + c ++; + } + + return ptr; +} + +static void cxr_stripext( char *path ) +{ + char *point, *start; + + // Skip folders + if( !(start = cxr_findsep( path )) ) + { + start = path; + } + + if( (point = cxr_findext( start, '.' )) ) + { + if( point > path ) + { + *(point-1) = 0x00; + } + } +} + +static void cxr_downlvl( char *path ) +{ + char *start_name, *c; + + c = path; + while( *c ) + c ++; + int len = c - path; + + if( len ) + path[ len -1 ] = 0x00; + + if( (start_name = cxr_findsep( path ) )) + *start_name = 0x00; + else + path[0] = 0x00; +} + +static char *cxr_filename( char *path ) +{ + char *base_name; + if( (base_name = cxr_findsep( path ) )) + return base_name; + + return path; +} + +static int cxr_path_is_abs( char const *path ) +{ +#ifdef _WIN32 + if( strlen( path ) < 2 ) return 0; + return path[1] == ':'; +#else + if( strlen( path ) < 1 ) return 0; + return path[0] == '/'; +#endif +} + +static char *cxr_str_clone( char const *str, int extra ) +{ + char *newstr = malloc(strlen(str)+1+extra); + strcpy( newstr, str ); + + return newstr; +} + +#endif /* CXR_IO_H */