Add support for GFILEs based on BaseFileStreams and Memory Pointers
parent
9ef10b9ec6
commit
e72e270538
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
|
|
||||||
#if GFX_USE_GMISC || defined(__DOXYGEN__)
|
#if GFX_USE_GFILE || defined(__DOXYGEN__)
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Type definitions */
|
/* Type definitions */
|
||||||
|
@ -99,6 +99,13 @@ extern "C" {
|
||||||
long int gfileGetSize(GFILE *f);
|
long int gfileGetSize(GFILE *f);
|
||||||
bool_t gfileEOF(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
|
#if GFILE_NEED_PRINTG
|
||||||
int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg);
|
int vfnprintg(GFILE *f, int maxlen, const char *fmt, va_list arg);
|
||||||
int fnprintg(GFILE *f, int maxlen, const char *fmt, ...);
|
int fnprintg(GFILE *f, int maxlen, const char *fmt, ...);
|
||||||
|
@ -192,8 +199,8 @@ extern "C" {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* GFX_USE_MISC */
|
#endif /* GFX_USE_GFILE */
|
||||||
|
|
||||||
#endif /* _GMISC_H */
|
#endif /* _GFILE_H */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
|
@ -43,13 +43,6 @@
|
||||||
#ifndef GFILE_NEED_STRINGS
|
#ifndef GFILE_NEED_STRINGS
|
||||||
#define GFILE_NEED_STRINGS FALSE
|
#define GFILE_NEED_STRINGS FALSE
|
||||||
#endif
|
#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
|
* @brief Map many stdio functions to their GFILE equivalent
|
||||||
* @details Defaults to FALSE
|
* @details Defaults to FALSE
|
||||||
|
@ -108,6 +101,28 @@
|
||||||
#ifndef GFILE_NEED_NATIVEFS
|
#ifndef GFILE_NEED_NATIVEFS
|
||||||
#define GFILE_NEED_NATIVEFS FALSE
|
#define GFILE_NEED_NATIVEFS FALSE
|
||||||
#endif
|
#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
|
#ifndef GFILE_MAX_GFILES
|
||||||
#define GFILE_MAX_GFILES 3
|
#define GFILE_MAX_GFILES 3
|
||||||
#endif
|
#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 */
|
#endif /* _GFILE_OPTIONS_H */
|
||||||
|
|
|
@ -31,6 +31,20 @@ GFILE *gfileStdErr;
|
||||||
* The last defined is the first searched.
|
* 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
|
* The RAM file-system VMT
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
@ -297,6 +311,66 @@ GFILE *gfileOpen(const char *fname, const char *mode) {
|
||||||
return FALSE;
|
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) {
|
void gfileClose(GFILE *f) {
|
||||||
if (!f || !(f->flags & GFILEFLG_OPEN))
|
if (!f || !(f->flags & GFILEFLG_OPEN))
|
||||||
return;
|
return;
|
||||||
|
@ -357,7 +431,7 @@ bool_t gfileEOF(GFILE *f) {
|
||||||
if (!f || !(f->flags & GFILEFLG_OPEN))
|
if (!f || !(f->flags & GFILEFLG_OPEN))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (!f->vmt->eof)
|
if (!f->vmt->eof)
|
||||||
return TRUE;
|
return FALSE;
|
||||||
return f->vmt->eof(f);
|
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