Made the memory backend, should somewhat work

This commit is contained in:
Godzil 2022-05-26 15:18:16 +01:00
parent 8fd7ab33fc
commit 52c1735ea1
7 changed files with 268 additions and 28 deletions

View File

@ -10,6 +10,15 @@
#define MINIFFS_H #define MINIFFS_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#define MINIFFS_VERSION_MAJOR (1)
#define MINIFFS_VERSION_MINOR (0)
#define MINIFFS_FILENAME_LENGTH (8)
#define MINIFFS_EXTENSION_LENGTH (3)
/* the full name is FILENAME + '.' + EXTENSION */
#define MINIFFS_FULLNAME_LENGTH (MINIFFS_FILENAME_LENGTH + MINIFFS_EXTENSION_LENGTH + 1)
/* /*
* The pack(1) may not be needed, but better be safe than sorry to * The pack(1) may not be needed, but better be safe than sorry to
@ -18,8 +27,8 @@
#pragma pack(1) #pragma pack(1)
typedef struct fileentry_t typedef struct fileentry_t
{ {
char name[8]; char name[MINIFFS_FILENAME_LENGTH];
char ext[3]; char ext[MINIFFS_EXTENSION_LENGTH];
uint32_t size; uint32_t size;
uint32_t offset; uint32_t offset;
} fileentry_t; } fileentry_t;
@ -27,6 +36,10 @@ typedef struct fileentry_t
typedef struct miniffs_header_t typedef struct miniffs_header_t
{ {
uint32_t magic; uint32_t magic;
uint8_t fs_version_major;
uint8_t fs_version_minor;
uint8_t fs_filename_len;
uint8_t fs_extention_len;
uint32_t entry_count; uint32_t entry_count;
fileentry_t fent[]; fileentry_t fent[];
} miniffs_header_t; } miniffs_header_t;
@ -49,9 +62,9 @@ typedef struct file_t
} file_t; } file_t;
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define MAKE4(_a, _b, _c, _d) (((_a) & 0xFF) << 24) | (((_b) & 0xFF) << 16) | (((_c) & 0xFF) << 8) | ((_d) & 0xFF) #define MAKE4(_a, _b, _c, _d) ((((_a) & 0xFF) << 24) | (((_b) & 0xFF) << 16) | (((_c) & 0xFF) << 8) | ((_d) & 0xFF))
#else #else
#define MAKE4(_d, _c, _b, _a) (((_a) & 0xFF) << 24) | (((_b) & 0xFF) << 16) | (((_c) & 0xFF) << 8) | ((_d) & 0xFF) #define MAKE4(_d, _c, _b, _a) ((((_a) & 0xFF) << 24) | (((_b) & 0xFF) << 16) | (((_c) & 0xFF) << 8) | ((_d) & 0xFF))
#endif #endif
#define MINIFFS_MAGIC MAKE4('M', 'F', 'F', 'S') #define MINIFFS_MAGIC MAKE4('M', 'F', 'F', 'S')
@ -67,18 +80,23 @@ enum {
*/ */
/* miniffs_openfs is backend specific and will be found in the backend header file */ /* miniffs_openfs is backend specific and will be found in the backend header file */
file_t *miniffs_open(miniffs_t *fs, char *filename); /***< Open a file */ file_t *miniffs_open(miniffs_t *fs, char *filename); /***< Open a file */
int miniffs_close(file_t *file); /***< Close a file */ int miniffs_close(file_t *file); /***< Close a file */
void *miniffs_map(file_t *file); /***< Map a file to memory */ void *miniffs_map(file_t *file); /***< Map a file to memory */
int miniffs_read(void *ptr, size_t size, size_t nmemb, file_t *file); /***< Read bytes from a file */ int miniffs_read_blocks(void *ptr, size_t size, size_t nmemb, file_t *file); /***< Read blocks of bytes from a file */
int miniffs_seek(file_t *file, size_t offset, int whence); /***< Set position in a file */ uint8_t miniffs_read(file_t *file); /***< Read a single byte from a file */
size_t miniffs_tell(file_t *file); /***< Get current position in a file*/ int miniffs_seek(file_t *file, size_t offset, int whence); /***< Set position in a file */
size_t miniffs_tell(file_t *file); /***< Get current position in a file*/
typedef enum miniffs_error_t typedef enum miniffs_error_t
{ {
MINIFFS_NOERROR = 0, MINIFFS_NOERROR = 0,
MINIFFS_INVALID_FS, MINIFFS_INVALID_FS,
MINIFFS_INVALID_NAME,
MINIFFS_INVALID_PARAMS,
MINIFFS_FILE_NOT_FOUND, MINIFFS_FILE_NOT_FOUND,
MINIFFS_ALLOCATION_ERROR,
MINIFFS_END_OF_FILE,
//MINIFFS_, //MINIFFS_,
} miniffs_error_t; } miniffs_error_t;
@ -99,9 +117,10 @@ int miniffs_closefs(miniffs_t *fs);
/* /*
* Function that are private to the library * Function that are private to the library
*/ */
int miniffs_checkfs(miniffs_t *fs); bool miniffs_isvalidfs(miniffs_t *fs);
fileentry_t *miniffs_findfile(miniffs_t *fs, char *filename); fileentry_t *miniffs_findfile(miniffs_t *fs, char *filename);
void miniffs_seterror(miniffs_error_t err);
void *miniffs_getfileaddr(miniffs_t *fs, fileentry_t *fent);
#endif /* __miniffs_internal */ #endif /* __miniffs_internal */
#endif /* MINIFFS_H */ #endif /* MINIFFS_H */

View File

@ -15,8 +15,8 @@
#ifdef BUILD_HOST_TOOLS #ifdef BUILD_HOST_TOOLS
typedef struct fs_fent_t typedef struct fs_fent_t
{ {
char name[8]; char name[MINIFFS_FILENAME_LENGTH];
char ext[3]; char ext[MINIFFS_EXTENSION_LENGTH];
bool deleted; bool deleted;
bool mapped; bool mapped;
uint32_t size; uint32_t size;
@ -27,6 +27,7 @@ typedef struct fs_fent_t
typedef struct miniffs_t typedef struct miniffs_t
{ {
miniffs_header_t *header; miniffs_header_t *header;
#ifdef BUILD_HOST_TOOLS #ifdef BUILD_HOST_TOOLS
uint32_t file_count; /***< Number of valid files in the list */ uint32_t file_count; /***< Number of valid files in the list */
uint32_t file_list_count; /***< Number of items in the list */ uint32_t file_list_count; /***< Number of items in the list */
@ -35,9 +36,11 @@ typedef struct miniffs_t
#endif #endif
} miniffs_t; } miniffs_t;
size_t host_map_file(char *filename, char **dest);
void host_unmap_file(char **dest, size_t length);
miniffs_t *miniffs_openfs(char *host_file); /***< Open a MiniFFS filesystem */ miniffs_t *miniffs_openfs(char *host_file); /***< Open a MiniFFS filesystem */
#ifdef __miniffs_internal
size_t host_map_file(char *filename, char **dest);
void host_unmap_file(char **dest, size_t length);
#endif
#endif /* MINIFFS_PLATFORM_FILE_H */ #endif /* MINIFFS_PLATFORM_FILE_H */

View File

@ -15,4 +15,6 @@ typedef struct miniffs_t
void *memoryOffset; void *memoryOffset;
} miniffs_t; } miniffs_t;
miniffs_t *miniffs_openfs(uintptr_t address); /***< Open a MiniFFS filesystem */
#endif /* MINIFFS_PLATFORM_MEMORY_H */ #endif /* MINIFFS_PLATFORM_MEMORY_H */

170
miniffs.c
View File

@ -6,16 +6,180 @@
* *
******************************************************************************/ ******************************************************************************/
#include <stdlib.h>
#include <string.h>
#define __miniffs_internal #define __miniffs_internal
#include <miniffs.h> #include <miniffs.h>
int miniffs_checkfs(miniffs_t *fs) static miniffs_error_t last_error = MINIFFS_NOERROR;
/* Public API */
file_t *miniffs_open(miniffs_t *fs, char *filename)
{ {
return 0; file_t *ret = (file_t *)calloc(1, sizeof(file_t));
if (ret == NULL)
{
miniffs_seterror(MINIFFS_ALLOCATION_ERROR);
goto exit;
}
ret->private = fs;
ret->fent = miniffs_findfile(fs, filename);
if (!ret->fent)
{
miniffs_seterror(MINIFFS_FILE_NOT_FOUND);
goto free_and_exit;
}
ret->offset = 0;
goto exit;
free_and_exit:
free(ret);
ret = NULL;
exit:
return ret;
}
int miniffs_close(file_t *file)
{
/* Let's poison the struct */
file->private = NULL;
file->offset = 0;
file->fent = NULL;
free(file);
}
void *miniffs_map(file_t *file)
{
miniffs_t *fs = (miniffs_t *)file->private;
return miniffs_getfileaddr(fs, file->fent);
}
uint8_t miniffs_read(file_t *file)
{
miniffs_t *fs = (miniffs_t *) file->private;
uint8_t *filePtr = miniffs_getfileaddr(fs, file->fent);
uint8_t ret = filePtr[file->offset];
file->offset++;
if (file->offset >= file->fent->size)
{
miniffs_seterror(MINIFFS_END_OF_FILE);
file->offset = file->fent->size - 1;
}
return ret;
}
int miniffs_read_blocks(void *ptr, size_t size, size_t nmemb, file_t *file)
{
int i;
miniffs_t *fs = (miniffs_t *) file->private;
uint8_t *filePtr = miniffs_getfileaddr(fs, file->fent);
size_t fileOffset = file->offset;
size_t bufferOffset = 0;
int blockCount = 0;
for(i = 0; i < nmemb; i++)
{
if (file->fent->size > (fileOffset + size))
{
memcpy(ptr + bufferOffset, &filePtr[fileOffset], size);
bufferOffset += size;
fileOffset += size;
blockCount++;
}
}
file->offset = fileOffset;
return blockCount;
}
int miniffs_seek(file_t *file, size_t offset, int whence)
{
switch(whence)
{
default:
miniffs_seterror(MINIFFS_INVALID_PARAMS);
return -1;
case MFFS_SEEK_SET:
file->offset = offset;
break;
case MFFS_SEEK_CUR:
file->offset += offset;
break;
case MFFS_SEEK_END:
file->offset = file->fent->size - offset;
break;
}
}
size_t miniffs_tell(file_t *file)
{
return file->offset;
}
miniffs_error_t miniffs_geterror()
{
return last_error;
}
/* Private API */
bool miniffs_isvalidfs(miniffs_t *fs)
{
return (fs->header->magic == MINIFFS_MAGIC) &&
(fs->header->fs_version_major == MINIFFS_VERSION_MAJOR) &&
(fs->header->fs_version_minor == MINIFFS_VERSION_MINOR) &&
(fs->header->fs_filename_len == MINIFFS_FILENAME_LENGTH) &&
(fs->header->fs_extention_len == MINIFFS_EXTENSION_LENGTH);
}
static void make_fullname(char *name, char *ext, char *out)
{
uint8_t nameLen = strnlen(name, MINIFFS_FILENAME_LENGTH);
uint8_t extLen = strnlen(ext, MINIFFS_EXTENSION_LENGTH);
memcpy(out, name, nameLen);
memcpy(out + nameLen, ".", 1);
memcpy(out + nameLen + 1, ext, extLen);
} }
fileentry_t *miniffs_findfile(miniffs_t *fs, char *filename) fileentry_t *miniffs_findfile(miniffs_t *fs, char *filename)
{ {
int i;
char entryFullName[MINIFFS_FULLNAME_LENGTH];
uint8_t filenameLength = strlen(filename);
fileentry_t *ret = NULL;
if (filenameLength > MINIFFS_FULLNAME_LENGTH)
{
miniffs_seterror(MINIFFS_INVALID_NAME);
goto exit;
}
return NULL; for(i = 0; i < fs->header->entry_count; i++)
{
fileentry_t *cur = &fs->header->fent[i];
make_fullname(cur->name, cur->ext, entryFullName);
if (memcmp(filename, entryFullName, filenameLength) == 0)
{
/* File found! */
ret = cur;
break;
}
}
exit:
return ret;
}
void miniffs_seterror(miniffs_error_t err)
{
last_error = err;
} }

View File

@ -8,11 +8,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#ifdef _WIN32
#include <string.h> #include <string.h>
#endif
#define __miniffs_internal
#include <miniffs.h> #include <miniffs.h>
miniffs_t *miniffs_createfs() miniffs_t *miniffs_createfs()
@ -28,8 +26,8 @@ miniffs_t *miniffs_createfs()
int miniffs_addfile(miniffs_t *fs, char *name, char *ext, char *host_path) int miniffs_addfile(miniffs_t *fs, char *name, char *ext, char *host_path)
{ {
fs_fent_t *cur; fs_fent_t *cur;
uint8_t nameLen = strnlen(name, 8); uint8_t nameLen = strnlen(name, MINIFFS_FILENAME_LENGTH);
uint8_t extLen = strnlen(ext, 3); uint8_t extLen = strnlen(ext, MINIFFS_EXTENSION_LENGTH);
if (fs->file_list_count == fs->file_list_size) if (fs->file_list_count == fs->file_list_size)
{ {
@ -69,14 +67,18 @@ int miniffs_writeimage(miniffs_t *fs, char *host_path)
header = (miniffs_header_t *)calloc(1, headerSize); header = (miniffs_header_t *)calloc(1, headerSize);
header->magic = MINIFFS_MAGIC; header->magic = MINIFFS_MAGIC;
header->fs_version_major = MINIFFS_VERSION_MAJOR;
header->fs_version_minor = MINIFFS_VERSION_MINOR;
header->fs_filename_len = MINIFFS_FILENAME_LENGTH;
header->fs_extention_len = MINIFFS_EXTENSION_LENGTH;
header->entry_count = fs->file_count; header->entry_count = fs->file_count;
for(i = 0; i < fs->file_list_count; i++) for(i = 0; i < fs->file_list_count; i++)
{ {
if (fs->files[i].deleted == false) if (fs->files[i].deleted == false)
{ {
memcpy(header->fent[fileIndex].name, fs->files[i].name, 8); memcpy(header->fent[fileIndex].name, fs->files[i].name, MINIFFS_FILENAME_LENGTH);
memcpy(header->fent[fileIndex].ext, fs->files[i].ext, 3); memcpy(header->fent[fileIndex].ext, fs->files[i].ext, MINIFFS_EXTENSION_LENGTH);
header->fent[fileIndex].size = fs->files[i].size; header->fent[fileIndex].size = fs->files[i].size;
header->fent[fileIndex].offset = filePosition; header->fent[fileIndex].offset = filePosition;
fileIndex ++; fileIndex ++;

View File

@ -18,6 +18,20 @@
#define __miniffs_internal #define __miniffs_internal
#include <miniffs.h> #include <miniffs.h>
/* Exported API */
miniffs_t *miniffs_openfs(char *host_file)
{
return NULL;
}
/* Some internal functions */
void *miniffs_getfileaddr(miniffs_t *fs, fileentry_t *fent)
{
}
size_t host_map_file(char *filename, char **dest) size_t host_map_file(char *filename, char **dest)
{ {
char *ret_ptr; char *ret_ptr;

View File

@ -7,4 +7,40 @@
******************************************************************************/ ******************************************************************************/
#define __miniffs_internal #define __miniffs_internal
#include <miniffs.h> #include <miniffs.h>
#include <stdlib.h>
/* Public API */
miniffs_t *miniffs_openfs(uintptr_t address)
{
miniffs_t *fs = (miniffs_t *)calloc(1, sizeof(miniffs_t));
if (fs == NULL)
{
miniffs_seterror(MINIFFS_ALLOCATION_ERROR);
goto exit;
}
fs->header = (miniffs_header_t *)address;
if (!miniffs_isvalidfs(fs))
{
miniffs_seterror(MINIFFS_INVALID_FS);
goto free_and_exit;
}
goto exit;
free_and_exit:
free(fs);
fs = NULL;
exit:
return fs;
}
/* Private API */
void *miniffs_getfileaddr(miniffs_t *fs, fileentry_t *fent)
{
return fs->memoryOffset + fent->offset;
}