1 /* Copyright (C) 2021-2024 Harry Godden (hgn) - All Rights Reserved */
4 #include "vg_platform.h"
10 int vg_dir_open( vg_dir
*dir
, const char *name
)
15 vg_strnull( &q
, q_buf
, 4096 );
16 vg_strcat( &q
, name
);
17 vg_strcat( &q
, "/*" );
18 if( !vg_strgood(&q
) ) return 0;
20 vg_info( "FindFirstFile( '%s' )\n", q
.buffer
);
21 dir
->h
= FindFirstFile( q
.buffer
, &dir
->data
);
22 if( dir
->h
== INVALID_HANDLE_VALUE
){
23 if( GetLastError() == ERROR_FILE_NOT_FOUND
){
30 dir
->h
= opendir( name
);
31 if( !dir
->h
) return 0;
37 const char *vg_dir_entry_name( vg_dir
*dir
)
40 return dir
->data
.cFileName
;
42 return dir
->data
->d_name
;
46 int vg_dirskip( vg_dir
*dir
)
48 const char *s
= vg_dir_entry_name(dir
);
50 if( dir
->data
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) return 1;
53 if( s
[1] == '\0' ) return 1;
54 else if( s
[1] == '.' ){
55 if( s
[2] == '\0' ) return 1;
61 int vg_dir_next_entry( vg_dir
*dir
)
64 if( dir
->index
== 0 ) return 0;
65 if( dir
->index
> 1 ) {
67 if( !FindNextFile( dir
->h
, &dir
->data
) ) return 0;
69 while( vg_dirskip(dir
) ){
71 if( !FindNextFile( dir
->h
, &dir
->data
) ) return 0;
73 if( dir
->index
== 1 ) dir
->index
++;
76 while( (dir
->data
= readdir(dir
->h
)) ){
78 if( !vg_dirskip(dir
) ) break;
80 if( dir
->data
) return 1;
85 enum vg_entry_type
vg_dir_entry_type( vg_dir
*dir
)
88 if( dir
->data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
89 return k_vg_entry_type_dir
;
90 return k_vg_entry_type_file
; /* sketchy? */
92 if( dir
->data
->d_type
== DT_DIR
) return k_vg_entry_type_dir
;
93 if( dir
->data
->d_type
== DT_REG
) return k_vg_entry_type_file
;
98 void vg_dir_close( vg_dir
*dir
)
101 if( dir
->index
) FindClose( dir
->h
);
102 dir
->h
= INVALID_HANDLE_VALUE
;
111 void vg_file_print_invalid( FILE *fp
)
114 vg_error( "mdl_open: header too short\n" );
118 vg_error( "mdl_open: %s\n", strerror(errno
) );
120 vg_error( "mdl_open: unkown failure\n" );
125 #define VG_FILE_IO_CHUNK_SIZE 1024*256
127 /* read entire binary file */
128 void *vg_file_read( void *lin_alloc
, const char *path
, u32
*size
)
130 FILE *f
= fopen( path
, "rb" );
132 void *buffer
= lin_alloc
? vg_linear_alloc( lin_alloc
, 0 ):
137 for( u32 i
=0; 1; i
++ ){
139 buffer
= vg_linear_extend( lin_alloc
,buffer
,VG_FILE_IO_CHUNK_SIZE
);
141 buffer
= realloc( buffer
, current
+ VG_FILE_IO_CHUNK_SIZE
);
143 u64 l
= fread( buffer
+ current
, 1, VG_FILE_IO_CHUNK_SIZE
, f
);
146 if( l
!= VG_FILE_IO_CHUNK_SIZE
){
153 vg_fatal_error( "read error" );
157 vg_fatal_error( "unknown error codition" );
164 buffer
= vg_linear_resize( lin_alloc
, buffer
, vg_align8(current
) );
166 buffer
= realloc( buffer
, vg_align8(current
) );
170 *size
= (u32
)current
;
174 vg_error( "vg_disk_open_read: %s (file: %s)\n", strerror(errno
), path
);
179 /* read entire file and append a null on the end */
180 char *vg_file_read_text( void *lin_alloc
, const char *path
, u32
*sz
)
183 char *str
= vg_file_read( lin_alloc
, path
, &size
);
188 /* include null terminator */
190 str
= vg_linear_extend( lin_alloc
, str
, 1 );
192 str
= realloc( str
, size
+1 );
201 int vg_asset_write( const char *path
, void *data
, i64 size
)
203 FILE *f
= fopen( path
, "wb" );
205 fwrite( data
, size
, 1, f
);
214 /* TODO: error handling if read fails */
215 int vg_file_copy( const char *src
, const char *dst
, void *lin_alloc
)
217 vg_info( "vg_file_copy( %s -> %s )\n", src
, dst
);
219 void *data
= vg_file_read( lin_alloc
, src
, &size
);
220 return vg_asset_write( dst
, data
, size
);
223 const char *vg_path_filename( const char *path
)
225 const char *base
= path
;
227 for( int i
=0; i
<1024; i
++ ){
228 if( path
[i
] == '\0' ) break;
229 if( path
[i
] == '/' ){