e39c15fa5975b6103e791cb56b41991016c252b6
1 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
8 #include "vg_platform.h"
13 typedef struct vg_dir vg_dir
;
32 k_vg_entry_type_unknown
,
37 static int vg_dir_open( vg_dir
*dir
, const char *name
){
41 vg_strnull( &q
, q_buf
, 4096 );
42 vg_strcat( &q
, name
);
43 vg_strcat( &q
, "/*" );
44 if( !vg_strgood(&q
) ) return 0;
46 vg_info( "FindFirstFile( '%s' )\n", q
.buffer
);
47 dir
->h
= FindFirstFile( q
.buffer
, &dir
->data
);
48 if( dir
->h
== INVALID_HANDLE_VALUE
){
49 if( GetLastError() == ERROR_FILE_NOT_FOUND
){
56 dir
->h
= opendir( name
);
57 if( !dir
->h
) return 0;
63 static const char *vg_dir_entry_name( vg_dir
*dir
){
65 return dir
->data
.cFileName
;
67 return dir
->data
->d_name
;
71 static int vg_dirskip( vg_dir
*dir
){
72 const char *s
= vg_dir_entry_name(dir
);
74 if( dir
->data
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
) return 1;
77 if( s
[1] == '\0' ) return 1;
78 else if( s
[1] == '.' ){
79 if( s
[2] == '\0' ) return 1;
85 static int vg_dir_next_entry( vg_dir
*dir
){
87 if( dir
->index
== 0 ) return 0;
88 if( dir
->index
> 1 ) {
90 if( !FindNextFile( dir
->h
, &dir
->data
) ) return 0;
92 while( vg_dirskip(dir
) ){
94 if( !FindNextFile( dir
->h
, &dir
->data
) ) return 0;
96 if( dir
->index
== 1 ) dir
->index
++;
99 while( (dir
->data
= readdir(dir
->h
)) ){
101 if( !vg_dirskip(dir
) ) break;
103 if( dir
->data
) return 1;
108 static enum vg_entry_type
vg_dir_entry_type( vg_dir
*dir
){
110 if( dir
->data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
111 return k_vg_entry_type_dir
;
112 return k_vg_entry_type_file
; /* sketchy? */
114 if( dir
->data
->d_type
== DT_DIR
) return k_vg_entry_type_dir
;
115 if( dir
->data
->d_type
== DT_REG
) return k_vg_entry_type_file
;
120 static void vg_dir_close( vg_dir
*dir
){
122 if( dir
->index
) FindClose( dir
->h
);
123 dir
->h
= INVALID_HANDLE_VALUE
;
136 #define VG_FILE_IO_CHUNK_SIZE 1024*256
140 #pragma GCC push_options
141 #pragma GCC optimize ("O3")
142 #pragma GCC diagnostic push
143 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
147 static void vg_file_print_invalid( FILE *fp
)
150 vg_error( "mdl_open: header too short\n" );
154 vg_error( "mdl_open: %s\n", strerror(errno
) );
156 vg_error( "mdl_open: unkown failure\n" );
161 /* read entire binary file */
162 static void *vg_file_read( void *lin_alloc
, const char *path
, u32
*size
){
163 FILE *f
= fopen( path
, "rb" );
165 void *buffer
= lin_alloc
? vg_linear_alloc( lin_alloc
, 0 ):
170 for( u32 i
=0; 1; i
++ ){
172 buffer
= vg_linear_extend( lin_alloc
,buffer
,VG_FILE_IO_CHUNK_SIZE
);
174 buffer
= realloc( buffer
, current
+ VG_FILE_IO_CHUNK_SIZE
);
176 u64 l
= fread( buffer
+ current
, 1, VG_FILE_IO_CHUNK_SIZE
, f
);
179 if( l
!= VG_FILE_IO_CHUNK_SIZE
){
186 vg_fatal_error( "read error" );
190 vg_fatal_error( "unknown error codition" );
197 buffer
= vg_linear_resize( lin_alloc
, buffer
, vg_align8(current
) );
199 buffer
= realloc( buffer
, vg_align8(current
) );
203 *size
= (u32
)current
;
207 vg_error( "vg_disk_open_read: %s (file: %s)\n", strerror(errno
), path
);
212 /* read entire file and append a null on the end */
213 static char *vg_file_read_text( void *lin_alloc
, const char *path
, u32
*sz
){
215 char *str
= vg_file_read( lin_alloc
, path
, &size
);
220 /* include null terminator */
222 str
= vg_linear_extend( lin_alloc
, str
, 1 );
224 str
= realloc( str
, size
+1 );
233 static int vg_asset_write( const char *path
, void *data
, i64 size
){
234 FILE *f
= fopen( path
, "wb" );
236 fwrite( data
, size
, 1, f
);
245 /* TODO: error handling if read fails */
246 static int vg_file_copy( const char *src
, const char *dst
, void *lin_alloc
)
248 vg_info( "vg_file_copy( %s -> %s )\n", src
, dst
);
250 void *data
= vg_file_read( lin_alloc
, src
, &size
);
251 return vg_asset_write( dst
, data
, size
);
254 static const char *vg_path_filename( const char *path
)
256 const char *base
= path
;
258 for( int i
=0; i
<1024; i
++ ){
259 if( path
[i
] == '\0' ) break;
260 if( path
[i
] == '/' ){
270 #pragma GCC pop_options
271 #pragma GCC diagnostic pop