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.