Add support for GFILEs based on BaseFileStreams and Memory Pointers

ugfx_release_2.6
inmarket 2014-02-07 01:34:38 +10:00
parent 9ef10b9ec6
commit e72e270538
5 changed files with 194 additions and 17 deletions

View File

@ -21,7 +21,7 @@
#include "gfx.h"
#if GFX_USE_GMISC || defined(__DOXYGEN__)
#if GFX_USE_GFILE || defined(__DOXYGEN__)
/*===========================================================================*/
/* Type definitions */
@ -99,6 +99,13 @@ extern "C" {
long int gfileGetSize(GFILE *f);
bool_t gfileEOF(GFILE *f);
#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS
GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, const char *mode);
#endif
#if GFILE_NEED_MEMFS
GFILE * gfileOpenMemory(void *memptr, const char *mode);
#endif
#if GFILE_NEED_PRINTG
int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg);
int fnprintg(GFILE *f, int maxlen, const char *fmt, ...);
@ -192,8 +199,8 @@ extern "C" {
}
#endif
#endif /* GFX_USE_MISC */
#endif /* GFX_USE_GFILE */
#endif /* _GMISC_H */
#endif /* _GFILE_H */
/** @} */

View File

@ -43,13 +43,6 @@
#ifndef GFILE_NEED_STRINGS
#define GFILE_NEED_STRINGS FALSE
#endif
/**
* @brief Include scang, fscang, sscang etc functions
* @details Defaults to FALSE
*/
#ifndef GFILE_NEED_SCANG
#define GFILE_NEED_SCANG FALSE
#endif
/**
* @brief Map many stdio functions to their GFILE equivalent
* @details Defaults to FALSE
@ -108,6 +101,28 @@
#ifndef GFILE_NEED_NATIVEFS
#define GFILE_NEED_NATIVEFS FALSE
#endif
/**
* @brief Include ChibiOS BaseFileStream support
* @details Defaults to FALSE
* @pre This is only relevant on the ChibiOS operating system.
* @note Use the @p gfileOpenBaseFileStream() call to open a GFILE based on a
* BaseFileStream. The BaseFileStream must already be open.
* @note A GFile of this type cannot be opened by filename. The BaseFileStream
* must be pre-opened using the operating system.
*/
#ifndef GFILE_NEED_CHIBIOSFS
#define GFILE_NEED_CHIBIOSFS FALSE
#endif
/**
* @brief Include raw memory pointer support
* @details Defaults to FALSE
* @note Use the @p gfileOpenMemory() call to open a GFILE based on a
* memory pointer. The GFILE opened appears to be of unlimited size.
* @note A GFile of this type cannot be opened by filename.
*/
#ifndef GFILE_NEED_MEMFS
#define GFILE_NEED_MEMFS FALSE
#endif
/**
* @}
*
@ -137,12 +152,6 @@
#ifndef GFILE_MAX_GFILES
#define GFILE_MAX_GFILES 3
#endif
/**
* @brief The size in bytes of the RAM file system
*/
#ifndef GFILE_RAMFS_SIZE
#define GFILE_RAMFS_SIZE 0
#endif
/** @} */
#endif /* _GFILE_OPTIONS_H */

View File

@ -31,6 +31,20 @@ GFILE *gfileStdErr;
* The last defined is the first searched.
*/
/********************************************************
* The ChibiOS BaseFileStream VMT
********************************************************/
#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
********************************************************/
@ -297,6 +311,66 @@ GFILE *gfileOpen(const char *fname, const char *mode) {
return FALSE;
}
#if GFILE_NEED_CHIBIOSFS && GFX_USE_OS_CHIBIOS
GFILE * gfileOpenBaseFileStream(void *BaseFileStreamPtr, 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
if (!(f->flags = mode2flags(mode)))
return FALSE;
// If we want write but the fs doesn't allow it then return
if ((f->flags & GFILEFLG_WRITE) && !(FsCHIBIOSVMT.flags & GFSFLG_WRITEABLE))
return FALSE;
// File is open - fill in all the details
f->vmt = &FsCHIBIOSVMT;
f->fd = BaseFileStreamPtr;
f->err = 0;
f->pos = 0;
f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK;
return TRUE;
}
}
// No available slot
return FALSE;
}
#endif
#if GFILE_NEED_MEMFS
GFILE * gfileOpenMemory(void *memptr, 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
if (!(f->flags = mode2flags(mode)))
return FALSE;
// If we want write but the fs doesn't allow it then return
if ((f->flags & GFILEFLG_WRITE) && !(FsMemVMT.flags & GFSFLG_WRITEABLE))
return FALSE;
// File is open - fill in all the details
f->vmt = &FsMemVMT;
f->fd = memptr;
f->err = 0;
f->pos = 0;
f->flags |= GFILEFLG_OPEN|GFILEFLG_CANSEEK;
return TRUE;
}
}
// No available slot
return FALSE;
}
#endif
void gfileClose(GFILE *f) {
if (!f || !(f->flags & GFILEFLG_OPEN))
return;
@ -357,7 +431,7 @@ bool_t gfileEOF(GFILE *f) {
if (!f || !(f->flags & GFILEFLG_OPEN))
return TRUE;
if (!f->vmt->eof)
return TRUE;
return FALSE;
return f->vmt->eof(f);
}

View File

@ -0,0 +1,46 @@
/*
* 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
*/
/**
* This file is included by src/gfile/gfile.c
*/
/********************************************************
* The ChibiOS BaseFileStream file-system VMT
********************************************************/
static void ChibiOSBFSClose(GFILE *f);
static int ChibiOSBFSRead(GFILE *f, char *buf, int size);
static int ChibiOSBFSWrite(GFILE *f, char *buf, int size);
static bool_t ChibiOSBFSSetpos(GFILE *f, long int pos);
static long int ChibiOSBFSGetsize(GFILE *f);
static bool_t ChibiOSBFSEof(GFILE *f);
static const GFILEVMT FsCHIBIOSVMT = {
0, // next
GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags
0, // prefix
0, 0, 0, 0,
0, ChibiOSBFSClose, ChibiOSBFSRead, ChibiOSBFSWrite,
ChibiOSBFSSetpos, ChibiOSBFSGetsize, ChibiOSBFSEof,
};
static void ChibiOSBFSClose(GFILE *f) {
chFileStreamClose(((BaseFileStream *)f->fd));
}
static int ChibiOSBFSRead(GFILE *f, char *buf, int size) {
return chSequentialStreamRead(((BaseFileStream *)f->fd), (uint8_t *)buf, size);
}
static int ChibiOSBFSWrite(GFILE *f, char *buf, int size) {
return chSequentialStreamWrite(((BaseFileStream *)f->fd), (uint8_t *)buf, size);
}
static bool_t ChibiOSBFSSetpos(GFILE *f, long int pos) {
chFileStreamSeek(((BaseFileStream *)f->fd), pos);
return TRUE;
}
static long int ChibiOSBFSGetsize(GFILE *f) { return chFileStreamGetSize(((BaseFileStream *)f->fd)); }
static bool_t ChibiOSBFSEof(GFILE *f) { return f->pos >= chFileStreamGetSize(((BaseFileStream *)f->fd)); }

View File

@ -0,0 +1,41 @@
/*
* 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
*/
/**
* This file is included by src/gfile/gfile.c
*/
/********************************************************
* The Memory pointer file-system VMT
********************************************************/
#include <string.h>
static int MEMRead(GFILE *f, char *buf, int size);
static int MEMWrite(GFILE *f, char *buf, int size);
static bool_t MEMSetpos(GFILE *f, long int pos);
static const GFILEVMT FsMemVMT = {
0, // next
GFSFLG_SEEKABLE|GFSFLG_WRITEABLE, // flags
0, // prefix
0, 0, 0, 0,
0, 0, MEMRead, MEMWrite,
MEMSetpos, 0, 0,
};
static int MEMRead(GFILE *f, char *buf, int size) {
memset(buf, ((char *)f->fd)+f->pos, size);
return size;
}
static int MEMWrite(GFILE *f, char *buf, int size) {
memset(((char *)f->fd)+f->pos, buf, size);
return size;
}
static bool_t MEMSetpos(GFILE *f, long int pos) {
return TRUE;
}