123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- /******************************************************************************
- * MiniFFS : Mini Flat File System
- * miniffs.c: Shared code for all platforms.
- *
- * Copyright (c) 2008-2022 986-Studio. All rights reserved.
- *
- ******************************************************************************/
- #include <stdlib.h>
- #include <string.h>
- #define __miniffs_internal
- #include <miniffs.h>
- static miniffs_error_t last_error = MINIFFS_NOERROR;
- /* Public API */
- file_t *miniffs_open(miniffs_t *fs, const char *filename)
- {
- file_t *ret = (file_t *)calloc(1, sizeof(file_t));
- if (ret == NULL)
- {
- miniffs_seterror(MINIFFS_ALLOCATION_ERROR);
- goto exit;
- }
- ret->private_data = fs;
- ret->fent = miniffs_findfile(fs, filename);
- if (!ret->fent)
- {
- if (miniffs_geterror() != MINIFFS_INVALID_NAME)
- {
- miniffs_seterror(MINIFFS_FILE_NOT_FOUND);
- }
- goto free_and_exit;
- }
- ret->offset = 0;
- miniffs_seterror(MINIFFS_NOERROR);
- 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_data = NULL;
- file->offset = 0;
- file->fent = NULL;
- free(file);
- miniffs_seterror(MINIFFS_NOERROR);
- }
- void *miniffs_map(file_t *file)
- {
- miniffs_t *fs = (miniffs_t *)file->private_data;
- miniffs_seterror(MINIFFS_NOERROR);
- return miniffs_getfileaddr(fs, file->fent);
- }
- uint8_t miniffs_read(file_t *file)
- {
- miniffs_t *fs = (miniffs_t *) file->private_data;
- 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;
- }
- else
- {
- miniffs_seterror(MINIFFS_NOERROR);
- }
- return ret;
- }
- int miniffs_write(file_t *file, char value)
- {
- miniffs_t *fs = (miniffs_t *) file->private_data;
- uint8_t *filePtr = miniffs_getfileaddr(fs, file->fent);
- filePtr[file->offset] = value;
- file->offset++;
- if (file->offset >= file->fent->size)
- {
- miniffs_seterror(MINIFFS_END_OF_FILE);
- file->offset = file->fent->size - 1;
- }
- else
- {
- miniffs_seterror(MINIFFS_NOERROR);
- }
- return 0;
- }
- int miniffs_read_blocks(void *ptr, size_t size, size_t nmemb, file_t *file)
- {
- int i;
- miniffs_t *fs = (miniffs_t *) file->private_data;
- 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;
- miniffs_seterror(MINIFFS_NOERROR);
- return blockCount;
- }
- int miniffs_seek(file_t *file, size_t offset, int whence)
- {
- bool noError = true;
- 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:
- if (file->fent->size <= offset)
- {
- /* Negative boundary check */
- noError = false;
- miniffs_seterror(MINIFFS_SEEK_OUT_OF_BOUNDARIES);
- file->offset = 0;
- }
- else
- {
- file->offset = file->fent->size - 1 - offset;
- }
- break;
- }
- if (file->offset >= file->fent->size)
- {
- /* Positive Boundary check */
- noError = false;
- miniffs_seterror(MINIFFS_SEEK_OUT_OF_BOUNDARIES);
- file->offset = file->fent->size - 1;
- }
- if (noError)
- {
- miniffs_seterror(MINIFFS_NOERROR);
- }
- }
- size_t miniffs_tell(file_t *file)
- {
- miniffs_seterror(MINIFFS_NOERROR);
- 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, const 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;
- }
- 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;
- }
- char *miniffs_getversion()
- {
- return VERSION;
- }
|