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