Various things but also major error
[vg.git] / vg_io.h
1 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
2
3 #ifndef VG_IO_H
4 #define VG_IO_H
5
6 #include "vg_stdint.h"
7 #include "vg_platform.h"
8 #include "vg_log.h"
9 #include "vg_mem.h"
10 #include <stdio.h>
11 #include <errno.h>
12
13
14 #define _TINYDIR_MALLOC(_size) vg_linear_alloc( vg_mem.scratch, _size )
15 #define _TINYDIR_FREE(_size)
16
17 #include "submodules/tinydir/tinydir.h"
18 #include <sys/stat.h>
19
20 /*
21 * Create directory and silently ignore errors for already exists
22 */
23 VG_STATIC int vg_mkdir( const char *path )
24 {
25 if( mkdir( path, S_IRWXU|S_IRWXG|S_IWOTH|S_IXOTH ) ){
26 if( errno == EEXIST )
27 return 1;
28
29 vg_error( "Failed to create directory: %s\n", path );
30 return 0;
31 }
32 else{
33 return 1;
34 }
35 }
36
37 /*
38 * File I/O
39 */
40
41 #define VG_FILE_IO_CHUNK_SIZE 1024*256
42
43 VG_STATIC void vg_file_print_invalid( FILE *fp )
44 {
45 if( feof( fp )) {
46 vg_error( "mdl_open: header too short\n" );
47 }
48 else{
49 if( ferror( fp ))
50 vg_error( "mdl_open: %s\n", strerror(errno) );
51 else
52 vg_error( "mdl_open: unkown failure\n" );
53
54 }
55 }
56
57 /* read entire binary file */
58 VG_STATIC void *vg_file_read( void *lin_alloc, const char *path, u32 *size )
59 {
60 FILE *f = fopen( path, "rb" );
61 if( f ){
62 void *buffer = vg_linear_alloc( lin_alloc, 0 );
63 u64 current = 0;
64
65 /* read in chunks */
66 for( u32 i=0; 1; i++ ){
67 buffer = vg_linear_extend( lin_alloc, buffer, VG_FILE_IO_CHUNK_SIZE );
68
69 u64 l = fread( buffer + current, 1, VG_FILE_IO_CHUNK_SIZE, f );
70 current += l;
71
72 if( l != VG_FILE_IO_CHUNK_SIZE ){
73 if( feof( f ) ){
74 break;
75 }
76 else{
77 if( ferror( f ) ){
78 fclose(f);
79 vg_fatal_error( "read error" );
80 }
81 else{
82 fclose(f);
83 vg_fatal_error( "unknown error codition" );
84 }
85 }
86 }
87 }
88
89 buffer = vg_linear_resize( lin_alloc, buffer, vg_align8(current) );
90 fclose( f );
91
92 *size = (u32)current;
93 return buffer;
94 }
95 else{
96 vg_error( "vg_disk_open_read: %s\n", strerror(errno) );
97 return NULL;
98 }
99 }
100
101 /* read entire file and append a null on the end */
102 VG_STATIC char *vg_file_read_text( void *lin_alloc, const char *path, u32 *sz )
103 {
104 u32 size;
105 char *str = vg_file_read( lin_alloc, path, &size );
106
107 if( !str )
108 return NULL;
109
110 /* include null terminator */
111 str = vg_linear_extend( lin_alloc, str, 1 );
112 str[ size ] = '\0';
113 *sz = size+1;
114
115 return str;
116 }
117
118
119 VG_STATIC int vg_asset_write( const char *path, void *data, i64 size ){
120 FILE *f = fopen( path, "wb" );
121 if( f ){
122 fwrite( data, size, 1, f );
123 fclose( f );
124 return 1;
125 }
126 else{
127 return 0;
128 }
129 }
130
131 /* TODO: error handling if read fails */
132 VG_STATIC int vg_file_copy( const char *src, const char *dst, void *lin_alloc )
133 {
134 vg_info( "vg_file_copy( %s -> %s )\n", src, dst );
135 u32 size;
136 void *data = vg_file_read( lin_alloc, src, &size );
137 return vg_asset_write( dst, data, size );
138 }
139
140 VG_STATIC const char *vg_path_filename( const char *path )
141 {
142 const char *base = path;
143
144 for( int i=0; i<1024; i++ ){
145 if( path[i] == '\0' ) break;
146 if( path[i] == '/' ){
147 base = path+i+1;
148 }
149 }
150
151 return base;
152 }
153
154 #endif /* VG_IO_H */