Add support for GFILEs based on BaseFileStreams and Memory Pointers
parent
9ef10b9ec6
commit
e72e270538
|
@ -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 */
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)); }
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue