|
@@ -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;
|
|
|
}
|