5#if !defined( DEBUG_THRESHOLD )
6# define DEBUG_THRESHOLD 1
9#ifndef UPRINTF_BUFFER_SZ_MAX
10# define UPRINTF_BUFFER_SZ_MAX 1024
13#if !defined( MAUG_NO_RETRO ) && !defined( DOCUMENTATION )
15 uint8_t flags,
const char* title,
const char* format, ... );
18#if !defined( MFILE_MMAP ) && \
19 !defined( RETROFLAT_API_WINCE ) && \
20 !defined( RETROFLAT_API_PALM ) && \
21 !defined( RETROFLAT_API_PSN )
39#ifndef MAUG_PATH_SZ_MAX
41# define MAUG_PATH_SZ_MAX 256
56#define MFILE_CADDY_TYPE_FILE 0x01
61#define MFILE_CADDY_TYPE_MEM_BUFFER 0x80
69#define MFILE_FLAG_READ_ONLY 0x01
77#define MFILE_FLAG_HANDLE_LOCKED 0x02
98#define MFILE_READ_FLAG_LSBF 0x01
105#define MFILE_READ_FLAG_MSBF 0x01
107#define MFILE_ASSIGN_FLAG_TRIM_EXT 0x01
109#ifndef MFILE_READ_TRACE_LVL
110# define MFILE_READ_TRACE_LVL 0
113#ifndef MFILE_WRITE_TRACE_LVL
114# define MFILE_WRITE_TRACE_LVL 0
117#ifndef MFILE_SEEK_TRACE_LVL
118# define MFILE_SEEK_TRACE_LVL 0
121#ifndef MFILE_CONTENTS_TRACE_LVL
122# define MFILE_CONTENTS_TRACE_LVL 0
146#define mfile_cmp_path( a, b ) strncmp( a, b, MAUG_PATH_SZ_MAX )
153typedef off_t (*mfile_cursor_t)(
struct MFILE_CADDY* p_file );
154typedef off_t (*mfile_has_bytes_t)(
struct MFILE_CADDY* p_file );
158 struct MFILE_CADDY* p_file, uint8_t* buf,
size_t buf_sz );
161 struct MFILE_CADDY* p_file, uint8_t* buf,
size_t buf_sz, uint8_t flags );
163 struct MFILE_CADDY* p_file,
char* buf, off_t buf_sz, uint8_t flags );
165 struct MFILE_CADDY* p_file, uint8_t flags,
const char* fmt, ... );
167 struct MFILE_CADDY* p_f,
const uint8_t* buf,
size_t buf_sz );
169off_t mfile_mem_cursor(
struct MFILE_CADDY* p_file );
170off_t mfile_mem_has_bytes(
struct MFILE_CADDY* p_file );
173 struct MFILE_CADDY* p_file, uint8_t* buf,
size_t buf_sz );
176 struct MFILE_CADDY* p_f,
char* buffer, off_t buffer_sz, uint8_t flags );
178 mfile_t* p_file, uint8_t flags,
const char* fmt, va_list args );
188 struct MFILE_CADDY* p_f,
const uint8_t* buf,
size_t buf_sz );
200 struct MFILE_CADDY* p_file, uint8_t flags,
const char* fmt, va_list args );
210 union MFILE_HANDLE
h;
220 mfile_has_bytes_t has_bytes;
221 mfile_cursor_t cursor;
222 mfile_read_byte_t read_byte;
223 mfile_read_block_t read_block;
225 mfile_read_int_t read_int;
226 mfile_read_line_t read_line;
227 mfile_printf_t printf;
229 mfile_write_block_t write_block;
248off_t mfile_file_has_bytes(
struct MFILE_CADDY* p_file );
253 struct MFILE_CADDY* p_file, uint8_t* buf,
size_t buf_sz );
256 struct MFILE_CADDY* p_f, uint8_t* buf,
size_t buf_sz, uint8_t flags );
261 struct MFILE_CADDY* p_f,
char* buffer, off_t buffer_sz, uint8_t flags );
264 struct MFILE_CADDY* p_f, uint8_t flags,
const char* fmt, ... );
267 struct MFILE_CADDY* p_f,
const uint8_t* buf,
size_t buf_sz );
270 struct MFILE_CADDY* p_f, uint8_t flags,
const char* fmt, va_list args );
272#define mfile_get_sz( p_file ) ((p_file)->sz)
278 MAUG_MHANDLE,
void* ptr, off_t,
mfile_t* p_file );
300off_t mfile_file_has_bytes(
struct MFILE_CADDY* p_file ) {
302 cursor = p_file->cursor( p_file );
303 if( p_file->
sz > cursor ) {
304#if MFILE_READ_TRACE_LVL > 0
305 debug_printf( MFILE_READ_TRACE_LVL,
306 "file has " OFF_T_FMT
" bytes left...",
307 p_file->
sz - cursor );
309 return p_file->
sz - cursor;
311#if MFILE_READ_TRACE_LVL > 0
313 debug_printf( MFILE_READ_TRACE_LVL,
"file has error bytes left!" );
325 char* ext_ptr = NULL;
330 if( MFILE_ASSIGN_FLAG_TRIM_EXT == (MFILE_ASSIGN_FLAG_TRIM_EXT & flags) ) {
331 ext_ptr = maug_strrchr( tgt,
'.' );
332 if( NULL != ext_ptr ) {
343 struct MFILE_CADDY* p_file, uint8_t* buf,
size_t buf_sz, uint8_t flags
350#elif defined( MAUG_MSBF )
354 debug_printf( MFILE_READ_TRACE_LVL,
"reading integer forward" );
356 retval = p_file->read_block( p_file, buf, buf_sz );
359 debug_printf( MFILE_READ_TRACE_LVL,
"reading integer reversed" );
361 while( 0 < buf_sz ) {
362 retval = p_file->read_byte( p_file, (buf + (buf_sz - 1)) );
363 maug_cleanup_if_not_ok();
376 struct MFILE_CADDY* p_file, uint8_t flags,
const char* fmt, ...
381 va_start( vargs, fmt );
382 retval = p_file->vprintf( p_file, flags, fmt, vargs );
390off_t mfile_mem_cursor(
struct MFILE_CADDY* p_file ) {
396off_t mfile_mem_has_bytes(
struct MFILE_CADDY* p_file ) {
411 if( (MAUG_MHANDLE)NULL != p_f->
h.mem ) {
422static void mfile_mem_release(
struct MFILE_CADDY* p_f ) {
428 p_f->flags &= ~MFILE_FLAG_HANDLE_LOCKED;
435 return p_file->read_block( p_file, buf, 1 );
441 struct MFILE_CADDY* p_file, uint8_t* buf,
size_t buf_sz
449 retval = mfile_mem_lock( p_file );
450 maug_cleanup_if_not_ok();
452 while( 0 < buf_sz-- ) {
458 mfile_mem_release( p_file );
472 debug_printf( MFILE_SEEK_TRACE_LVL,
473 "seeking memory buffer to position " OFF_T_FMT
" (" OFF_T_FMT
")",
482 struct MFILE_CADDY* p_f,
char* buffer, off_t buffer_sz, uint8_t flags
490 if( !p_f->has_bytes( p_f ) ) {
491 error_printf(
"file %s out of bytes!", p_f->filename );
492 retval = MERROR_FILE;
496 while( i < buffer_sz - 1 && p_f->has_bytes( p_f ) ) {
498 if( i + 1 >= buffer_sz ) {
499 error_printf(
"overflow reading string from file %s!", p_f->filename );
500 retval = MERROR_FILE;
504 retval = p_f->read_int( p_f, (uint8_t*)&(buffer[i]), 1, 0 );
505 maug_cleanup_if_not_ok();
506 if(
'\n' == buffer[i] ) {
513 assert( i < buffer_sz );
526 mfile_t* p_file, uint8_t flags,
const char* fmt, va_list args
535 error_printf(
"writing to memory buffer not currently supported!" );
547 struct MFILE_CADDY* p_f,
const uint8_t* buf,
size_t buf_sz
561 retval = mfile_mem_lock( p_f );
562 maug_cleanup_if_not_ok();
564#if MFILE_WRITE_TRACE_LVL > 0
565 debug_printf( MFILE_WRITE_TRACE_LVL,
"p: %p, sz: %u, cur: %u, buf_sz: %u\n",
586 mfile_mem_release( p_f );
594 MAUG_MHANDLE handle,
void* ptr, off_t handle_sz,
mfile_t* p_file
598 debug_printf( MFILE_SEEK_TRACE_LVL,
599 "locking handle %p as file %p (" OFF_T_FMT
" bytes)...",
600 handle, p_file, handle_sz );
602 maug_mzero( p_file,
sizeof(
struct MFILE_CADDY ) );
605 if( (MAUG_MHANDLE)NULL == handle && NULL != ptr ) {
607 }
else if( (MAUG_MHANDLE)NULL != handle && NULL == ptr ) {
608 p_file->
h.mem = handle;
611 error_printf(
"must specify handle or pointer!" );
612 retval = MERROR_FILE;
618 p_file->has_bytes = mfile_mem_has_bytes;
619 p_file->cursor = mfile_mem_cursor;
620 p_file->read_byte = mfile_mem_read_byte;
621 p_file->read_block = mfile_mem_read_block;
622 p_file->read_int = mfile_file_read_int;
623 p_file->seek = mfile_mem_seek;
624 p_file->read_line = mfile_mem_read_line;
627 p_file->
sz = handle_sz;
642 retval = mfile_plt_open_read( filename, p_file );
644 if( MERROR_OK == retval ) {
659 retval = mfile_plt_open_write( filename, p_file );
661 if( MERROR_OK == retval ) {
672# if MFILE_SEEK_TRACE_LVL > 0
673 debug_printf( MFILE_SEEK_TRACE_LVL,
"closing file..." );
676 munmap( bytes_ptr_h, bytes_sz );
679 switch( p_file->
type ) {
685 mfile_plt_close( p_file );
692 debug_printf( MFILE_SEEK_TRACE_LVL,
693 "unlocked handle %p from file %p...",
694 p_file->
h.mem, p_file );
700 error_printf(
"unknown file type: %d", (p_file)->
type );
uint16_t MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition: merror.h:28
#define MFILE_CADDY_TYPE_FILE
A standard UNIX file.
Definition: mfile.h:56
#define MFILE_CADDY_TYPE_MEM_BUFFER
An array of bytes in memory abstracted through this library.
Definition: mfile.h:61
MERROR_RETVAL mfile_open_read(const maug_path filename, mfile_t *p_file)
Open a file and read it into memory or memory-map it.
MERROR_RETVAL mfile_lock_buffer(MAUG_MHANDLE, void *ptr, off_t, mfile_t *p_file)
Lock a buffer and assign it to an ::mfile_t to read/write.
#define MAUG_PATH_SZ_MAX
Maximum size allocated for asset paths.
Definition: mfile.h:41
#define MFILE_READ_FLAG_MSBF
Flag for mfile_read_int_t() indicating integer should always be read most significant byte first.
Definition: mfile.h:105
MERROR_RETVAL(* mfile_vprintf_t)(struct MFILE_CADDY *p_file, uint8_t flags, const char *fmt, va_list args)
Callback to printf the given format string, replacing tokens from the providied pre-initialized list ...
Definition: mfile.h:199
#define MFILE_READ_FLAG_LSBF
Flag for mfile_read_int_t() indicating integer should always be read least significant byte first.
Definition: mfile.h:98
MERROR_RETVAL mfile_mem_write_block(struct MFILE_CADDY *p_f, const uint8_t *buf, size_t buf_sz)
Insert provided buffer into the given file.
void mfile_close(mfile_t *p_file)
Close a file opened with mfile_open_read().
MERROR_RETVAL mfile_assign_path(maug_path tgt, const maug_path src, uint8_t flags)
Copy a maug_path from one place to another, safely observing character limits, etc.
char maug_path[MAUG_PATH_SZ_MAX]
Path/name used to load an asset from disk or access other files.
Definition: mfile.h:141
void retroflat_message(uint8_t flags, const char *title, const char *format,...)
Display a message in a dialog box and/or on stderr.
off_t mem_cursor
Current position if its type is MFILE_CADDY_TYPE_MEM_BUFFER.
Definition: mfile.h:213
#define MFILE_FLAG_HANDLE_LOCKED
Flag for MFILE_CADDY::flags indicating subsequent internal unlocks should unlock the handle back to i...
Definition: mfile.h:77
uint8_t type
The RetroFile Types flag describing this file.
Definition: mfile.h:208
union MFILE_HANDLE h
The physical handle or pointer to access the file by.
Definition: mfile.h:210
uint8_t * mem_buffer
Locked pointer for MFILE_HANDLE::mem.
Definition: mfile.h:215
#define MFILE_FLAG_READ_ONLY
Flag for MFILE_CADDY::flags indicating this file is read-only.
Definition: mfile.h:69
off_t sz
Size of the current file/buffer in bytes.
Definition: mfile.h:218