aboutsummaryrefslogtreecommitdiffstats
path: root/src/gfile
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2014-01-24 19:33:28 +1000
committerinmarket <andrewh@inmarket.com.au>2014-01-24 19:33:28 +1000
commitc5ab2adbf0c14a6d0d4e2245a616d01de4b88214 (patch)
tree0394021132c5457d2af253b13938993b7261f418 /src/gfile
parent0d9532c0470ef6e6c5d04bbf221e3f8d543965c4 (diff)
downloaduGFX-c5ab2adbf0c14a6d0d4e2245a616d01de4b88214.tar.gz
uGFX-c5ab2adbf0c14a6d0d4e2245a616d01de4b88214.tar.bz2
uGFX-c5ab2adbf0c14a6d0d4e2245a616d01de4b88214.zip
More code for GFile
Diffstat (limited to 'src/gfile')
-rw-r--r--src/gfile/gfile.c93
-rw-r--r--src/gfile/inc_nativefs.c23
-rw-r--r--src/gfile/inc_romfs.c14
3 files changed, 113 insertions, 17 deletions
diff --git a/src/gfile/gfile.c b/src/gfile/gfile.c
index bf76e8bc..83e487a1 100644
--- a/src/gfile/gfile.c
+++ b/src/gfile/gfile.c
@@ -147,7 +147,7 @@ long int gfileGetFilesize(const char *fname) {
bool_t gfileRename(const char *oldname, const char *newname) {
const GFILEVMT *p;
- if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1])) {
+ if ((oldname[0] && oldname[1] == '|') || (newname[0] && newname[1] == '|')) {
char ch;
if (oldname[0] && oldname[1] == '|') {
@@ -155,6 +155,7 @@ bool_t gfileRename(const char *oldname, const char *newname) {
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;
}
@@ -175,12 +176,100 @@ bool_t gfileRename(const char *oldname, const char *newname) {
return FALSE;
}
+static uint16_t mode2flags(const char *mode) {
+ uint16_t flags;
+
+ switch(mode[0]) {
+ case 'r':
+ flags = GFILEFLG_READ|GFILEFLG_MUSTEXIST;
+ while (*++mode) {
+ switch(mode[0]) {
+ case '+': flags |= GFILEFLG_WRITE; break;
+ case 'b': flags |= GFILEFLG_BINARY; break;
+ }
+ }
+ return flags;
+ case 'w':
+ flags = GFILEFLG_WRITE|GFILEFLG_TRUNC;
+ while (*++mode) {
+ switch(mode[0]) {
+ case '+': flags |= GFILEFLG_READ; break;
+ case 'b': flags |= GFILEFLG_BINARY; break;
+ case 'x': flags |= GFILEFLG_MUSTNOTEXIST; break;
+ }
+ }
+ return flags;
+ case 'a':
+ flags = GFILEFLG_WRITE|GFILEFLG_APPEND;
+ while (*++mode) {
+ switch(mode[0]) {
+ case '+': flags |= GFILEFLG_READ; break;
+ case 'b': flags |= GFILEFLG_BINARY; break;
+ case 'x': flags |= GFILEFLG_MUSTNOTEXIST; break;
+ }
+ }
+ return flags;
+ }
+ return 0;
+}
+
+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->err = 0;
+ 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 *p;
+
+ // 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;
+ }
+ }
+ // File not found
+ return FALSE;
+ }
+ }
+
+ // No available slot
+ return FALSE;
}
void gfileClose(GFILE *f) {
-
+ // Make sure it is one of the system GFILE's
+ if (f < gfileArr || f >= &gfileArr[GFILE_MAX_GFILES])
+ return;
}
size_t gfileRead(GFILE *f, char *buf, size_t len) {
diff --git a/src/gfile/inc_nativefs.c b/src/gfile/inc_nativefs.c
index 7828ff84..ccf1d40a 100644
--- a/src/gfile/inc_nativefs.c
+++ b/src/gfile/inc_nativefs.c
@@ -36,11 +36,11 @@ static bool_t NativeEof(GFILE *f);
static const GFILEVMT FsNativeVMT = {
GFILE_CHAINHEAD, // next
- 'N', // prefix
#if !defined(WIN32) && !GFX_USE_OS_WIN32
GFSFLG_CASESENSITIVE|
#endif
GFSFLG_WRITEABLE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags
+ 'N', // prefix
NativeDel, NativeExists, NativeFilesize, NativeRen,
NativeOpen, NativeClose, NativeRead, NativeWrite,
NativeSetpos, NativeGetsize, NativeEof,
@@ -48,6 +48,23 @@ static const GFILEVMT FsNativeVMT = {
#undef GFILE_CHAINHEAD
#define GFILE_CHAINHEAD &FsNativeVMT
+static char *flags2mode(char *buf, uint16_t flags) {
+ if (flags & GFILEFLG_MUSTEXIST)
+ *buf = 'r';
+ else if (flags & GFILEFLG_APPEND)
+ *buf = 'a';
+ else
+ *buf = 'w';
+ buf++;
+ if ((flags & (GFILEFLG_READ|GFILEFLG_WRITE)) == (GFILEFLG_READ|GFILEFLG_WRITE))
+ *buf++ = '+';
+ if (flags & GFILEFLG_BINARY)
+ *buf++ = 'b';
+ if (flags & GFILEFLG_MUSTNOTEXIST)
+ *buf++ = 'x';
+ *buf++ = 0;
+}
+
static bool_t NativeDel(const char *fname) { return remove(fname) ? FALSE : TRUE; }
static bool_t NativeExists(const char *fname) { return access(fname, 0) ? FALSE : TRUE; }
static long int NativeFilesize(const char *fname) {
@@ -56,12 +73,12 @@ static long int NativeFilesize(const char *fname) {
return st.st_size;
}
static bool_t NativeRen(const char *oldname, const char *newname) { return rename(oldname, newname) ? FALSE : TRUE };
-static bool_t NativeOpen(GFILE *f, const char *fname, const char *mode) {
+static bool_t NativeOpen(GFILE *f, const char *fname) {
FILE *fd;
+ char mode[5];
if (!(fd = fopen(fname, mode)))
return FALSE;
- f->vmt = &FsNativeVMT;
f->obj = (void *)fd;
return TRUE;
}
diff --git a/src/gfile/inc_romfs.c b/src/gfile/inc_romfs.c
index 321dc9b1..170b9a6c 100644
--- a/src/gfile/inc_romfs.c
+++ b/src/gfile/inc_romfs.c
@@ -39,8 +39,8 @@ static bool_t ROMEof(GFILE *f);
static const GFILEVMT FsROMVMT = {
GFILE_CHAINHEAD, // next
- 'S', // prefix
GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags
+ 'S', // prefix
0, ROMExists, ROMFilesize, 0,
ROMOpen, ROMClose, ROMRead, 0,
ROMSetpos, ROMGetsize, ROMEof,
@@ -64,20 +64,10 @@ static long int ROMFilesize(const char *fname) {
if (!(p = ROMFindFile(fname))) return -1;
return p->size;
}
-static bool_t ROMOpen(GFILE *f, const char *fname, const char *mode) {
+static bool_t ROMOpen(GFILE *f, const char *fname) {
const ROMFS_DIRENTRY *p;
- // Check mode
- if (mode[0] != 'r') return FALSE;
- while(*++mode) {
- switch(*mode) {
- case '+': case 'w': case 'a':
- return FALSE;
- }
- }
-
if (!(p = ROMFindFile(fname))) return FALSE;
- f->vmt = &FsROMVMT;
f->obj = (void *)p;
return TRUE;
}