20     extern const GFILEVMT FsUSERVMT;
 
   23     extern const GFILEVMT FsROMVMT;
 
   25 #if GFILE_NEED_NATIVEFS 
   26     extern const GFILEVMT FsNativeVMT;
 
   29     extern const GFILEVMT FsFatFSVMT;
 
   32     extern const GFILEVMT FsRAMVMT;
 
   43 static const GFILEVMT* FsArray[] = {
 
   50     #if GFILE_NEED_NATIVEFS 
   72 void _gfileInit(
void) {
 
   73     #if GFILE_NEED_NATIVEFS 
   74         extern void _gfileNativeAssignStdio(
void);
 
   75         _gfileNativeAssignStdio();
 
   79 void _gfileDeinit(
void)
 
   83         if (f->flags & GFILEFLG_OPEN)
 
   91 GFILE *_gfileFindSlot(
const char *mode) {
 
   96         if (!(f->flags & GFILEFLG_OPEN)) {
 
  100                 f->flags = GFILEFLG_READ|GFILEFLG_MUSTEXIST;
 
  103                     case '+':   f->flags |= GFILEFLG_WRITE;         
break;
 
  104                     case 'b':   f->flags |= GFILEFLG_BINARY;        
break;
 
  109                 f->flags = GFILEFLG_WRITE|GFILEFLG_TRUNC;
 
  112                     case '+':   f->flags |= GFILEFLG_READ;          
break;
 
  113                     case 'b':   f->flags |= GFILEFLG_BINARY;        
break;
 
  114                     case 'x':   f->flags |= GFILEFLG_MUSTNOTEXIST;  
break;
 
  119                 f->flags = GFILEFLG_WRITE|GFILEFLG_APPEND;
 
  122                     case '+':   f->flags |= GFILEFLG_READ;          
break;
 
  123                     case 'b':   f->flags |= GFILEFLG_BINARY;        
break;
 
  124                     case 'x':   f->flags |= GFILEFLG_MUSTNOTEXIST;  
break;
 
  142     const GFILEVMT * 
const *p;
 
  144     #if GFILE_ALLOW_DEVICESPECIFIC 
  145         if (fname[0] && fname[1] == 
'|') {
 
  146             for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  147                 if (p[0]->prefix == fname[0])
 
  148                     return p[0]->exists && p[0]->exists(fname+2);
 
  154     for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  155         if (p[0]->exists && p[0]->exists(fname))
 
  164     #if GFILE_ALLOW_DEVICESPECIFIC 
  165         if (fname[0] && fname[1] == 
'|') {
 
  166             for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  167                 if (p[0]->prefix == fname[0])
 
  168                     return p[0]->del && p[0]->del(fname+2);
 
  174     for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  175         if (p[0]->del && p[0]->del(fname))
 
  182     const GFILEVMT * 
const *p;
 
  185     #if GFILE_ALLOW_DEVICESPECIFIC 
  186         if (fname[0] && fname[1] == 
'|') {
 
  187             for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  188                 if (p[0]->prefix == fname[0])
 
  189                     return p[0]->filesize ? p[0]->filesize(fname+2) : -1;
 
  191             return (gFileSize)-1;
 
  195     for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  196         if (p[0]->filesize && (res = p[0]->filesize(fname)) != -1)
 
  202 gBool 
gfileRename(
const char *oldname, 
const char *newname) {
 
  203     const GFILEVMT * 
const *p;
 
  205     #if GFILE_ALLOW_DEVICESPECIFIC 
  206         if ((oldname[0] && oldname[1] == 
'|') || (newname[0] && newname[1] == 
'|')) {
 
  209             if (oldname[0] && oldname[1] == 
'|') {
 
  212                 if (newname[0] && newname[1] == 
'|') {
 
  213                     if (newname[0] != ch)
 
  222             for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  223                 if (p[0]->prefix == ch)
 
  224                     return p[0]->ren && p[0]->ren(oldname, newname);
 
  230     for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  231         if (p[0]->ren && p[0]->ren(oldname,newname))
 
  237 static gBool testopen(
const GFILEVMT *p, 
GFILE *f, 
const char *fname) {
 
  239     if ((f->flags & GFILEFLG_WRITE) && !(p->flags & GFSFLG_WRITEABLE))
 
  243     if (!p->open || !p->open(f, fname))
 
  249     f->flags |= GFILEFLG_OPEN;
 
  250     if (p->flags & GFSFLG_SEEKABLE)
 
  251         f->flags |= GFILEFLG_CANSEEK;
 
  257     const GFILEVMT * 
const *p;
 
  260     if (!(f = _gfileFindSlot(mode)))
 
  263     #if GFILE_ALLOW_DEVICESPECIFIC 
  264         if (fname[0] && fname[1] == 
'|') {
 
  265             for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  266                 if (p[0]->prefix == fname[0])
 
  267                     return testopen(p[0], f, fname+2) ? f : 0;
 
  275     for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  276         if (testopen(p[0], f, fname))
 
  285     if (!f || !(f->flags & GFILEFLG_OPEN))
 
  295     if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_READ)) != (GFILEFLG_OPEN|GFILEFLG_READ))
 
  299     if ((res = f->vmt->read(f, buf, len)) <= 0)
 
  308     if (!f || (f->flags & (GFILEFLG_OPEN|GFILEFLG_WRITE)) != (GFILEFLG_OPEN|GFILEFLG_WRITE))
 
  312     if ((res = f->vmt->write(f, buf, len)) <= 0)
 
  319     if (!f || !(f->flags & GFILEFLG_OPEN))
 
  325     if (!f || !(f->flags & GFILEFLG_OPEN))
 
  327     if (!f->vmt->setpos || !f->vmt->setpos(f, pos))
 
  334     if (!f || !(f->flags & GFILEFLG_OPEN))
 
  336     if (!f->vmt->getsize)
 
  338     return f->vmt->getsize(f);
 
  342     if (!f || !(f->flags & GFILEFLG_OPEN))
 
  346     return f->vmt->eof(f);
 
  349 gBool 
gfileMount(
char fs, 
const char* drive) {
 
  350     const GFILEVMT * 
const *p;
 
  353     for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  354         if (p[0]->prefix == fs) {
 
  357             return p[0]->mount(drive);
 
  364     const GFILEVMT * 
const *p;
 
  367     for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  368         if (p[0]->prefix == fs) {
 
  371             return p[0]->unmount(drive);
 
  380     return f->vmt->sync(f);
 
  383 #if GFILE_NEED_FILELISTS 
  385         const GFILEVMT * 
const *p;
 
  389         for(p = FsArray; p < &FsArray[
sizeof(FsArray)/
sizeof(FsArray[0])]; p++) {
 
  390             if (p[0]->prefix == fs) {
 
  393                 pfl = p[0]->flopen(path, dirs);
 
  405         return pfl->vmt->flread ? pfl->vmt->flread(pfl) : 0;
 
  409         if (pfl->vmt->flclose)
 
  410             pfl->vmt->flclose(pfl);
 
GFILE file system header.
gBool gfileUnmount(char fs, const char *drive)
Unmount a logical drive (aka partition)
GFILE * gfileOpen(const char *fname, const char *mode)
Open file.
gBool gfileSetPos(GFILE *f, gFileSize pos)
Set the position of the read/write cursor.
gBool gfileMount(char fs, const char *drive)
Mount a logical drive (aka partition)
gBool gfileDelete(const char *fname)
Delete file.
gMemSize gfileRead(GFILE *f, void *buf, gMemSize len)
Read from file.
gBool gfileSync(GFILE *f)
Syncs the file object (flushes the buffer)
gBool gfileExists(const char *fname)
Check if file exists.
gfileList * gfileOpenFileList(char fs, const char *path, gBool dirs)
Open a file list.
#define GFILE_MAX_GFILES
The maximum number of open files.
void gfileClose(GFILE *f)
Close file.
const char * gfileReadFileList(gfileList *pfl)
Get the next file in a file list.
struct GFILE GFILE
A file pointer.
gFileSize gfileGetPos(GFILE *f)
Get the current position of the read/write cursor.
gMemSize gfileWrite(GFILE *f, const void *buf, gMemSize len)
Write to file.
void gfileCloseFileList(gfileList *pfl)
Close a file list.
gBool gfileRename(const char *oldname, const char *newname)
Rename file.
gFileSize gfileGetFilesize(const char *fname)
Get the size of a file.
gFileSize gfileGetSize(GFILE *f)
Get the size of file.
gBool gfileEOF(GFILE *f)
Check for EOF.