model view prototype
[convexer.git] / cxr / cxr_io.h
diff --git a/cxr/cxr_io.h b/cxr/cxr_io.h
new file mode 100644 (file)
index 0000000..ed28bb8
--- /dev/null
@@ -0,0 +1,215 @@
+#ifndef CXR_IO_H
+#define CXR_IO_H
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "cxr_types.h"
+
+/* Read binary or text assets in full from file */
+static void *cxr_asset_read_s( const char *path, i64 *size );
+static void *cxr_asset_read( const char *path );
+static char *cxr_textasset_read_s( const char *path, i64 *size );
+static char *cxr_textasset_read( const char *name );
+
+static i64 cxr_file_size( FILE *fileptr );
+
+/* Path utilities */
+/* Returns pointer to the extension in path */
+static char *cxr_findext( char *path, char const delim );
+static char *cxr_findsep( char *path );
+
+static void cxr_stripext( char *path );
+static int cxr_path_is_abs( char const *path );
+static char *cxr_filename( char *path );
+
+/* Remove one level (nop if can't) eg: /home/harry/test.file -> /home/harry/ */
+static void cxr_downlvl( char *path );
+
+#ifdef _WIN32
+ #define CXR_FOLDER_CHAR '\\'
+#else
+ #define CXR_FOLDER_CHAR '/'
+#endif
+
+static i64 cxr_file_size( FILE *fileptr )
+{
+       fseek( fileptr, 0, SEEK_END );
+       i64 fsize = ftell( fileptr );
+       fseek( fileptr, 0, SEEK_SET );
+       
+       return fsize;
+}
+
+static void *fs_disk_open_read( const char *path, int reserve_end, i64 *size )
+{
+       FILE *f = fopen( path, "rb" );
+       if( f )
+       {
+               i64 fsize = cxr_file_size( f );
+               void *buf = malloc( fsize + reserve_end );
+               
+               if( buf )
+               {
+                       if( fread( buf, 1, fsize, f ) != fsize )
+                       {
+                               free( buf );
+                               buf = NULL;
+                       }
+               }
+               
+               *size = fsize;
+               
+               fclose( f );
+               return buf;
+       }
+       else
+       {
+               return NULL;
+       }
+}
+
+static char *fs_disk_load_text( const char *path, i64 *size )
+{
+       char *buf;
+       i64 fsize;
+       
+       if( (buf = fs_disk_open_read( path, 1, &fsize )) )
+       {
+               buf[ fsize ] = 0x00;
+               *size = fsize +1;
+               
+               return buf;
+       }
+
+       return NULL;
+}
+
+static void *cxr_asset_read_s( const char *path, i64 *size )
+{
+       return fs_disk_open_read( path, 0, size );
+}
+
+static void *cxr_asset_read( const char *path )
+{
+       i64 size;
+       return fs_disk_open_read( path, 0, &size );
+}
+
+static char *cxr_textasset_read_s( const char *path, i64 *size )
+{
+       return fs_disk_load_text( path, size );
+}
+
+static char *cxr_textasset_read( const char *name )
+{
+       i64 size;
+       return fs_disk_load_text( name, &size );
+}
+
+static char *cxr_findext( char *path, char const delim )
+{
+       char *c, *ptr;
+
+       c = path;
+       ptr = NULL;
+       
+       while( *c )
+       {
+               if( *c == delim )
+               {
+                       ptr = c + 1;
+               }
+       
+               c ++;
+       }
+
+       return ptr;
+}
+
+static char *cxr_findsep( char *path )
+{
+       char *c, *ptr;
+
+       c = path;
+       ptr = NULL;
+       
+       while( *c )
+       {
+               if( *c == '/' || *c == '\\' )
+               {
+                       ptr = c + 1;
+               }
+       
+               c ++;
+       }
+
+       return ptr;
+}
+
+static void cxr_stripext( char *path )
+{
+       char *point, *start;
+       
+       // Skip folders
+       if( !(start = cxr_findsep( path )) )
+       {
+               start = path;
+       }
+       
+       if( (point = cxr_findext( start, '.' )) )
+       {
+               if( point > path )
+               {
+                       *(point-1) = 0x00;
+               }
+       }
+}
+
+static void cxr_downlvl( char *path )
+{
+       char *start_name, *c;
+
+       c = path;
+       while( *c )
+               c ++;
+       int len = c - path;
+       
+       if( len )
+               path[ len -1 ] = 0x00;
+       
+       if( (start_name = cxr_findsep( path ) ))
+               *start_name = 0x00;
+       else
+               path[0] = 0x00;
+}
+
+static char *cxr_filename( char *path )
+{
+       char *base_name;
+       if( (base_name = cxr_findsep( path ) ))
+               return base_name;
+               
+       return path;
+}
+
+static int cxr_path_is_abs( char const *path )
+{
+#ifdef _WIN32
+       if( strlen( path ) < 2 ) return 0;
+       return path[1] == ':';
+#else
+       if( strlen( path ) < 1 ) return 0;
+       return path[0] == '/';
+#endif
+}
+
+static char *cxr_str_clone( char const *str, int extra )
+{
+   char *newstr = malloc(strlen(str)+1+extra);
+   strcpy( newstr, str );
+
+   return newstr;
+}
+
+#endif /* CXR_IO_H */