X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vg_io.h;h=87562ace408a919ba0d02afdc4c0262ac3e64893;hb=76d234b7dc5e6500e8a54009b367e7620f11ef97;hp=93525446094aa6a9ee3dac9ff9e0fad914b4673f;hpb=6d772a1e69860f4ae3e838e8c5c164754e6533ae;p=vg.git diff --git a/vg_io.h b/vg_io.h index 9352544..87562ac 100644 --- a/vg_io.h +++ b/vg_io.h @@ -3,17 +3,131 @@ #ifndef VG_IO_H #define VG_IO_H +#include "vg.h" #include "vg_stdint.h" #include "vg_platform.h" #include "vg_log.h" #include "vg_mem.h" -#include -#include -#define _TINYDIR_MALLOC(_size) vg_linear_alloc( vg_mem.scratch, _size ) -#define _TINYDIR_FREE(_size) -#include "submodules/tinydir/tinydir.h" +typedef struct vg_dir vg_dir; +#ifndef _WIN32 + #include + struct vg_dir{ + DIR *h; + struct dirent *data; + u32 index; + }; +#else + #include + #include + struct vg_dir{ + HANDLE h; + WIN32_FIND_DATA data; + u32 index; + }; +#endif + +enum vg_entry_type{ + k_vg_entry_type_unknown, + k_vg_entry_type_file, + k_vg_entry_type_dir +}; + +static int vg_dir_open( vg_dir *dir, const char *name ){ +#ifdef _WIN32 + char q_buf[4096]; + vg_str q; + vg_strnull( &q, q_buf, 4096 ); + vg_strcat( &q, name ); + vg_strcat( &q, "/*" ); + if( !vg_strgood(&q) ) return 0; + + vg_info( "FindFirstFile( '%s' )\n", q.buffer ); + dir->h = FindFirstFile( q.buffer, &dir->data ); + if( dir->h == INVALID_HANDLE_VALUE ){ + if( GetLastError() == ERROR_FILE_NOT_FOUND ){ + dir->index = 0; + return 1; + } + else return 0; + } +#else + dir->h = opendir( name ); + if( !dir->h ) return 0; +#endif + dir->index = 1; + return 1; +} + +static const char *vg_dir_entry_name( vg_dir *dir ){ +#ifdef _WIN32 + return dir->data.cFileName; +#else + return dir->data->d_name; +#endif +} + +static int vg_dirskip( vg_dir *dir ){ + const char *s = vg_dir_entry_name(dir); +#ifdef _WIN32 + if( dir->data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) return 1; +#endif + if( s[0] == '.' ){ + if( s[1] == '\0' ) return 1; + else if( s[1] == '.' ){ + if( s[2] == '\0' ) return 1; + } + } + return 0; +} + +static int vg_dir_next_entry( vg_dir *dir ){ +#ifdef _WIN32 + if( dir->index == 0 ) return 0; + if( dir->index > 1 ) { + dir->index ++; + if( !FindNextFile( dir->h, &dir->data ) ) return 0; + } + while( vg_dirskip(dir) ){ + dir->index ++; + if( !FindNextFile( dir->h, &dir->data ) ) return 0; + } + if( dir->index == 1 ) dir->index ++; + return 1; +#else + while( (dir->data = readdir(dir->h)) ){ + dir->index ++; + if( !vg_dirskip(dir) ) break; + } + if( dir->data ) return 1; + else return 0; +#endif +} + +static enum vg_entry_type vg_dir_entry_type( vg_dir *dir ){ +#ifdef _WIN32 + if( dir->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + return k_vg_entry_type_dir; + return k_vg_entry_type_file; /* sketchy? */ +#else + if( dir->data->d_type == DT_DIR ) return k_vg_entry_type_dir; + if( dir->data->d_type == DT_REG ) return k_vg_entry_type_file; +#endif + return 0; +} + +static void vg_dir_close( vg_dir *dir ){ +#ifdef _WIN32 + if( dir->index ) FindClose( dir->h ); + dir->h = INVALID_HANDLE_VALUE; +#else + closedir( dir->h ); + dir->h = NULL; + dir->data = NULL; +#endif + dir->index = 0; +} /* * File I/O @@ -21,7 +135,16 @@ #define VG_FILE_IO_CHUNK_SIZE 1024*256 -VG_STATIC void vg_file_print_invalid( FILE *fp ) +#ifdef __GNUC__ + #ifndef __clang__ + #pragma GCC push_options + #pragma GCC optimize ("O3") + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #endif +#endif + +static void vg_file_print_invalid( FILE *fp ) { if( feof( fp )) { vg_error( "mdl_open: header too short\n" ); @@ -36,7 +159,7 @@ VG_STATIC void vg_file_print_invalid( FILE *fp ) } /* read entire binary file */ -VG_STATIC void *vg_file_read( void *lin_alloc, const char *path, u32 *size ) +static void *vg_file_read( void *lin_alloc, const char *path, u32 *size ) { FILE *f = fopen( path, "rb" ); if( f ){ @@ -71,7 +194,6 @@ VG_STATIC void *vg_file_read( void *lin_alloc, const char *path, u32 *size ) fclose( f ); *size = (u32)current; - return buffer; } else{ @@ -81,7 +203,7 @@ VG_STATIC void *vg_file_read( void *lin_alloc, const char *path, u32 *size ) } /* read entire file and append a null on the end */ -VG_STATIC char *vg_file_read_text( void *lin_alloc, const char *path, u32 *sz ) +static char *vg_file_read_text( void *lin_alloc, const char *path, u32 *sz ) { u32 size; char *str = vg_file_read( lin_alloc, path, &size ); @@ -98,7 +220,7 @@ VG_STATIC char *vg_file_read_text( void *lin_alloc, const char *path, u32 *sz ) } -VG_STATIC int vg_asset_write( const char *path, void *data, i64 size ){ +static int vg_asset_write( const char *path, void *data, i64 size ){ FILE *f = fopen( path, "wb" ); if( f ){ fwrite( data, size, 1, f ); @@ -110,4 +232,34 @@ VG_STATIC int vg_asset_write( const char *path, void *data, i64 size ){ } } +/* TODO: error handling if read fails */ +static int vg_file_copy( const char *src, const char *dst, void *lin_alloc ) +{ + vg_info( "vg_file_copy( %s -> %s )\n", src, dst ); + u32 size; + void *data = vg_file_read( lin_alloc, src, &size ); + return vg_asset_write( dst, data, size ); +} + +static const char *vg_path_filename( const char *path ) +{ + const char *base = path; + + for( int i=0; i<1024; i++ ){ + if( path[i] == '\0' ) break; + if( path[i] == '/' ){ + base = path+i+1; + } + } + + return base; +} + +#ifdef __GNUC__ + #ifndef __clang__ + #pragma GCC pop_options + #pragma GCC diagnostic pop + #endif +#endif + #endif /* VG_IO_H */