aboutsummaryrefslogtreecommitdiffstats
path: root/src/gfile/gfile_gfile.c
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2014-08-20 17:42:53 +1000
committerinmarket <andrewh@inmarket.com.au>2014-08-20 17:42:53 +1000
commit0f3f8f68f87233bf59c3fa68c3dfe1f492a1a478 (patch)
tree3dc625e7dfcfc620e83827ccd18423be1b5334f4 /src/gfile/gfile_gfile.c
parentfcbb66a9394eaf4059bc942df6729b4b55a057d8 (diff)
downloaduGFX-0f3f8f68f87233bf59c3fa68c3dfe1f492a1a478.tar.gz
uGFX-0f3f8f68f87233bf59c3fa68c3dfe1f492a1a478.tar.bz2
uGFX-0f3f8f68f87233bf59c3fa68c3dfe1f492a1a478.zip
Rename lots of files to help prevent compile time name conflicts.
Diffstat (limited to 'src/gfile/gfile_gfile.c')
-rw-r--r--src/gfile/gfile_gfile.c407
1 files changed, 407 insertions, 0 deletions
diff --git a/src/gfile/gfile_gfile.c b/src/gfile/gfile_gfile.c
new file mode 100644
index 00000000..3547f861
--- /dev/null
+++ b/src/gfile/gfile_gfile.c
@@ -0,0 +1,407 @@
+/*
+ * 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_gfile.c
+ * @brief GFILE code.
+ *
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GFILE
+
+#include "gfile_fs.h"
+
+/**
+ * Define the VMT's for the file-systems we want to search for files.
+ * 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
+
+
+/**
+ * The order of the file-systems below determines the order
+ * that they are searched to find a file.
+ */
+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 table of GFILE's
+ */
+static GFILE gfileArr[GFILE_MAX_GFILES];
+GFILE *gfileStdIn;
+GFILE *gfileStdOut;
+GFILE *gfileStdErr;
+
+/**
+ * The init routine
+ */
+void _gfileInit(void) {
+ #if GFILE_NEED_NATIVEFS
+ extern void _gfileNativeAssignStdio(void);
+ _gfileNativeAssignStdio();
+ #endif
+}
+
+void _gfileDeinit(void)
+{
+ /* ToDo */
+}
+
+/**
+ * Internal routine to find an empty GFILE slot and interpret flags.
+ */
+GFILE *_gfileFindSlot(const char *mode) {
+ GFILE * f;
+
+ // First find an available GFILE slot.
+ for (f = gfileArr; f < &gfileArr[GFILE_MAX_GFILES]; f++) {
+ if (!(f->flags & GFILEFLG_OPEN)) {
+ // Get the flags
+ switch(mode[0]) {
+ case 'r':
+ f->flags = GFILEFLG_READ|GFILEFLG_MUSTEXIST;
+ while (*++mode) {
+ switch(mode[0]) {
+ case '+': f->flags |= GFILEFLG_WRITE; break;
+ case 'b': f->flags |= GFILEFLG_BINARY; break;
+ }
+ }
+ break;
+ case 'w':
+ f->flags = GFILEFLG_WRITE|GFILEFLG_TRUNC;
+ while (*++mode) {
+ switch(mode[0]) {
+ case '+': f->flags |= GFILEFLG_READ; break;
+ case 'b': f->flags |= GFILEFLG_BINARY; break;
+ case 'x': f->flags |= GFILEFLG_MUSTNOTEXIST; break;
+ }
+ }
+ break;
+ case 'a':
+ f->flags = GFILEFLG_WRITE|GFILEFLG_APPEND;
+ while (*++mode) {
+ switch(mode[0]) {
+ case '+': f->flags |= GFILEFLG_READ; break;
+ case 'b': f->flags |= GFILEFLG_BINARY; break;
+ case 'x': f->flags |= GFILEFLG_MUSTNOTEXIST; break;
+ }
+ }
+ break;
+ default:
+ return 0;
+ }
+ return f;
+ }
+ }
+ 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) {
+ // If we want write but the fs doesn't allow it then return
+ if ((f->flags & GFILEFLG_WRITE) && !(p->flags & GFSFLG_WRITEABLE))
+ return FALSE;
+
+ // Try to open
+ if (!p->open || !p->open(f, fname))
+ return FALSE;
+
+ // File is open - fill in all the details
+ f->vmt = p;
+ f->pos = 0;
+ f->flags |= GFILEFLG_OPEN;
+ if (p->flags & GFSFLG_SEEKABLE)
+ f->flags |= GFILEFLG_CANSEEK;
+ return TRUE;
+}
+
+GFILE *gfileOpen(const char *fname, const char *mode) {
+ GFILE * f;
+ const GFILEVMT * const *p;
+
+ // Get an empty file and set the flags
+ if (!(f = _gfileFindSlot(mode)))
+ return 0;
+
+ #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 testopen(p[0], f, fname+2) ? f : 0;
+ }
+
+ // File not found
+ return 0;
+ }
+ #endif
+
+ for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
+ if (testopen(p[0], f, fname))
+ return f;
+ }
+
+ // File not found
+ return 0;
+}
+
+void gfileClose(GFILE *f) {
+ if (!f || !(f->flags & GFILEFLG_OPEN))
+ return;
+ if (f->vmt->close)
+ f->vmt->close(f);
+ f->flags = 0;
+}
+
+size_t gfileRead(GFILE *f, void *buf, size_t len) {
+ size_t res;
+
+ if (!f || (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 void *buf, size_t len) {
+ size_t res;
+
+ if (!f || (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) {
+ if (!f || !(f->flags & GFILEFLG_OPEN))
+ return 0;
+ return f->pos;
+}
+
+bool_t gfileSetPos(GFILE *f, long int pos) {
+ if (!f || !(f->flags & GFILEFLG_OPEN))
+ return FALSE;
+ if (!f->vmt->setpos || !f->vmt->setpos(f, pos))
+ return FALSE;
+ f->pos = pos;
+ return TRUE;
+}
+
+long int gfileGetSize(GFILE *f) {
+ if (!f || !(f->flags & GFILEFLG_OPEN))
+ return 0;
+ if (!f->vmt->getsize)
+ return 0;
+ return f->vmt->getsize(f);
+}
+
+bool_t gfileEOF(GFILE *f) {
+ if (!f || !(f->flags & GFILEFLG_OPEN))
+ return TRUE;
+ if (!f->vmt->eof)
+ return FALSE;
+ return f->vmt->eof(f);
+}
+
+bool_t gfileMount(char fs, const char* drive) {
+ const GFILEVMT * const *p;
+
+ // Find the correct VMT
+ for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
+ if (p[0]->prefix == fs) {
+ if (!p[0]->mount)
+ return FALSE;
+ return p[0]->mount(drive);
+ }
+ }
+ return FALSE;
+}
+
+bool_t gfileUnmount(char fs, const char* drive) {
+ const GFILEVMT * const *p;
+
+ // Find the correct VMT
+ for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
+ if (p[0]->prefix == fs) {
+ if (!p[0]->mount)
+ return FALSE;
+ return p[0]->unmount(drive);
+ }
+ }
+ return FALSE;
+}
+
+bool_t gfileSync(GFILE *f) {
+ if (!f->vmt->sync)
+ return FALSE;
+ return f->vmt->sync(f);
+}
+
+#if GFILE_NEED_FILELISTS
+ gfileList *gfileOpenFileList(char fs, const char *path, bool_t dirs) {
+ const GFILEVMT * const *p;
+ gfileList * pfl;
+
+ // Find the correct VMT
+ for(p = FsArray; p < &FsArray[sizeof(FsArray)/sizeof(FsArray[0])]; p++) {
+ if (p[0]->prefix == fs) {
+ if (!p[0]->flopen)
+ return 0;
+ pfl = p[0]->flopen(path, dirs);
+ if (pfl) {
+ pfl->vmt = p[0];
+ pfl->dirs = dirs;
+ }
+ return pfl;
+ }
+ }
+ return 0;
+ }
+
+ const char *gfileReadFileList(gfileList *pfl) {
+ return pfl->vmt->flread ? pfl->vmt->flread(pfl) : 0;
+ }
+
+ void gfileCloseFileList(gfileList *pfl) {
+ if (pfl->vmt->flclose)
+ pfl->vmt->flclose(pfl);
+ }
+#endif
+
+#endif /* GFX_USE_GFILE */