06aee757179ca82c525c8c9c3f49368603351a5e
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
138 VG_STATIC
void vg_file_print_invalid( FILE *fp
)
141 vg_error( "mdl_open: header too short\n" );
145 vg_error( "mdl_open: %s\n", strerror(errno
) );
147 vg_error( "mdl_open: unkown failure\n" );
152 /* read entire binary file */
153 VG_STATIC
void *vg_file_read( void *lin_alloc
, const char *path
, u32
*size
)
155 FILE *f
= fopen( path
, "rb" );
157 void *buffer
= vg_linear_alloc( lin_alloc
, 0 );
161 for( u32 i
=0; 1; i
++ ){
162 buffer
= vg_linear_extend( lin_alloc
, buffer
, VG_FILE_IO_CHUNK_SIZE
);
164 u64 l
= fread( buffer
+ current
, 1, VG_FILE_IO_CHUNK_SIZE
, f
);
167 if( l
!= VG_FILE_IO_CHUNK_SIZE
){
174 vg_fatal_error( "read error" );
178 vg_fatal_error( "unknown error codition" );
184 buffer
= vg_linear_resize( lin_alloc
, buffer
, vg_align8(current
) );
187 *size
= (u32
)current
;
191 vg_error( "vg_disk_open_read: %s\n", strerror(errno
) );
196 /* read entire file and append a null on the end */
197 VG_STATIC
char *vg_file_read_text( void *lin_alloc
, const char *path
, u32
*sz
)
200 char *str
= vg_file_read( lin_alloc
, path
, &size
);
205 /* include null terminator */
206 str
= vg_linear_extend( lin_alloc
, str
, 1 );
214 VG_STATIC
int vg_asset_write( const char *path
, void *data
, i64 size
){
215 FILE *f
= fopen( path
, "wb" );
217 fwrite( data
, size
, 1, f
);
226 /* TODO: error handling if read fails */
227 VG_STATIC
int vg_file_copy( const char *src
, const char *dst
, void *lin_alloc
)
229 vg_info( "vg_file_copy( %s -> %s )\n", src
, dst
);
231 void *data
= vg_file_read( lin_alloc
, src
, &size
);
232 return vg_asset_write( dst
, data
, size
);
235 VG_STATIC
const char *vg_path_filename( const char *path
)
237 const char *base
= path
;
239 for( int i
=0; i
<1024; i
++ ){
240 if( path
[i
] == '\0' ) break;
241 if( path
[i
] == '/' ){