From 5bba108949ed1f97b18f1ea732553da369e8beb0 Mon Sep 17 00:00:00 2001 From: inmarket Date: Wed, 29 Jan 2014 00:37:16 +1000 Subject: [PATCH] More GFile code --- include/gfile/gfile.h | 68 ++--- include/gfile/options.h | 47 +++- src/gfile/gfile.c | 522 +++++++++++++++++++++++++++++++++------ src/gfile/inc_nativefs.c | 14 +- src/gfile/inc_romfs.c | 2 +- 5 files changed, 530 insertions(+), 123 deletions(-) diff --git a/include/gfile/gfile.h b/include/gfile/gfile.h index 5b49a6b3..bc476956 100644 --- a/include/gfile/gfile.h +++ b/include/gfile/gfile.h @@ -45,7 +45,6 @@ typedef struct GFILE { #define GFILEFLG_MUSTEXIST 0x0100 // On open file must exist #define GFILEFLG_MUSTNOTEXIST 0x0200 // On open file must not exist #define GFILEFLG_TRUNC 0x0400 // On open truncate the file - short err; void * obj; long int pos; } GFILE; @@ -58,6 +57,7 @@ typedef struct GFILEVMT { #define GFSFLG_SEEKABLE 0x0004 #define GFSFLG_FAST 0x0010 #define GFSFLG_SMALL 0x0020 + #define GFSFLG_TEXTMODES 0x0040 char prefix; bool_t del(const char *fname); bool_t exists(const char *fname); @@ -66,7 +66,7 @@ typedef struct GFILEVMT { bool_t open(GFILE *f, const char *fname); void close(GFILE *f); int read(GFILE *f, char *buf, int size); - int write(GFILE *f, char *buf, int size); + int write(GFILE *f, const char *buf, int size); bool_t setpos(GFILE *f, long int pos); long int getsize(GFILE *f); bool_t eof(GFILE *f); @@ -112,37 +112,46 @@ extern GFILE *gfileStdOut; extern "C" { #endif - bool_t gfileExists(const char *fname); - bool_t gfileDelete(const char *fname); - long int gfileGetFilesize(const char *fname); - bool_t gfileRename(const char *oldname, const char *newname); - GFILE *gfileOpen(const char *fname, const char *mode); - void gfileClose(GFILE *f); - size_t gfileRead(GFILE *f, char *buf, size_t len); - size_t gfileWrite(GFILE *f, const char *buf, size_t len); + bool_t gfileExists(const char *fname); + bool_t gfileDelete(const char *fname); + long int gfileGetFilesize(const char *fname); + bool_t gfileRename(const char *oldname, const char *newname); + GFILE * gfileOpen(const char *fname, const char *mode); + void gfileClose(GFILE *f); + size_t gfileRead(GFILE *f, char *buf, size_t len); + size_t gfileWrite(GFILE *f, const char *buf, size_t len); long int gfileGetPos(GFILE *f); - bool_t gfileSetPos(GFILE *f, long int pos); + bool_t gfileSetPos(GFILE *f, long int pos); long int gfileGetSize(GFILE *f); + bool_t gfileEOF(GFILE *f); - int vfnprintg(GFILE *f, size_t maxlen, const char *fmt, va_list arg); - int fnprintg(GFILE *f, size_t maxlen, const char *fmt, ...); - #define vfprintg(f,m,a) vfnprintg(f,0,m,a) - #define fprintg(f,m,...) fnprintg(f,0,m,...) - #define vprintg(m,a) vfnprintg(gfileStdOut,0,m,a) - #define printg(m,...) fnprintg(gfileStdOut,0,m,...) + #if GFILE_NEED_PRINTG + int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg); + int fnprintg(GFILE *f, int maxlen, const char *fmt, ...); + #define vfprintg(f,m,a) vfnprintg(f,0,m,a) + #define fprintg(f,m,...) fnprintg(f,0,m,...) + #define vprintg(m,a) vfnprintg(gfileStdOut,0,m,a) + #define printg(m,...) fnprintg(gfileStdOut,0,m,...) + + #if GFILE_NEED_STRINGS + int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg); + int snprintg(char *buf, int maxlen, const char *fmt, ...); + #define vsprintg(s,m,a) vsnprintg(s,0,m,a) + #define sprintg(s,m,...) snprintg(s,0,m,...) + #endif + #endif - int vsnprintg(char *buf, size_t maxlen, const char *fmt, va_list arg); - int snprintg(char *buf, size_t maxlen, const char *fmt, ...); - #define vsprintg(s,m,a) vsnprintg(s,0,m,a) - #define sprintg(s,m,...) snprintg(s,0,m,...) #if GFILE_NEED_STDIO && !defined(GFILE_IMPLEMENTATION) #define FILE GFILE #define fopen(n,m) gfileOpen(n,m) #define fclose(f) gfileClose(f) - size_t fread(void * ptr, size_t size, size_t count, FILE *f); - size_t fwrite(const void * ptr, size_t size, size_t count, FILE *f); - int fseek(FILE *f, size_t offset, int origin); + size_t gstdioRead(void * ptr, size_t size, size_t count, FILE *f); + size_t gstdioWrite(const void * ptr, size_t size, size_t count, FILE *f); + #define fread(p,sz,cnt,f) gstdioRead(p,sz,cnt,f) + #define fwrite(p,sz,cnt,f) gstdioWrite(p,sz,cnt,f) + int gstdioSeek(FILE *f, size_t offset, int origin); + #define fseek(f,ofs,org) gstdioSeek(f,ofs,org) #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 @@ -150,13 +159,14 @@ extern "C" { #define rename(o,n) (!gfileRename(o,n)) #define fflush(f) (0) #define ftell(f) gfileGetPos(f) - typedef long int fpos_t; - int fgetpos(FILE *f, fpos_t *pos); + #define fpos_t long int + int gstdioGetpos(FILE *f, long int *pos); + #define fgetpos(f,pos) gstdioGetpos(f,pos) #define fsetpos(f, pos) (!gfileSetPos(f, *pos)) #define rewind(f) gfileSetPos(f, 0); - #define clearerr(f) do {f->err = 0; } while(0) - #define feof(f) (f->flags & GFILEFLG_EOF) - #define ferror(f) (f->err) + #define clearerr(f) (0) + #define feof(f) gfileEOF(f) + //#define ferror(f) (0) #define vfprintf(f,m,a) vfnprintg(f,0,m,a) #define fprintf(f,m,...) fnprintg(f,0,m,...) diff --git a/include/gfile/options.h b/include/gfile/options.h index 176c6270..a64937f1 100644 --- a/include/gfile/options.h +++ b/include/gfile/options.h @@ -21,12 +21,28 @@ * @{ */ /** - * @brief Include printg, fprintg, sprintg etc functions + * @brief Include printg, fprintg etc functions * @details Defaults to FALSE */ #ifndef GFILE_NEED_PRINTG #define GFILE_NEED_PRINTG FALSE #endif + /** + * @brief Include scang, fscang etc functions + * @details Defaults to FALSE + */ + #ifndef GFILE_NEED_SCANG + #define GFILE_NEED_SCANG FALSE + #endif + /** + * @brief Include the string sprintg/sscang functions + * @details Defaults to FALSE + * @pre To get sprintg functions you also need to define @p GFILE_NEED_PRINTG + * @pre To get sscang functions you also need to define @p GFILE_NEED_SCANG + */ + #ifndef GFILE_NEED_STRINGS + #define GFILE_NEED_STRINGS FALSE + #endif /** * @brief Include scang, fscang, sscang etc functions * @details Defaults to FALSE @@ -35,7 +51,7 @@ #define GFILE_NEED_SCANG FALSE #endif /** - * @brief Map all the stdio functions to their GFILE equivalent + * @brief Map many stdio functions to their GFILE equivalent * @details Defaults to FALSE * @note This replaces the functions in stdio.h with equivalents * - Do not include stdio.h as it has different conflicting definitions. @@ -46,7 +62,8 @@ /** * @brief Include the ROM file system * @details Defaults to FALSE - * @note To ensure that you are opening a file on the ROM file system, prefix + * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are + * opening a file on the ROM file system by prefixing * its name with "S|" (the letter 'S', followed by a vertical bar). * @note This requires a file called romfs_files.h to be included in the * users project. This file includes all the files converted to .h files @@ -58,7 +75,8 @@ /** * @brief Include the RAM file system * @details Defaults to FALSE - * @note To ensure that you are opening a file on the RAM file system, prefix + * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are + * opening a file on the RAM file system by prefixing * its name with "R|" (the letter 'R', followed by a vertical bar). * @note You must also define GFILE_RAMFS_SIZE with the size of the file system * to be allocated in RAM. @@ -69,7 +87,8 @@ /** * @brief Include the FAT file system driver * @details Defaults to FALSE - * @note To ensure that you are opening a file on the FAT file system, prefix + * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are + * opening a file on the FAT file system by prefixing * its name with "F|" (the letter 'F', followed by a vertical bar). * @note You must separately include the FATFS library and code. */ @@ -79,7 +98,8 @@ /** * @brief Include the operating system's native file system * @details Defaults to FALSE - * @note To ensure that you are opening a file on the native file system, prefix + * @note If GFILE_ALLOW_DEVICESPECIFIC is on then you can ensure that you are + * opening a file on the native file system by prefixing * its name with "N|" (the letter 'N', followed by a vertical bar). * @note If defined then the gfileStdOut and gfileStdErr handles * use the operating system equivalent stdio and stderr. @@ -94,6 +114,21 @@ * @name GFILE Optional Parameters * @{ */ + /** + * @brief Add floating point support to printg/scang etc. + */ + #ifndef GFILE_ALLOW_FLOATS + #define GFILE_ALLOW_FLOATS + #endif + /** + * @brief Can the device be specified as part of the file name. + * @note If this is on then a device letter and a vertical bar can be + * prefixed on a file name to specify that it must be on a + * specific device. + */ + #ifndef GFILE_ALLOW_DEVICESPECIFIC + #define GFILE_ALLOW_DEVICESPECIFIC FALSE + #endif /** * @brief The maximum number of open files * @note This count excludes gfileStdIn, gfileStdOut and gfileStdErr diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c index 83e487a1..e42dc2af 100644 --- a/src/gfile/gfile.c +++ b/src/gfile/gfile.c @@ -91,87 +91,98 @@ void _gfileInit(void) { #endif } -bool_t gfileExists(const char *fname) { +bool_t gfileExists(const char *fname) { const GFILEVMT *p; - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->exists && p->exists(fname+2); - } - } else { - for(p = FsChain; p; p = p->next) { - if (p->exists && p->exists(fname)) - return TRUE; + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->exists && p->exists(fname+2); + } + return FALSE; } + #endif + + for(p = FsChain; p; p = p->next) { + if (p->exists && p->exists(fname)) + return TRUE; } return FALSE; } -bool_t gfileDelete(const char *fname) { +bool_t gfileDelete(const char *fname) { const GFILEVMT *p; - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->del && p->del(fname+2); - } - } else { - for(p = FsChain; p; p = p->next) { - if (p->del && p->del(fname)) - return TRUE; + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->del && p->del(fname+2); + } + return FALSE; } + #endif + + for(p = FsChain; p; p = p->next) { + if (p->del && p->del(fname)) + return TRUE; } return FALSE; } long int gfileGetFilesize(const char *fname) { const GFILEVMT *p; + long int res; - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return p->filesize ? p->filesize(fname+2) : -1; + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return p->filesize ? p->filesize(fname+2) : -1; + } + return -1; } - } else { - long int res; + #endif - for(p = FsChain; p; p = p->next) { - if (p->filesize && (res = p->filesize(fname)) != -1) - return res; - } + for(p = FsChain; p; p = p->next) { + if (p->filesize && (res = p->filesize(fname)) != -1) + return res; } return -1; } -bool_t gfileRename(const char *oldname, const char *newname) { +bool_t gfileRename(const char *oldname, const char *newname) { const GFILEVMT *p; - if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) { - char ch; + #if GFILE_ALLOW_DEVICESPECIFIC + if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) { + char ch; - if (oldname[0] && oldname[1] == '|') { - ch = oldname[0]; - oldname += 2; - if (newname[0] && newname[1] == '|') { - if (newname[0] != ch) - // Both oldname and newname are fs specific but different ones. - return FALSE; + if (oldname[0] && oldname[1] == '|') { + ch = oldname[0]; + oldname += 2; + if (newname[0] && newname[1] == '|') { + if (newname[0] != ch) + // Both oldname and newname are fs specific but different ones. + return FALSE; + newname += 2; + } + } else { + ch = newname[0]; newname += 2; } - } else { - ch = newname[0]; - newname += 2; - } - for(p = FsChain; p; p = p->next) { - if (p->prefix == ch) - return p->ren && p->ren(oldname, newname); - } - } else { - for(p = FsChain; p; p = p->next) { - if (p->ren && p->ren(oldname,newname)) - return TRUE; + for(p = FsChain; p; p = p->next) { + if (p->prefix == ch) + return p->ren && p->ren(oldname, newname); + } + return FALSE; } + #endif + + for(p = FsChain; p; p = p->next) { + if (p->ren && p->ren(oldname,newname)) + return TRUE; } return FALSE; } @@ -233,32 +244,47 @@ static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) { } GFILE *gfileOpen(const char *fname, const char *mode) { - GFILE *f; + uint16_t flags; + GFILE * f; const GFILEVMT *p; + // Get the requested mode + if (!(flags = mode2flags(mode))) + return FALSE; + + #if GFILE_ALLOW_DEVICESPECIFIC + if (fname[0] && fname[1] == '|') { + // First find an available GFILE slot. + for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { + if (!(f->flags & GFILEFLG_OPEN)) { + // Try to open the file + f->flags = flags; + for(p = FsChain; p; p = p->next) { + if (p->prefix == fname[0]) + return testopen(p, f, fname+2); + } + // File not found + break; + } + } + + // No available slot + return FALSE; + } + #endif + // First find an available GFILE slot. for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) { if (!(f->flags & GFILEFLG_OPEN)) { - // Get the requested mode - if (!(f->flags = mode2flags(mode))) - return FALSE; - // Try to open the file - if (fname[0] && fname[1] == '|') { - for(p = FsChain; p; p = p->next) { - if (p->prefix == fname[0]) - return testopen(p, f, fname+2); - } - } else { - for(p = FsChain; p; p = p->next) { - if (testopen(p, f, fname)) - return TRUE; - } + f->flags = flags; + for(p = FsChain; p; p = p->next) { + if (testopen(p, f, fname)) + return TRUE; } - // File not found - return FALSE; + break; } } @@ -267,48 +293,384 @@ GFILE *gfileOpen(const char *fname, const char *mode) { } void gfileClose(GFILE *f) { - // Make sure it is one of the system GFILE's - if (f < gfileArr || f >= &gfileArr[GFILE_MAX_GFILES]) + if (!(f->flags & GFILEFLG_OPEN)) return; + if (f->vmt->close) + f->vmt->close(f); + f->flags = 0; } -size_t gfileRead(GFILE *f, char *buf, size_t len) { +size_t gfileRead(GFILE *f, char *buf, size_t len) { + size_t res; + if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ)) + return 0; + if (!f->vmt->read) + return 0; + if ((res = f->vmt->read(f, buf, len)) <= 0) + return 0; + f->pos += res; + return res; } -size_t gfileWrite(GFILE *f, const char *buf, size_t len) { +size_t gfileWrite(GFILE *f, const char *buf, size_t len) { + size_t res; + if ((f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE)) + return 0; + if (!f->vmt->write) + return 0; + if ((res = f->vmt->write(f, buf, len)) <= 0) + return 0; + f->pos += res; + return res; } -long int gfileGetPos(GFILE *f) { - +long int gfileGetPos(GFILE *f) { + if (!(f->flags & GFILEFLG_OPEN)) + return 0; + return f->pos; } bool_t gfileSetPos(GFILE *f, long int pos) { - + if (!(f->flags & GFILEFLG_OPEN)) + return FALSE; + if (!f->vmt->setpos || !f->vmt->setpos(f, pos)) + return FALSE; + f->pos = pos; } -long int gfileGetSize(GFILE *f) { - +long int gfileGetSize(GFILE *f) { + if (!(f->flags & GFILEFLG_OPEN)) + return 0; + if (!f->vmt->getsize) + return 0; + return f->vmt->getsize(f); } +bool_t gfileEOF(GFILE *f) { + if (!(f->flags & GFILEFLG_OPEN)) + return TRUE; + if (!f->vmt->eof) + return TRUE; + return f->vmt->eof(f); +} + +/******************************************************** + * String VMT routines + ********************************************************/ +#if GFILE_NEED_STRINGS && (GFILE_NEED_PRINTG || GFILE_NEED_SCANG) + #include + + // Special String VMT + static int StringRead(GFILE *f, char *buf, int size) { + memcpy(buf, (char *)f->obj+f->pos, size); + return size; + } + static int StringWrite(GFILE *f, const char *buf, int size) { + memcpy((char *)f->obj+f->pos, buf, size); + return size; + } + static const GFILEVMT StringVMT = { + 0, // next + 0, // flags + '_', // prefix + 0, 0, 0, 0, + 0, 0, StringRead, StringWrite, + 0, 0, 0, + }; +#endif + /******************************************************** * printg routines ********************************************************/ #if GFILE_NEED_PRINTG + #include + + #define MAX_FILLER 11 + #define FLOAT_PRECISION 100000 + + int fnprintg(GFILE *f, int maxlen, const char *fmt, ...) { + int res; + va_list ap; + + va_start(ap, fmt); + res = vfnprintg(f, maxlen, fmt, ap); + va_end(ap); + return res; + } + + static char *ltoa_wd(char *p, long num, unsigned radix, long divisor) { + int i; + char * q; + + if (!divisor) divisor = num; + + q = p + MAX_FILLER; + do { + i = (int)(num % radix); + i += '0'; + if (i > '9') + i += 'A' - '0' - 10; + *--q = i; + num /= radix; + } while ((divisor /= radix) != 0); + + i = (int)(p + MAX_FILLER - q); + do { + *p++ = *q++; + } while (--i); + + return p; + } + + int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg) { + int ret; + char *p, *s, c, filler; + int i, precision, width; + bool_t is_long, left_align; + long l; + #if GFILE_ALLOW_FLOATS + float f; + char tmpbuf[2*MAX_FILLER + 1]; + #else + char tmpbuf[MAX_FILLER + 1]; + #endif + + ret = 0; + if (maxlen < 0) + return 0; + if (!maxlen) + maxlen = -1; + + while (*fmt) { + if (*fmt != '%') { + gfileWrite(f, fmt, 1); + ret++; if (--maxlen) return ret; + fmt++; + continue; + } + fmt++; + + p = s = tmpbuf; + left_align = FALSE; + filler = ' '; + width = 0; + precision = 0; + + if (*fmt == '-') { + fmt++; + left_align = TRUE; + } + if (*fmt == '.') { + fmt++; + filler = '0'; + } + + while (1) { + c = *fmt++; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c == '*') + c = va_arg(ap, int); + else + break; + width = width * 10 + c; + } + if (c == '.') { + while (1) { + c = *fmt++; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c == '*') + c = va_arg(ap, int); + else + break; + precision = precision * 10 + c; + } + } + /* Long modifier.*/ + if (c == 'l' || c == 'L') { + is_long = TRUE; + if (*fmt) + c = *fmt++; + } + else + is_long = (c >= 'A') && (c <= 'Z'); + + /* Command decoding.*/ + switch (c) { + case 0: + return ret; + case 'c': + filler = ' '; + *p++ = va_arg(ap, int); + break; + case 's': + filler = ' '; + if ((s = va_arg(ap, char *)) == 0) + s = "(null)"; + if (precision == 0) + precision = 32767; + for (p = s; *p && (--precision >= 0); p++); + break; + case 'D': + case 'd': + if (is_long) + l = va_arg(ap, long); + else + l = va_arg(ap, int); + if (l < 0) { + *p++ = '-'; + l = -l; + } + p = ltoa_wd(p, l, 10, 0); + break; + #if GFILE_ALLOW_FLOATS + case 'f': + f = (float) va_arg(ap, double); + if (f < 0) { + *p++ = '-'; + f = -f; + } + l = f; + p = ltoa_wd(p, l, 10, 0); + *p++ = '.'; + l = (f - l) * FLOAT_PRECISION; + p = ltoa_wd(p, l, 10, FLOAT_PRECISION / 10); + break; + #endif + case 'X': + case 'x': + c = 16; + goto unsigned_common; + case 'U': + case 'u': + c = 10; + goto unsigned_common; + case 'O': + case 'o': + c = 8; + unsigned_common: + if (is_long) + l = va_arg(ap, long); + else + l = va_arg(ap, int); + p = ltoa_wd(p, l, c, 0); + break; + default: + *p++ = c; + break; + } + + i = (int)(p - s); + if ((width -= i) < 0) + width = 0; + if (left_align == FALSE) + width = -width; + if (width < 0) { + if (*s == '-' && filler == '0') { + gfileWrite(f, s++, 1); + ret++; if (--maxlen) return ret; + i--; + } + do { + gfileWrite(f, &filler, 1); + ret++; if (--maxlen) return ret; + } while (++width != 0); + } + while (--i >= 0) { + gfileWrite(f, s++, 1); + ret++; if (--maxlen) return ret; + } + while (width) { + gfileWrite(f, &filler, 1); + ret++; if (--maxlen) return ret; + width--; + } + } + return ret; + } + + #if GFILE_NEED_STRINGS + int snprintg(char *buf, int maxlen, const char *fmt, ...) { + int res; + GFILE f; + va_list ap; + + if (maxlen <= 1) { + if (maxlen == 1) + *buf = 0; + return 0; + } + f.flags = GFILEFLG_OPEN|GFILEFLG_WRITE; + f.vmt = &StringVMT; + f.pos = 0; + f.obj = buf; + va_start(ap, fmt); + res = vfnprintg(&f, maxlen-1, fmt, ap); + va_end(ap); + buf[res] = 0; + return res; + } + int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg) { + int res; + GFILE f; + + if (maxlen <= 1) { + if (maxlen == 1) + *buf = 0; + return 0; + } + f.flags = GFILEFLG_OPEN|GFILEFLG_WRITE; + f.vmt = &StringVMT; + f.pos = 0; + f.obj = buf; + res = vfnprintg(&f, maxlen-1, fmt, arg); + buf[res] = 0; + return res; + } + #endif #endif /******************************************************** * scang routines ********************************************************/ #if GFILE_NEED_SCANG + #error "GFILE-SCANG: Not implemented yet" #endif /******************************************************** * stdio emulation routines ********************************************************/ -#ifndef GFILE_NEED_STDIO - #define GFILE_NEED_STDIO FALSE +#if GFILE_NEED_STDIO + size_t gstdioRead(void * ptr, size_t size, size_t count, FILE *f) { + return gfileRead(f, ptr, size*count)/size; + } + size_t gstdioWrite(const void * ptr, size_t size, size_t count, FILE *f) { + return gfileWrite(f, ptr, size*count)/size; + } + int gstdioSeek(FILE *f, size_t offset, int origin) { + switch(origin) { + case SEEK_SET: + break; + case SEEK_CUR: + offset += f->pos; + break; + case SEEK_END: + offset += gfileGetSize(f); + break; + default: + return -1; + } + return gfileSetPos(f, offset) ? 0 : -1; + } + int gstdioGetpos(FILE *f, long int *pos) { + if (!(f->flags & GFILEFLG_OPEN)) + return -1; + *pos = f->pos; + return 0; + } #endif #endif /* GFX_USE_GFILE */ diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c index ccf1d40a..df5e7861 100644 --- a/src/gfile/inc_nativefs.c +++ b/src/gfile/inc_nativefs.c @@ -26,17 +26,19 @@ static bool_t NativeDel(const char *fname); static bool_t NativeExists(const char *fname); static long int NativeFilesize(const char *fname); static bool_t NativeRen(const char *oldname, const char *newname); -static bool_t NativeOpen(GFILE *f, const char *fname, const char *mode); +static bool_t NativeOpen(GFILE *f, const char *fname); static void NativeClose(GFILE *f); static int NativeRead(GFILE *f, char *buf, int size); -static int NativeWrite(GFILE *f, char *buf, int size); +static int NativeWrite(GFILE *f, const char *buf, int size); static bool_t NativeSetpos(GFILE *f, long int pos); static long int NativeGetsize(GFILE *f); static bool_t NativeEof(GFILE *f); static const GFILEVMT FsNativeVMT = { GFILE_CHAINHEAD, // next - #if !defined(WIN32) && !GFX_USE_OS_WIN32 + #if defined(WIN32) || GFX_USE_OS_WIN32 + GFSFLG_TEXTMODES| + #else GFSFLG_CASESENSITIVE| #endif GFSFLG_WRITEABLE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags @@ -84,11 +86,9 @@ static bool_t NativeOpen(GFILE *f, const char *fname) { } static void NativeClose(GFILE *f) { fclose((FILE *)f->obj); } static int NativeRead(GFILE *f, char *buf, int size) { return fread(buf, 1, size, (FILE *)f->obj); } -static int NativeWrite(GFILE *f, char *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } +static int NativeWrite(GFILE *f, const char *buf, int size) { return fwrite(buf, 1, size, (FILE *)f->obj); } static bool_t NativeSetpos(GFILE *f, long int pos) { - if (fseek((FILE *)f->obj, pos, SEEK_SET)) return FALSE; - f->pos = pos; - return TRUE; + return fseek((FILE *)f->obj, pos, SEEK_SET) ? FALSE : TRUE; } static long int NativeGetsize(GFILE *f) { struct stat st; diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c index 170b9a6c..5a780554 100644 --- a/src/gfile/inc_romfs.c +++ b/src/gfile/inc_romfs.c @@ -30,7 +30,7 @@ static const ROMFS_DIRENTRY const *FsROMHead = ROMFS_DIRENTRY_HEAD; static bool_t ROMExists(const char *fname); static long int ROMFilesize(const char *fname); -static bool_t ROMOpen(GFILE *f, const char *fname, const char *mode); +static bool_t ROMOpen(GFILE *f, const char *fname); static void ROMClose(GFILE *f); static int ROMRead(GFILE *f, char *buf, int size); static bool_t ROMSetpos(GFILE *f, long int pos);