i32r, q_dist fix
[vg.git] / vg_io.h
diff --git a/vg_io.h b/vg_io.h
index 640ceaea12dd0397320c9cb143f1527b02641460..87562ace408a919ba0d02afdc4c0262ac3e64893 100644 (file)
--- a/vg_io.h
+++ b/vg_io.h
 #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 <stdio.h>
-#include <errno.h>
 
 
-#define _TINYDIR_MALLOC(_size) vg_linear_alloc( vg_mem.scratch, _size )
-#define _TINYDIR_FREE(_size) 
+typedef struct vg_dir vg_dir;
+#ifndef _WIN32
+ #include <dirent.h>
+ struct vg_dir{
+   DIR *h;
+   struct dirent *data;
+   u32 index;
+ };
+#else
+ #include <windows.h>
+ #include <fileapi.h>
+ struct vg_dir{
+   HANDLE h;
+   WIN32_FIND_DATA data;
+   u32 index;
+ };
+#endif
 
-#include "submodules/tinydir/tinydir.h"
+enum vg_entry_type{
+   k_vg_entry_type_unknown,
+   k_vg_entry_type_file,
+   k_vg_entry_type_dir
+};
 
-#include <sys/stat.h>
-VG_STATIC int vg_mkdir( const char *path )
-{
-   if( mkdir( path, S_IRWXU|S_IRWXG|S_IWOTH|S_IXOTH ) ){
-      vg_error( "Failed to create directory: %s\n", path );
-      return 0;
+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{
-      return 1;
+#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;
 }
 
 /*
@@ -34,7 +135,16 @@ VG_STATIC int vg_mkdir( const char *path )
 
 #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" );
@@ -49,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 ){
@@ -93,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 );
@@ -110,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 );
@@ -123,7 +233,7 @@ VG_STATIC int vg_asset_write( const char *path, void *data, i64 size ){
 }
 
 /* TODO: error handling if read fails */
-VG_STATIC int vg_file_copy( const char *src, const char *dst, void *lin_alloc )
+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;
@@ -131,7 +241,7 @@ VG_STATIC int vg_file_copy( const char *src, const char *dst, void *lin_alloc )
    return vg_asset_write( dst, data, size );
 }
 
-VG_STATIC const char *vg_path_filename( const char *path )
+static const char *vg_path_filename( const char *path )
 {
    const char *base = path;
    
@@ -145,4 +255,11 @@ VG_STATIC const char *vg_path_filename( const char *path )
    return base;
 }
 
+#ifdef __GNUC__
+  #ifndef __clang__
+    #pragma GCC pop_options
+    #pragma GCC diagnostic pop 
+  #endif
+#endif
+
 #endif /* VG_IO_H */