-/* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
+/* Copyright (C) 2021-2024 Harry Godden (hgn) - All Rights Reserved */
-#ifndef VG_IO_H
-#define VG_IO_H
-
-#include "vg.h"
-#include "vg_stdint.h"
+#pragma once
#include "vg_platform.h"
#include "vg_log.h"
#include "vg_mem.h"
-
typedef struct vg_dir vg_dir;
#ifndef _WIN32
#include <dirent.h>
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;
-}
+int vg_dir_open( vg_dir *dir, const char *name );
+const char *vg_dir_entry_name( vg_dir *dir );
+int vg_dirskip( vg_dir *dir );
+int vg_dir_next_entry( vg_dir *dir );
+enum vg_entry_type vg_dir_entry_type( vg_dir *dir );
+void vg_dir_close( vg_dir *dir );
+void vg_file_print_invalid( FILE *fp );
/*
* File I/O
*/
-#define VG_FILE_IO_CHUNK_SIZE 1024*256
-
-#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" );
- }
- else{
- if( ferror( fp ))
- vg_error( "mdl_open: %s\n", strerror(errno) );
- else
- vg_error( "mdl_open: unkown failure\n" );
-
- }
-}
-
/* read entire binary file */
-static void *vg_file_read( void *lin_alloc, const char *path, u32 *size ){
- FILE *f = fopen( path, "rb" );
- if( f ){
- void *buffer = lin_alloc? vg_linear_alloc( lin_alloc, 0 ):
- NULL;
- u64 current = 0;
-
- /* read in chunks */
- for( u32 i=0; 1; i++ ){
- if( lin_alloc )
- buffer = vg_linear_extend( lin_alloc,buffer,VG_FILE_IO_CHUNK_SIZE );
- else
- buffer = realloc( buffer, current + VG_FILE_IO_CHUNK_SIZE );
-
- u64 l = fread( buffer + current, 1, VG_FILE_IO_CHUNK_SIZE, f );
- current += l;
-
- if( l != VG_FILE_IO_CHUNK_SIZE ){
- if( feof( f ) ){
- break;
- }
- else{
- if( ferror( f ) ){
- fclose(f);
- vg_fatal_error( "read error" );
- }
- else{
- fclose(f);
- vg_fatal_error( "unknown error codition" );
- }
- }
- }
- }
-
- if( lin_alloc )
- buffer = vg_linear_resize( lin_alloc, buffer, vg_align8(current) );
- else
- buffer = realloc( buffer, vg_align8(current) );
-
- fclose( f );
-
- *size = (u32)current;
- return buffer;
- }
- else{
- vg_error( "vg_disk_open_read: %s (file: %s)\n", strerror(errno), path );
- return NULL;
- }
-}
+void *vg_file_read( void *lin_alloc, const char *path, u32 *size );
/* read entire file and append a null on the end */
-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 );
-
- if( !str )
- return NULL;
-
- /* include null terminator */
- if( lin_alloc )
- str = vg_linear_extend( lin_alloc, str, 1 );
- else
- str = realloc( str, size+1 );
-
- str[ size ] = '\0';
- *sz = size+1;
-
- return str;
-}
-
-
-static int vg_asset_write( const char *path, void *data, i64 size ){
- FILE *f = fopen( path, "wb" );
- if( f ){
- fwrite( data, size, 1, f );
- fclose( f );
- return 1;
- }
- else{
- return 0;
- }
-}
-
-/* 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
+char *vg_file_read_text( void *lin_alloc, const char *path, u32 *sz );
-#endif /* VG_IO_H */
+int vg_asset_write( const char *path, void *data, i64 size );
+int vg_file_copy( const char *src, const char *dst, void *lin_alloc );
+const char *vg_path_filename( const char *path );