Separate GFILE into separate source files to prevent future name and include file conflicts.
This commit is contained in:
parent
a588740dc3
commit
1105e38414
@ -11,183 +11,65 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GFILE_IMPLEMENTATION
|
|
||||||
|
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
|
|
||||||
#if GFX_USE_GFILE
|
#if GFX_USE_GFILE
|
||||||
|
|
||||||
struct GFILE {
|
#include "gfile_fs.h"
|
||||||
const struct GFILEVMT * vmt;
|
|
||||||
uint16_t flags;
|
|
||||||
#define GFILEFLG_OPEN 0x0001 // File is open
|
|
||||||
#define GFILEFLG_READ 0x0002 // Read the file
|
|
||||||
#define GFILEFLG_WRITE 0x0004 // Write the file
|
|
||||||
#define GFILEFLG_APPEND 0x0008 // Append on each write
|
|
||||||
#define GFILEFLG_BINARY 0x0010 // Treat as a binary file
|
|
||||||
#define GFILEFLG_DELONCLOSE 0x0020 // Delete on close
|
|
||||||
#define GFILEFLG_CANSEEK 0x0040 // Seek operations are valid
|
|
||||||
#define GFILEFLG_FAILONBLOCK 0x0080 // Fail on a blocking call
|
|
||||||
#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
|
|
||||||
void * obj;
|
|
||||||
long int pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gfileList {
|
/**
|
||||||
const struct GFILEVMT * vmt;
|
* Define the VMT's for the file-systems we want to search for files.
|
||||||
bool_t dirs;
|
* Virtual file-systems that have special open() calls do not need to
|
||||||
};
|
* be in this list.
|
||||||
|
*/
|
||||||
|
#if GFILE_NEED_ROMFS
|
||||||
|
extern const GFILEVMT FsROMVMT;
|
||||||
|
#endif
|
||||||
|
#if GFILE_NEED_NATIVEFS
|
||||||
|
extern const GFILEVMT FsNativeVMT;
|
||||||
|
#endif
|
||||||
|
#if GFILE_NEED_FATFS
|
||||||
|
extern const GFILEVMT FsFatFSVMT;
|
||||||
|
#endif
|
||||||
|
#if GFILE_NEED_RAMFS
|
||||||
|
extern const GFILEVMT FsRAMVMT;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct GFILEVMT {
|
|
||||||
const struct GFILEVMT * next;
|
|
||||||
uint8_t flags;
|
|
||||||
#define GFSFLG_WRITEABLE 0x0001
|
|
||||||
#define GFSFLG_CASESENSITIVE 0x0002
|
|
||||||
#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);
|
|
||||||
long int (*filesize) (const char *fname);
|
|
||||||
bool_t (*ren) (const char *oldname, const char *newname);
|
|
||||||
bool_t (*open) (GFILE *f, const char *fname);
|
|
||||||
void (*close) (GFILE *f);
|
|
||||||
int (*read) (GFILE *f, void *buf, int size);
|
|
||||||
int (*write) (GFILE *f, const void *buf, int size);
|
|
||||||
bool_t (*setpos) (GFILE *f, long int pos);
|
|
||||||
long int (*getsize) (GFILE *f);
|
|
||||||
bool_t (*eof) (GFILE *f);
|
|
||||||
bool_t (*mount) (const char *drive);
|
|
||||||
bool_t (*unmount) (const char *drive);
|
|
||||||
bool_t (*sync) (GFILE *f);
|
|
||||||
#if GFILE_NEED_FILELISTS
|
|
||||||
gfileList * (*flopen) (const char *path, bool_t dirs);
|
|
||||||
const char *(*flread) (gfileList *pfl);
|
|
||||||
void (*flclose) (gfileList *pfl);
|
|
||||||
#endif
|
|
||||||
} GFILEVMT;
|
|
||||||
|
|
||||||
// The chain of FileSystems
|
|
||||||
#define GFILE_CHAINHEAD 0
|
|
||||||
|
|
||||||
// The table of GFILE's
|
|
||||||
static GFILE gfileArr[GFILE_MAX_GFILES];
|
|
||||||
GFILE *gfileStdIn;
|
|
||||||
GFILE *gfileStdOut;
|
|
||||||
GFILE *gfileStdErr;
|
|
||||||
|
|
||||||
// Forward definition used by some special open calls
|
|
||||||
static GFILE *findemptyfile(const char *mode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The order of the file-systems below determines the order
|
* The order of the file-systems below determines the order
|
||||||
* that they are searched to find a file.
|
* that they are searched to find a file.
|
||||||
* The last defined is the first searched.
|
|
||||||
*/
|
*/
|
||||||
|
static const GFILEVMT const * FsArray[] = {
|
||||||
|
#if GFILE_NEED_ROMFS
|
||||||
|
&FsROMVMT,
|
||||||
|
#endif
|
||||||
|
#if GFILE_NEED_NATIVEFS
|
||||||
|
&FsNativeVMT,
|
||||||
|
#endif
|
||||||
|
#if GFILE_NEED_FATFS
|
||||||
|
&FsFatFSVMT,
|
||||||
|
#endif
|
||||||
|
#if GFILE_NEED_RAMFS
|
||||||
|
&FsRAMVMT,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/********************************************************
|
/*
|
||||||
* The ChibiOS BaseFileStream VMT
|
* The table of GFILE's
|
||||||
********************************************************/
|
|
||||||
#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS
|
|
||||||
#include "src/gfile/inc_chibiosfs.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* The Memory Pointer VMT
|
|
||||||
********************************************************/
|
|
||||||
#if GFILE_NEED_MEMFS
|
|
||||||
#include "src/gfile/inc_memfs.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* The RAM file-system VMT
|
|
||||||
********************************************************/
|
|
||||||
#if GFILE_NEED_RAMFS
|
|
||||||
#include "src/gfile/inc_ramfs.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* The FAT file-system VMT
|
|
||||||
********************************************************/
|
|
||||||
#if GFILE_NEED_FATFS
|
|
||||||
#include "src/gfile/inc_fatfs.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* The native file-system
|
|
||||||
********************************************************/
|
|
||||||
#if GFILE_NEED_NATIVEFS
|
|
||||||
#include "src/gfile/inc_nativefs.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* The ROM file-system VMT
|
|
||||||
********************************************************/
|
|
||||||
#if GFILE_NEED_ROMFS
|
|
||||||
#include "src/gfile/inc_romfs.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* The virtual string file VMT
|
|
||||||
********************************************************/
|
|
||||||
#if GFILE_NEED_STRINGS
|
|
||||||
#include "src/gfile/inc_strings.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* Printg Routines
|
|
||||||
********************************************************/
|
|
||||||
#if GFILE_NEED_PRINTG
|
|
||||||
#include "src/gfile/inc_printg.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* Scang Routines
|
|
||||||
********************************************************/
|
|
||||||
#if GFILE_NEED_SCANG
|
|
||||||
#include "src/gfile/inc_scang.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* Stdio Emulation Routines
|
|
||||||
********************************************************/
|
|
||||||
#if GFILE_NEED_STDIO
|
|
||||||
#include "src/gfile/inc_stdio.c"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/********************************************************
|
|
||||||
* IO routines
|
|
||||||
********************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The chain of file systems.
|
|
||||||
*/
|
*/
|
||||||
static const GFILEVMT const * FsChain = GFILE_CHAINHEAD;
|
static GFILE gfileArr[GFILE_MAX_GFILES];
|
||||||
|
GFILE *gfileStdIn;
|
||||||
|
GFILE *gfileStdOut;
|
||||||
|
GFILE *gfileStdErr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The init routine
|
* The init routine
|
||||||
*/
|
*/
|
||||||
void _gfileInit(void) {
|
void _gfileInit(void) {
|
||||||
#if GFILE_NEED_NATIVEFS
|
#if GFILE_NEED_NATIVEFS
|
||||||
NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ;
|
extern void _gfileNativeAssignStdio(void);
|
||||||
NativeStdIn.vmt = &FsNativeVMT;
|
_gfileNativeAssignStdio();
|
||||||
NativeStdIn.obj = (void *)stdin;
|
|
||||||
NativeStdIn.pos = 0;
|
|
||||||
gfileStdIn = &NativeStdIn;
|
|
||||||
NativeStdOut.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND;
|
|
||||||
NativeStdOut.vmt = &FsNativeVMT;
|
|
||||||
NativeStdOut.obj = (void *)stdout;
|
|
||||||
NativeStdOut.pos = 0;
|
|
||||||
gfileStdOut = &NativeStdOut;
|
|
||||||
NativeStdErr.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND;
|
|
||||||
NativeStdErr.vmt = &FsNativeVMT;
|
|
||||||
NativeStdErr.obj = (void *)stderr;
|
|
||||||
NativeStdErr.pos = 0;
|
|
||||||
gfileStdErr = &NativeStdErr;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,103 +78,10 @@ void _gfileDeinit(void)
|
|||||||
/* ToDo */
|
/* ToDo */
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t gfileExists(const char *fname) {
|
/**
|
||||||
const GFILEVMT *p;
|
* Internal routine to find an empty GFILE slot and interpret flags.
|
||||||
|
*/
|
||||||
#if GFILE_ALLOW_DEVICESPECIFIC
|
GFILE *_gfileFindSlot(const char *mode) {
|
||||||
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) {
|
|
||||||
const GFILEVMT *p;
|
|
||||||
|
|
||||||
#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 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;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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) {
|
|
||||||
const GFILEVMT *p;
|
|
||||||
|
|
||||||
#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;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(p = FsChain; p; p = p->next) {
|
|
||||||
if (p->ren && p->ren(oldname,newname))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GFILE *findemptyfile(const char *mode) {
|
|
||||||
GFILE * f;
|
GFILE * f;
|
||||||
|
|
||||||
// First find an available GFILE slot.
|
// First find an available GFILE slot.
|
||||||
@ -338,6 +127,106 @@ static GFILE *findemptyfile(const char *mode) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* IO routines
|
||||||
|
********************************************************/
|
||||||
|
|
||||||
|
bool_t gfileExists(const char *fname) {
|
||||||
|
const GFILEVMT * const *p;
|
||||||
|
|
||||||
|
#if GFILE_ALLOW_DEVICESPECIFIC
|
||||||
|
if (fname[0] && fname[1] == '|') {
|
||||||
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
|
if (p[0]->prefix == fname[0])
|
||||||
|
return p[0]->exists && p[0]->exists(fname+2);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
|
if (p[0]->exists && p[0]->exists(fname))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t gfileDelete(const char *fname) {
|
||||||
|
const GFILEVMT **p;
|
||||||
|
|
||||||
|
#if GFILE_ALLOW_DEVICESPECIFIC
|
||||||
|
if (fname[0] && fname[1] == '|') {
|
||||||
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
|
if (p[0]->prefix == fname[0])
|
||||||
|
return p[0]->del && p[0]->del(fname+2);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
|
if (p[0]->del && p[0]->del(fname))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
long int gfileGetFilesize(const char *fname) {
|
||||||
|
const GFILEVMT * const *p;
|
||||||
|
long int res;
|
||||||
|
|
||||||
|
#if GFILE_ALLOW_DEVICESPECIFIC
|
||||||
|
if (fname[0] && fname[1] == '|') {
|
||||||
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
|
if (p[0]->prefix == fname[0])
|
||||||
|
return p[0]->filesize ? p[0]->filesize(fname+2) : -1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
|
if (p[0]->filesize && (res = p[0]->filesize(fname)) != -1)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t gfileRename(const char *oldname, const char *newname) {
|
||||||
|
const GFILEVMT * const *p;
|
||||||
|
|
||||||
|
#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;
|
||||||
|
newname += 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ch = newname[0];
|
||||||
|
newname += 2;
|
||||||
|
}
|
||||||
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
|
if (p[0]->prefix == ch)
|
||||||
|
return p[0]->ren && p[0]->ren(oldname, newname);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
|
if (p[0]->ren && p[0]->ren(oldname,newname))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) {
|
static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) {
|
||||||
// If we want write but the fs doesn't allow it then return
|
// If we want write but the fs doesn't allow it then return
|
||||||
if ((f->flags & GFILEFLG_WRITE) && !(p->flags & GFSFLG_WRITEABLE))
|
if ((f->flags & GFILEFLG_WRITE) && !(p->flags & GFSFLG_WRITEABLE))
|
||||||
@ -358,17 +247,17 @@ static bool_t testopen(const GFILEVMT *p, GFILE *f, const char *fname) {
|
|||||||
|
|
||||||
GFILE *gfileOpen(const char *fname, const char *mode) {
|
GFILE *gfileOpen(const char *fname, const char *mode) {
|
||||||
GFILE * f;
|
GFILE * f;
|
||||||
const GFILEVMT *p;
|
const GFILEVMT * const *p;
|
||||||
|
|
||||||
// Get an empty file and set the flags
|
// Get an empty file and set the flags
|
||||||
if (!(f = findemptyfile(mode)))
|
if (!(f = _gfileFindSlot(mode)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#if GFILE_ALLOW_DEVICESPECIFIC
|
#if GFILE_ALLOW_DEVICESPECIFIC
|
||||||
if (fname[0] && fname[1] == '|') {
|
if (fname[0] && fname[1] == '|') {
|
||||||
for(p = FsChain; p; p = p->next) {
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
if (p->prefix == fname[0])
|
if (p[0]->prefix == fname[0])
|
||||||
return testopen(p, f, fname+2) ? f : 0;
|
return testopen(p[0], f, fname+2) ? f : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// File not found
|
// File not found
|
||||||
@ -376,8 +265,8 @@ GFILE *gfileOpen(const char *fname, const char *mode) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(p = FsChain; p; p = p->next) {
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
if (testopen(p, f, fname))
|
if (testopen(p[0], f, fname))
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,28 +340,28 @@ bool_t gfileEOF(GFILE *f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool_t gfileMount(char fs, const char* drive) {
|
bool_t gfileMount(char fs, const char* drive) {
|
||||||
const GFILEVMT *p;
|
const GFILEVMT * const *p;
|
||||||
|
|
||||||
// Find the correct VMT
|
// Find the correct VMT
|
||||||
for(p = FsChain; p; p = p->next) {
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
if (p->prefix == fs) {
|
if (p[0]->prefix == fs) {
|
||||||
if (!p->mount)
|
if (!p[0]->mount)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return p->mount(drive);
|
return p[0]->mount(drive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t gfileUnmount(char fs, const char* drive) {
|
bool_t gfileUnmount(char fs, const char* drive) {
|
||||||
const GFILEVMT *p;
|
const GFILEVMT * const *p;
|
||||||
|
|
||||||
// Find the correct VMT
|
// Find the correct VMT
|
||||||
for(p = FsChain; p; p = p->next) {
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
if (p->prefix == fs) {
|
if (p[0]->prefix == fs) {
|
||||||
if (!p->mount)
|
if (!p[0]->mount)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return p->unmount(drive);
|
return p[0]->unmount(drive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -486,17 +375,17 @@ bool_t gfileSync(GFILE *f) {
|
|||||||
|
|
||||||
#if GFILE_NEED_FILELISTS
|
#if GFILE_NEED_FILELISTS
|
||||||
gfileList *gfileOpenFileList(char fs, const char *path, bool_t dirs) {
|
gfileList *gfileOpenFileList(char fs, const char *path, bool_t dirs) {
|
||||||
const GFILEVMT *p;
|
const GFILEVMT * const *p;
|
||||||
gfileList * pfl;
|
gfileList * pfl;
|
||||||
|
|
||||||
// Find the correct VMT
|
// Find the correct VMT
|
||||||
for(p = FsChain; p; p = p->next) {
|
for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
|
||||||
if (p->prefix == fs) {
|
if (p[0]->prefix == fs) {
|
||||||
if (!p->flopen)
|
if (!p[0]->flopen)
|
||||||
return 0;
|
return 0;
|
||||||
pfl = p->flopen(path, dirs);
|
pfl = p[0]->flopen(path, dirs);
|
||||||
if (pfl) {
|
if (pfl) {
|
||||||
pfl->vmt = p;
|
pfl->vmt = p[0];
|
||||||
pfl->dirs = dirs;
|
pfl->dirs = dirs;
|
||||||
}
|
}
|
||||||
return pfl;
|
return pfl;
|
||||||
|
72
src/gfile/gfile_fs.h
Normal file
72
src/gfile/gfile_fs.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file src/gfile/gfile_fs.h
|
||||||
|
* @brief GFILE file system header.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GFILE_FS_H
|
||||||
|
#define _GFILE_FS_H
|
||||||
|
|
||||||
|
struct GFILE {
|
||||||
|
const struct GFILEVMT * vmt;
|
||||||
|
uint16_t flags;
|
||||||
|
#define GFILEFLG_OPEN 0x0001 // File is open
|
||||||
|
#define GFILEFLG_READ 0x0002 // Read the file
|
||||||
|
#define GFILEFLG_WRITE 0x0004 // Write the file
|
||||||
|
#define GFILEFLG_APPEND 0x0008 // Append on each write
|
||||||
|
#define GFILEFLG_BINARY 0x0010 // Treat as a binary file
|
||||||
|
#define GFILEFLG_DELONCLOSE 0x0020 // Delete on close
|
||||||
|
#define GFILEFLG_CANSEEK 0x0040 // Seek operations are valid
|
||||||
|
#define GFILEFLG_FAILONBLOCK 0x0080 // Fail on a blocking call
|
||||||
|
#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
|
||||||
|
void * obj;
|
||||||
|
long int pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gfileList {
|
||||||
|
const struct GFILEVMT * vmt;
|
||||||
|
bool_t dirs;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct GFILEVMT {
|
||||||
|
uint8_t flags;
|
||||||
|
#define GFSFLG_WRITEABLE 0x0001
|
||||||
|
#define GFSFLG_CASESENSITIVE 0x0002
|
||||||
|
#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);
|
||||||
|
long int (*filesize) (const char *fname);
|
||||||
|
bool_t (*ren) (const char *oldname, const char *newname);
|
||||||
|
bool_t (*open) (GFILE *f, const char *fname);
|
||||||
|
void (*close) (GFILE *f);
|
||||||
|
int (*read) (GFILE *f, void *buf, int size);
|
||||||
|
int (*write) (GFILE *f, const void *buf, int size);
|
||||||
|
bool_t (*setpos) (GFILE *f, long int pos);
|
||||||
|
long int (*getsize) (GFILE *f);
|
||||||
|
bool_t (*eof) (GFILE *f);
|
||||||
|
bool_t (*mount) (const char *drive);
|
||||||
|
bool_t (*unmount) (const char *drive);
|
||||||
|
bool_t (*sync) (GFILE *f);
|
||||||
|
#if GFILE_NEED_FILELISTS
|
||||||
|
gfileList * (*flopen) (const char *path, bool_t dirs);
|
||||||
|
const char *(*flread) (gfileList *pfl);
|
||||||
|
void (*flclose) (gfileList *pfl);
|
||||||
|
#endif
|
||||||
|
} GFILEVMT;
|
||||||
|
|
||||||
|
GFILE *_gfileFindSlot(const char *mode);
|
||||||
|
|
||||||
|
#endif //_GFILE_FS_H
|
@ -5,14 +5,16 @@
|
|||||||
* http://ugfx.org/license.html
|
* http://ugfx.org/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is included by src/gfile/gfile.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* The ChibiOS BaseFileStream file-system VMT
|
* The ChibiOS BaseFileStream file-system
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GFILE && GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS
|
||||||
|
|
||||||
|
#include "gfile_fs.h"
|
||||||
|
|
||||||
static void ChibiOSBFSClose(GFILE *f);
|
static void ChibiOSBFSClose(GFILE *f);
|
||||||
static int ChibiOSBFSRead(GFILE *f, void *buf, int size);
|
static int ChibiOSBFSRead(GFILE *f, void *buf, int size);
|
||||||
static int ChibiOSBFSWrite(GFILE *f, const void *buf, int size);
|
static int ChibiOSBFSWrite(GFILE *f, const void *buf, int size);
|
||||||
@ -21,7 +23,6 @@ static long int ChibiOSBFSGetsize(GFILE *f);
|
|||||||
static bool_t ChibiOSBFSEof(GFILE *f);
|
static bool_t ChibiOSBFSEof(GFILE *f);
|
||||||
|
|
||||||
static const GFILEVMT FsCHIBIOSVMT = {
|
static const GFILEVMT FsCHIBIOSVMT = {
|
||||||
0, // next
|
|
||||||
GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags
|
GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags
|
||||||
0, // prefix
|
0, // prefix
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
@ -53,7 +54,7 @@ GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, const char *mode) {
|
|||||||
GFILE * f;
|
GFILE * f;
|
||||||
|
|
||||||
// Get an empty file and set the flags
|
// Get an empty file and set the flags
|
||||||
if (!(f = findemptyfile(mode)))
|
if (!(f = _gfileFindSlot(mode)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// File is open - fill in all the details
|
// File is open - fill in all the details
|
||||||
@ -63,3 +64,5 @@ GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, const char *mode) {
|
|||||||
f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK;
|
f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif //GFX_USE_GFILE && GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS
|
||||||
|
@ -5,10 +5,15 @@
|
|||||||
* http://ugfx.org/license.html
|
* http://ugfx.org/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/********************************************************
|
||||||
* This file is included by src/gfile/gfile.c
|
* The FATFS file-system
|
||||||
*/
|
********************************************************/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GFILE && GFILE_NEED_FATFS
|
||||||
|
|
||||||
|
#include "gfile_fs.h"
|
||||||
#include "fatfs_wrapper.h"
|
#include "fatfs_wrapper.h"
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
@ -35,8 +40,7 @@ static bool_t fatfsSync(GFILE* f);
|
|||||||
static void fatfsFlClose(gfileList *pfl);
|
static void fatfsFlClose(gfileList *pfl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const GFILEVMT FsFatFSVMT = {
|
const GFILEVMT FsFatFSVMT = {
|
||||||
GFILE_CHAINHEAD,
|
|
||||||
GFSFLG_WRITEABLE | GFSFLG_SEEKABLE,
|
GFSFLG_WRITEABLE | GFSFLG_SEEKABLE,
|
||||||
'F',
|
'F',
|
||||||
fatfsDel,
|
fatfsDel,
|
||||||
@ -60,9 +64,6 @@ static const GFILEVMT FsFatFSVMT = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef GFILE_CHAINHEAD
|
|
||||||
#define GFILE_CHAINHEAD &FsFatFSVMT
|
|
||||||
|
|
||||||
// Our directory list structure
|
// Our directory list structure
|
||||||
typedef struct fatfsList {
|
typedef struct fatfsList {
|
||||||
gfileList fl; // This must be the first element.
|
gfileList fl; // This must be the first element.
|
||||||
@ -319,3 +320,6 @@ static bool_t fatfsSync(GFILE *f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif //GFX_USE_GFILE && GFILE_NEED_FATFS
|
||||||
|
|
||||||
|
@ -5,14 +5,16 @@
|
|||||||
* http://ugfx.org/license.html
|
* http://ugfx.org/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is included by src/gfile/gfile.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* The Memory pointer file-system VMT
|
* The virtual memory file-system
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GFILE && GFILE_NEED_MEMFS
|
||||||
|
|
||||||
|
#include "gfile_fs.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static int MEMRead(GFILE *f, void *buf, int size);
|
static int MEMRead(GFILE *f, void *buf, int size);
|
||||||
@ -20,7 +22,6 @@ static int MEMWrite(GFILE *f, const void *buf, int size);
|
|||||||
static bool_t MEMSetpos(GFILE *f, long int pos);
|
static bool_t MEMSetpos(GFILE *f, long int pos);
|
||||||
|
|
||||||
static const GFILEVMT FsMemVMT = {
|
static const GFILEVMT FsMemVMT = {
|
||||||
0, // next
|
|
||||||
GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags
|
GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags
|
||||||
0, // prefix
|
0, // prefix
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
@ -50,7 +51,7 @@ GFILE * gfileOpenMemory(void *memptr, const char *mode) {
|
|||||||
GFILE *f;
|
GFILE *f;
|
||||||
|
|
||||||
// Get an empty file and set the flags
|
// Get an empty file and set the flags
|
||||||
if (!(f = findemptyfile(mode)))
|
if (!(f = _gfileFindSlot(mode)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// File is open - fill in all the details
|
// File is open - fill in all the details
|
||||||
@ -60,3 +61,5 @@ GFILE * gfileOpenMemory(void *memptr, const char *mode) {
|
|||||||
f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK;
|
f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif //GFX_USE_GFILE && GFILE_NEED_MEMFS
|
||||||
|
@ -5,23 +5,21 @@
|
|||||||
* http://ugfx.org/license.html
|
* http://ugfx.org/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is included by src/gfile/gfile.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* The native file-system
|
* The native file-system
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GFILE && GFILE_NEED_NATIVEFS
|
||||||
|
|
||||||
|
#include "gfile_fs.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
//#include <unistd.h>
|
//#include <unistd.h>
|
||||||
|
|
||||||
static GFILE NativeStdIn;
|
|
||||||
static GFILE NativeStdOut;
|
|
||||||
static GFILE NativeStdErr;
|
|
||||||
|
|
||||||
static bool_t NativeDel(const char *fname);
|
static bool_t NativeDel(const char *fname);
|
||||||
static bool_t NativeExists(const char *fname);
|
static bool_t NativeExists(const char *fname);
|
||||||
static long int NativeFilesize(const char *fname);
|
static long int NativeFilesize(const char *fname);
|
||||||
@ -39,8 +37,7 @@ static bool_t NativeEof(GFILE *f);
|
|||||||
static void NativeFlClose(gfileList *pfl);
|
static void NativeFlClose(gfileList *pfl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const GFILEVMT FsNativeVMT = {
|
const GFILEVMT FsNativeVMT = {
|
||||||
GFILE_CHAINHEAD, // next
|
|
||||||
#if defined(WIN32) || GFX_USE_OS_WIN32
|
#if defined(WIN32) || GFX_USE_OS_WIN32
|
||||||
GFSFLG_TEXTMODES|
|
GFSFLG_TEXTMODES|
|
||||||
#else
|
#else
|
||||||
@ -56,8 +53,28 @@ static const GFILEVMT FsNativeVMT = {
|
|||||||
NativeFlOpen, NativeFlRead, NativeFlClose
|
NativeFlOpen, NativeFlRead, NativeFlClose
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
#undef GFILE_CHAINHEAD
|
|
||||||
#define GFILE_CHAINHEAD &FsNativeVMT
|
void _gfileNativeAssignStdio(void) {
|
||||||
|
static GFILE NativeStdIn;
|
||||||
|
static GFILE NativeStdOut;
|
||||||
|
static GFILE NativeStdErr;
|
||||||
|
|
||||||
|
NativeStdIn.flags = GFILEFLG_OPEN|GFILEFLG_READ;
|
||||||
|
NativeStdIn.vmt = &FsNativeVMT;
|
||||||
|
NativeStdIn.obj = (void *)stdin;
|
||||||
|
NativeStdIn.pos = 0;
|
||||||
|
gfileStdIn = &NativeStdIn;
|
||||||
|
NativeStdOut.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND;
|
||||||
|
NativeStdOut.vmt = &FsNativeVMT;
|
||||||
|
NativeStdOut.obj = (void *)stdout;
|
||||||
|
NativeStdOut.pos = 0;
|
||||||
|
gfileStdOut = &NativeStdOut;
|
||||||
|
NativeStdErr.flags = GFILEFLG_OPEN|GFILEFLG_WRITE|GFILEFLG_APPEND;
|
||||||
|
NativeStdErr.vmt = &FsNativeVMT;
|
||||||
|
NativeStdErr.obj = (void *)stderr;
|
||||||
|
NativeStdErr.pos = 0;
|
||||||
|
gfileStdErr = &NativeStdErr;
|
||||||
|
}
|
||||||
|
|
||||||
static void Native_flags2mode(char *buf, uint16_t flags) {
|
static void Native_flags2mode(char *buf, uint16_t flags) {
|
||||||
if (flags & GFILEFLG_MUSTEXIST)
|
if (flags & GFILEFLG_MUSTEXIST)
|
||||||
@ -214,3 +231,5 @@ static long int NativeGetsize(GFILE *f) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif //GFX_USE_GFILE && GFILE_NEED_NATIVEFS
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
* http://ugfx.org/license.html
|
* http://ugfx.org/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is included by src/gfile/gfile.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Printg Routines
|
* Printg Routines
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GFILE && GFILE_NEED_PRINTG
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define MAX_FILLER 11
|
#define MAX_FILLER 11
|
||||||
@ -220,42 +220,4 @@ int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GFILE_NEED_STRINGS
|
#endif //GFX_USE_GFILE && GFILE_NEED_PRINTG
|
||||||
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;
|
|
||||||
}
|
|
||||||
maxlen += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
f.flags = GFILEFLG_WRITE|GFILEFLG_TRUNC;
|
|
||||||
gfileOpenStringFromStaticGFILE(&f, buf);
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
res = vfnprintg(&f, maxlen-1, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg) {
|
|
||||||
GFILE f;
|
|
||||||
|
|
||||||
if (maxlen <= 1) {
|
|
||||||
if (maxlen == 1) {
|
|
||||||
*buf = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
maxlen += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
f.flags = GFILEFLG_WRITE|GFILEFLG_TRUNC;
|
|
||||||
gfileOpenStringFromStaticGFILE(&f, buf);
|
|
||||||
|
|
||||||
return vfnprintg(&f, maxlen-1, fmt, arg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -5,11 +5,28 @@
|
|||||||
* http://ugfx.org/license.html
|
* http://ugfx.org/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is included by src/gfile/gfile.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* The RAM file-system VMT
|
* The RAM file-system
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GFILE && GFILE_NEED_RAMFS
|
||||||
|
|
||||||
|
#include "gfile_fs.h"
|
||||||
|
|
||||||
#error "GFILE: RAMFS Not implemented yet"
|
#error "GFILE: RAMFS Not implemented yet"
|
||||||
|
|
||||||
|
const GFILEVMT FsRAMVMT = {
|
||||||
|
0, // flags
|
||||||
|
'R', // prefix
|
||||||
|
0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
#if GFILE_NEED_FILELISTS
|
||||||
|
0, 0, 0,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GFX_USE_GFILE && GFILE_NEED_RAMFS
|
||||||
|
@ -5,14 +5,16 @@
|
|||||||
* http://ugfx.org/license.html
|
* http://ugfx.org/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is included by src/gfile/gfile.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* The ROM file-system VMT
|
* The ROM file-system
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GFILE && GFILE_NEED_ROMFS
|
||||||
|
|
||||||
|
#include "gfile_fs.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// What directory file formats do we understand
|
// What directory file formats do we understand
|
||||||
@ -54,8 +56,7 @@ static bool_t ROMEof(GFILE *f);
|
|||||||
static void ROMFlClose(gfileList *pfl);
|
static void ROMFlClose(gfileList *pfl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const GFILEVMT FsROMVMT = {
|
const GFILEVMT FsROMVMT = {
|
||||||
GFILE_CHAINHEAD, // next
|
|
||||||
GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags
|
GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags
|
||||||
'S', // prefix
|
'S', // prefix
|
||||||
0, ROMExists, ROMFilesize, 0,
|
0, ROMExists, ROMFilesize, 0,
|
||||||
@ -66,8 +67,6 @@ static const GFILEVMT FsROMVMT = {
|
|||||||
ROMFlOpen, ROMFlRead, ROMFlClose
|
ROMFlOpen, ROMFlRead, ROMFlClose
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
#undef GFILE_CHAINHEAD
|
|
||||||
#define GFILE_CHAINHEAD &FsROMVMT
|
|
||||||
|
|
||||||
static const ROMFS_DIRENTRY *ROMFindFile(const char *fname)
|
static const ROMFS_DIRENTRY *ROMFindFile(const char *fname)
|
||||||
{
|
{
|
||||||
@ -175,3 +174,5 @@ static bool_t ROMEof(GFILE *f)
|
|||||||
gfxFree(pfl);
|
gfxFree(pfl);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif //GFX_USE_GFILE && GFILE_NEED_ROMFS
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
* http://ugfx.org/license.html
|
* http://ugfx.org/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is included by src/gfile/gfile.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Scang Routines
|
* Scang Routines
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GFILE && GFILE_NEED_SCANG
|
||||||
|
|
||||||
int fscang(GFILE *f, const char *fmt, ...) {
|
int fscang(GFILE *f, const char *fmt, ...) {
|
||||||
int res;
|
int res;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@ -231,27 +231,4 @@ int vfscang(GFILE *f, const char *fmt, va_list arg) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GFILE_NEED_STRINGS
|
#endif //GFX_USE_GFILE && GFILE_NEED_SCANG
|
||||||
int sscang(const char *buf, const char *fmt, ...) {
|
|
||||||
int res;
|
|
||||||
GFILE f;
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
f.flags = GFILEFLG_READ;
|
|
||||||
gfileOpenStringFromStaticGFILE(&f, (char *)buf);
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
res = vfscang(&f, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int vsscang(const char *buf, const char *fmt, va_list arg) {
|
|
||||||
GFILE f;
|
|
||||||
|
|
||||||
f.flags = GFILEFLG_READ;
|
|
||||||
gfileOpenStringFromStaticGFILE(&f, (char *)buf);
|
|
||||||
|
|
||||||
return vfscang(&f, fmt, arg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
* http://ugfx.org/license.html
|
* http://ugfx.org/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is included by src/gfile/gfile.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Stdio Emulation Routines
|
* Stdio Emulation Routines
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GFILE && GFILE_NEED_STDIO
|
||||||
|
|
||||||
size_t gstdioRead(void * ptr, size_t size, size_t count, FILE *f) {
|
size_t gstdioRead(void * ptr, size_t size, size_t count, FILE *f) {
|
||||||
return gfileRead(f, ptr, size*count)/size;
|
return gfileRead(f, ptr, size*count)/size;
|
||||||
}
|
}
|
||||||
@ -43,3 +43,5 @@ int gstdioGetpos(FILE *f, long int *pos) {
|
|||||||
*pos = f->pos;
|
*pos = f->pos;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif //GFX_USE_GFILE && GFILE_NEED_STDIO
|
||||||
|
@ -5,14 +5,16 @@
|
|||||||
* http://ugfx.org/license.html
|
* http://ugfx.org/license.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is included by src/gfile/gfile.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* The virtual string file VMT
|
* The virtual string file
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GFILE && GFILE_NEED_STRINGS
|
||||||
|
|
||||||
|
#include "gfile_fs.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// Special String VMT
|
// Special String VMT
|
||||||
@ -34,8 +36,8 @@ static int StringWrite(GFILE *f, const void *buf, int size) {
|
|||||||
((char *)f->obj)[f->pos+size] = 0;
|
((char *)f->obj)[f->pos+size] = 0;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GFILEVMT StringVMT = {
|
static const GFILEVMT StringVMT = {
|
||||||
0, // next
|
|
||||||
0, // flags
|
0, // flags
|
||||||
'_', // prefix
|
'_', // prefix
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
@ -60,10 +62,77 @@ GFILE *gfileOpenString(char *str, const char *mode) {
|
|||||||
GFILE *f;
|
GFILE *f;
|
||||||
|
|
||||||
// Get an empty file and set the flags
|
// Get an empty file and set the flags
|
||||||
if (!(f = findemptyfile(mode)))
|
if (!(f = _gfileFindSlot(mode)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// File is open - fill in all the details
|
// File is open - fill in all the details
|
||||||
gfileOpenStringFromStaticGFILE(f, str);
|
gfileOpenStringFromStaticGFILE(f, str);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GFILE_NEED_PRINTG
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
maxlen += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.flags = GFILEFLG_WRITE|GFILEFLG_TRUNC;
|
||||||
|
gfileOpenStringFromStaticGFILE(&f, buf);
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
res = vfnprintg(&f, maxlen-1, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
int vsnprintg(char *buf, int maxlen, const char *fmt, va_list arg) {
|
||||||
|
GFILE f;
|
||||||
|
|
||||||
|
if (maxlen <= 1) {
|
||||||
|
if (maxlen == 1) {
|
||||||
|
*buf = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
maxlen += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.flags = GFILEFLG_WRITE|GFILEFLG_TRUNC;
|
||||||
|
gfileOpenStringFromStaticGFILE(&f, buf);
|
||||||
|
|
||||||
|
return vfnprintg(&f, maxlen-1, fmt, arg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GFILE_NEED_SCANG
|
||||||
|
int sscang(const char *buf, const char *fmt, ...) {
|
||||||
|
int res;
|
||||||
|
GFILE f;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
f.flags = GFILEFLG_READ;
|
||||||
|
gfileOpenStringFromStaticGFILE(&f, (char *)buf);
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
res = vfscang(&f, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsscang(const char *buf, const char *fmt, va_list arg) {
|
||||||
|
GFILE f;
|
||||||
|
|
||||||
|
f.flags = GFILEFLG_READ;
|
||||||
|
gfileOpenStringFromStaticGFILE(&f, (char *)buf);
|
||||||
|
|
||||||
|
return vfscang(&f, fmt, arg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //GFX_USE_GFILE && GFILE_NEED_STRINGS
|
||||||
|
@ -31,13 +31,8 @@
|
|||||||
* @brief A file pointer
|
* @brief A file pointer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef GFILE_IMPLEMENTATION
|
typedef struct GFILE GFILE;
|
||||||
typedef void GFILE;
|
typedef struct gfileList gfileList;
|
||||||
typedef void gfileList;
|
|
||||||
#else
|
|
||||||
typedef struct GFILE GFILE;
|
|
||||||
typedef struct gfileList gfileList;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern GFILE *gfileStdIn;
|
extern GFILE *gfileStdIn;
|
||||||
extern GFILE *gfileStdErr;
|
extern GFILE *gfileStdErr;
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
GFXSRC += $(GFXLIB)/src/gfile/gfile.c \
|
GFXSRC += $(GFXLIB)/src/gfile/gfile.c \
|
||||||
|
$(GFXLIB)/src/gfile/inc_nativefs.c \
|
||||||
|
$(GFXLIB)/src/gfile/inc_ramfs.c \
|
||||||
|
$(GFXLIB)/src/gfile/inc_romfs.c \
|
||||||
|
$(GFXLIB)/src/gfile/inc_fatfs.c \
|
||||||
|
$(GFXLIB)/src/gfile/inc_memfs.c \
|
||||||
|
$(GFXLIB)/src/gfile/inc_chibiosfs.c \
|
||||||
|
$(GFXLIB)/src/gfile/inc_strings.c \
|
||||||
|
$(GFXLIB)/src/gfile/inc_printg.c \
|
||||||
|
$(GFXLIB)/src/gfile/inc_scang.c \
|
||||||
|
$(GFXLIB)/src/gfile/inc_stdio.c \
|
||||||
$(GFXLIB)/src/gfile/fatfs_wrapper.c \
|
$(GFXLIB)/src/gfile/fatfs_wrapper.c \
|
||||||
$(GFXLIB)/src/gfile/fatfs_chibios_diskio.c
|
$(GFXLIB)/src/gfile/fatfs_chibios_diskio.c
|
||||||
|
Loading…
Reference in New Issue
Block a user