Browse Source

Made the memory backend, should somewhat work

Godzil 1 year ago
parent
commit
86acbaa30f
7 changed files with 267 additions and 27 deletions
  1. 31 12
      includes/miniffs.h
  2. 7 4
      includes/platform/file.h
  3. 2 0
      includes/platform/memory.h
  4. 167 3
      miniffs.c
  5. 9 7
      miniffs_tools.c
  6. 14 0
      platform/file.c
  7. 37 1
      platform/memory.c

+ 31 - 12
includes/miniffs.h

@@ -10,6 +10,15 @@
 #define MINIFFS_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
@@ -18,8 +27,8 @@
 #pragma pack(1)
 typedef struct fileentry_t
 {
-    char name[8];
-    char ext[3];
+    char name[MINIFFS_FILENAME_LENGTH];
+    char ext[MINIFFS_EXTENSION_LENGTH];
     uint32_t size;
     uint32_t offset;
 } fileentry_t;
@@ -27,6 +36,10 @@ typedef struct fileentry_t
 typedef struct miniffs_header_t
 {
     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;
     fileentry_t fent[];
 } miniffs_header_t;
@@ -49,9 +62,9 @@ typedef struct file_t
 } file_t;
 
 #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
-#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
 #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 */
-file_t *miniffs_open(miniffs_t *fs, char *filename);                  /***< Open a file */
-int miniffs_close(file_t *file);                                      /***< Close a file */
-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_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*/
+file_t *miniffs_open(miniffs_t *fs, char *filename);                         /***< Open a file */
+int miniffs_close(file_t *file);                                             /***< Close a file */
+void *miniffs_map(file_t *file);                                             /***< Map a file to memory */
+int miniffs_read_blocks(void *ptr, size_t size, size_t nmemb, file_t *file); /***< Read blocks of bytes from a file */
+uint8_t miniffs_read(file_t *file);                                          /***< Read a single byte from 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
 {
     MINIFFS_NOERROR = 0,
     MINIFFS_INVALID_FS,
+    MINIFFS_INVALID_NAME,
+    MINIFFS_INVALID_PARAMS,
     MINIFFS_FILE_NOT_FOUND,
+    MINIFFS_ALLOCATION_ERROR,
+    MINIFFS_END_OF_FILE,
     //MINIFFS_,
 } miniffs_error_t;
 
@@ -99,9 +117,10 @@ int miniffs_closefs(miniffs_t *fs);
 /*
  * 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);
-
+void miniffs_seterror(miniffs_error_t err);
+void *miniffs_getfileaddr(miniffs_t *fs, fileentry_t *fent);
 #endif /* __miniffs_internal */
 
 #endif /* MINIFFS_H */

+ 7 - 4
includes/platform/file.h

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

+ 2 - 0
includes/platform/memory.h

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

+ 167 - 3
miniffs.c

@@ -6,16 +6,180 @@
  *
  ******************************************************************************/
 
+#include <stdlib.h>
+#include <string.h>
+
 #define __miniffs_internal
 #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)
+{
+    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)
 {
-    return 0;
+    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)
 {
+    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;
 }

+ 9 - 7
miniffs_tools.c

@@ -8,11 +8,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
-
-#ifdef _WIN32
 #include <string.h>
-#endif
 
+#define __miniffs_internal
 #include <miniffs.h>
 
 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)
 {
     fs_fent_t *cur;
-    uint8_t nameLen = strnlen(name, 8);
-    uint8_t extLen = strnlen(ext, 3);
+    uint8_t nameLen = strnlen(name, MINIFFS_FILENAME_LENGTH);
+    uint8_t extLen = strnlen(ext, MINIFFS_EXTENSION_LENGTH);
 
     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->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;
 
     for(i = 0; i < fs->file_list_count; i++)
     {
         if (fs->files[i].deleted == false)
         {
-            memcpy(header->fent[fileIndex].name, fs->files[i].name, 8);
-            memcpy(header->fent[fileIndex].ext, fs->files[i].ext, 3);
+            memcpy(header->fent[fileIndex].name, fs->files[i].name, MINIFFS_FILENAME_LENGTH);
+            memcpy(header->fent[fileIndex].ext, fs->files[i].ext, MINIFFS_EXTENSION_LENGTH);
             header->fent[fileIndex].size = fs->files[i].size;
             header->fent[fileIndex].offset = filePosition;
             fileIndex ++;

+ 14 - 0
platform/file.c

@@ -18,6 +18,20 @@
 #define __miniffs_internal
 #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)
 {
     char *ret_ptr;

+ 37 - 1
platform/memory.c

@@ -7,4 +7,40 @@
  ******************************************************************************/
 
 #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;
+}