|
|
@@ -5,20 +5,27 @@
|
|
|
#define LUAT_LOG_TAG "fs"
|
|
|
#include "luat_log.h"
|
|
|
|
|
|
+#define BLOCK_SIZE 4096
|
|
|
+
|
|
|
+typedef struct ram_file_block
|
|
|
+{
|
|
|
+ uint8_t data[BLOCK_SIZE];
|
|
|
+ struct ram_file_block* next;
|
|
|
+} ram_file_block_t;
|
|
|
+
|
|
|
typedef struct ram_file
|
|
|
{
|
|
|
- size_t size; // 当前文件大小, 也是指针对应内存块的大小
|
|
|
- // size_t ptr_size; // 数值指针的大小
|
|
|
+ size_t size; // 当前文件大小
|
|
|
char name[32]; // 文件名称
|
|
|
- char ptr[4];
|
|
|
-}ram_file_t;
|
|
|
+ ram_file_block_t* head; // 链表头指针
|
|
|
+} ram_file_t;
|
|
|
|
|
|
typedef struct luat_ram_fd
|
|
|
{
|
|
|
int fid;
|
|
|
- uint32_t offset;
|
|
|
+ uint32_t offset;
|
|
|
uint8_t readonly;
|
|
|
-}luat_raw_fd_t;
|
|
|
+} luat_raw_fd_t;
|
|
|
|
|
|
#define RAM_FILE_MAX (64)
|
|
|
static ram_file_t* files[RAM_FILE_MAX];
|
|
|
@@ -33,7 +40,7 @@ FILE* luat_vfs_ram_fopen(void* userdata, const char *filename, const char *mode)
|
|
|
if (!strcmp("r", mode) || !strcmp("rb", mode)) {
|
|
|
for (size_t i = 0; i < RAM_FILE_MAX; i++)
|
|
|
{
|
|
|
- if (files[i]== NULL)
|
|
|
+ if (files[i] == NULL)
|
|
|
continue;
|
|
|
if (!strcmp(files[i]->name, filename)) {
|
|
|
luat_raw_fd_t* fd = luat_heap_malloc(sizeof(luat_raw_fd_t));
|
|
|
@@ -54,7 +61,7 @@ FILE* luat_vfs_ram_fopen(void* userdata, const char *filename, const char *mode)
|
|
|
// 先看看是否存在, 如果存在就重用老的
|
|
|
for (size_t i = 0; i < RAM_FILE_MAX; i++)
|
|
|
{
|
|
|
- if (files[i]== NULL)
|
|
|
+ if (files[i] == NULL)
|
|
|
continue;
|
|
|
if (!strcmp(files[i]->name, filename)) {
|
|
|
luat_raw_fd_t* fd = luat_heap_malloc(sizeof(luat_raw_fd_t));
|
|
|
@@ -67,16 +74,14 @@ FILE* luat_vfs_ram_fopen(void* userdata, const char *filename, const char *mode)
|
|
|
fd->offset = 0;
|
|
|
if (!strcmp("w+", mode) || !strcmp("wb+", mode) || !strcmp("w+b", mode)) {
|
|
|
// 截断模式
|
|
|
- char* tmp = luat_heap_realloc(files[i], sizeof(ram_file_t));
|
|
|
- if (tmp) {
|
|
|
- files[i] = (ram_file_t*)tmp;
|
|
|
- }
|
|
|
- else {
|
|
|
- LLOGE("realloc ram_file_t failed");
|
|
|
- luat_heap_free(fd);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
files[i]->size = 0;
|
|
|
+ ram_file_block_t* block = files[i]->head;
|
|
|
+ while (block) {
|
|
|
+ ram_file_block_t* next = block->next;
|
|
|
+ luat_heap_free(block);
|
|
|
+ block = next;
|
|
|
+ }
|
|
|
+ files[i]->head = NULL;
|
|
|
}
|
|
|
return (FILE*)fd;
|
|
|
}
|
|
|
@@ -143,11 +148,19 @@ int luat_vfs_ram_getc(void* userdata, FILE* stream) {
|
|
|
if (files[fd->fid] == NULL) {
|
|
|
return -1;
|
|
|
}
|
|
|
- if (fd->offset < files[fd->fid]->size) {
|
|
|
- uint8_t c = (uint8_t)files[fd->fid]->ptr[fd->offset];
|
|
|
- fd->offset ++;
|
|
|
- //LLOGD("getc %02X", c);
|
|
|
- return c;
|
|
|
+ ram_file_block_t* block = files[fd->fid]->head;
|
|
|
+ size_t offset = fd->offset;
|
|
|
+ while (block) {
|
|
|
+ if (offset < BLOCK_SIZE) {
|
|
|
+ uint8_t c = block->data[offset];
|
|
|
+ if (c == '\0') {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ fd->offset++;
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+ offset -= BLOCK_SIZE;
|
|
|
+ block = block->next;
|
|
|
}
|
|
|
return -1;
|
|
|
}
|
|
|
@@ -155,18 +168,17 @@ int luat_vfs_ram_getc(void* userdata, FILE* stream) {
|
|
|
int luat_vfs_ram_fseek(void* userdata, FILE* stream, long int offset, int origin) {
|
|
|
(void)userdata;
|
|
|
luat_raw_fd_t* fd = (luat_raw_fd_t*)stream;
|
|
|
+ // LLOGE("luat_vfs_ram_fseek seek %p %p %d %d", userdata, stream, offset, origin);
|
|
|
if (origin == SEEK_CUR) {
|
|
|
fd->offset += offset;
|
|
|
- return 0;
|
|
|
}
|
|
|
else if (origin == SEEK_SET) {
|
|
|
fd->offset = offset;
|
|
|
- return 0;
|
|
|
}
|
|
|
else {
|
|
|
fd->offset = files[fd->fid]->size - offset;
|
|
|
- return 0;
|
|
|
}
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
int luat_vfs_ram_ftell(void* userdata, FILE* stream) {
|
|
|
@@ -183,58 +195,103 @@ int luat_vfs_ram_fclose(void* userdata, FILE* stream) {
|
|
|
luat_heap_free(fd);
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
int luat_vfs_ram_feof(void* userdata, FILE* stream) {
|
|
|
(void)userdata;
|
|
|
luat_raw_fd_t* fd = (luat_raw_fd_t*)stream;
|
|
|
//LLOGD("feof %p %p %d %d", userdata, stream, fd->size, fd->offset);
|
|
|
return fd->offset >= files[fd->fid]->size ? 1 : 0;
|
|
|
}
|
|
|
+
|
|
|
int luat_vfs_ram_ferror(void* userdata, FILE *stream) {
|
|
|
(void)userdata;
|
|
|
(void)stream;
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
size_t luat_vfs_ram_fread(void* userdata, void *ptr, size_t size, size_t nmemb, FILE *stream) {
|
|
|
(void)userdata;
|
|
|
luat_raw_fd_t* fd = (luat_raw_fd_t*)stream;
|
|
|
- //LLOGD("fread %p %p %d %d", userdata, stream, fd->size, fd->offset);
|
|
|
- //LLOGD("fread2 %p %p %d %d", userdata, stream, size * nmemb, fd->offset);
|
|
|
- size_t read_size = size*nmemb;
|
|
|
+ size_t read_size = size * nmemb;
|
|
|
if (fd->offset >= files[fd->fid]->size) {
|
|
|
return 0;
|
|
|
}
|
|
|
if (fd->offset + read_size >= files[fd->fid]->size) {
|
|
|
read_size = files[fd->fid]->size - fd->offset;
|
|
|
}
|
|
|
- memcpy(ptr, files[fd->fid]->ptr + fd->offset, read_size);
|
|
|
- fd->offset += read_size;
|
|
|
- return read_size;
|
|
|
+ ram_file_block_t* block = files[fd->fid]->head;
|
|
|
+ size_t offset = fd->offset;
|
|
|
+ uint8_t* dst = (uint8_t*)ptr;
|
|
|
+ size_t bytes_read = 0; // 用于记录实际读取的字节数
|
|
|
+ while (block && read_size > 0) {
|
|
|
+ size_t copy_size = BLOCK_SIZE - (offset % BLOCK_SIZE);
|
|
|
+ if (copy_size > read_size) {
|
|
|
+ copy_size = read_size;
|
|
|
+ }
|
|
|
+ memcpy(dst, block->data + (offset % BLOCK_SIZE), copy_size);
|
|
|
+ dst += copy_size;
|
|
|
+ read_size -= copy_size;
|
|
|
+ offset += copy_size;
|
|
|
+ bytes_read += copy_size; // 累加读取的字节数
|
|
|
+ if (offset % BLOCK_SIZE == 0) {
|
|
|
+ block = block->next;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fd->offset += bytes_read; // 更新文件偏移量
|
|
|
+ return bytes_read; // 返回实际读取的字节数
|
|
|
}
|
|
|
+
|
|
|
size_t luat_vfs_ram_fwrite(void* userdata, const void *ptr, size_t size, size_t nmemb, FILE *stream) {
|
|
|
(void)userdata;
|
|
|
luat_raw_fd_t* fd = (luat_raw_fd_t*)stream;
|
|
|
- size_t write_size = size*nmemb;
|
|
|
- if (write_size > 128 * 1024) {
|
|
|
- LLOGW("ramfs large write !! %ld", write_size);
|
|
|
- }
|
|
|
+ size_t write_size = size * nmemb;
|
|
|
if (fd->readonly) {
|
|
|
LLOGW("readonly fd %d!! path %s", fd->fid, files[fd->fid]->name);
|
|
|
return 0;
|
|
|
}
|
|
|
-
|
|
|
- if (fd->offset + write_size > files[fd->fid]->size) {
|
|
|
- char* ptr = luat_heap_realloc(files[fd->fid], fd->offset + write_size + sizeof(ram_file_t));
|
|
|
- if (ptr == NULL) {
|
|
|
- LLOGW("/ram out of sys memory!! %ld", write_size);
|
|
|
- return 0;
|
|
|
+ ram_file_block_t* block = files[fd->fid]->head;
|
|
|
+ size_t offset = fd->offset;
|
|
|
+ const uint8_t* src = (const uint8_t*)ptr;
|
|
|
+ while (write_size > 0) {
|
|
|
+ if (block == NULL || offset % BLOCK_SIZE == 0) {
|
|
|
+ if (block == NULL) {
|
|
|
+ block = luat_heap_malloc(sizeof(ram_file_block_t));
|
|
|
+ if (block == NULL) {
|
|
|
+ LLOGW("out of memory when malloc ram_file_block_t");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ memset(block, 0, sizeof(ram_file_block_t));
|
|
|
+ block->next = NULL;
|
|
|
+ if (files[fd->fid]->head == NULL) {
|
|
|
+ files[fd->fid]->head = block;
|
|
|
+ } else {
|
|
|
+ ram_file_block_t* last = files[fd->fid]->head;
|
|
|
+ while (last->next) {
|
|
|
+ last = last->next;
|
|
|
+ }
|
|
|
+ last->next = block;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ size_t copy_size = BLOCK_SIZE - (offset % BLOCK_SIZE);
|
|
|
+ if (copy_size > write_size) {
|
|
|
+ copy_size = write_size;
|
|
|
+ }
|
|
|
+ memcpy(block->data + (offset % BLOCK_SIZE), src, copy_size);
|
|
|
+ src += copy_size;
|
|
|
+ write_size -= copy_size;
|
|
|
+ offset += copy_size;
|
|
|
+ if (offset % BLOCK_SIZE == 0) {
|
|
|
+ block = block->next;
|
|
|
}
|
|
|
- files[fd->fid] = (ram_file_t*)ptr;
|
|
|
- files[fd->fid]->size = fd->offset + write_size;
|
|
|
}
|
|
|
- memcpy(files[fd->fid]->ptr + fd->offset, ptr, write_size);
|
|
|
- fd->offset += write_size;
|
|
|
- return write_size;
|
|
|
+ fd->offset += (size_t)(src - (const uint8_t*)ptr);
|
|
|
+ files[fd->fid]->size = offset > files[fd->fid]->size ? offset : files[fd->fid]->size;
|
|
|
+ // 打印一下写入的数据
|
|
|
+ // LLOGD("write data %s", (char*)ptr);
|
|
|
+ return (size_t)(src - (const uint8_t*)ptr);
|
|
|
}
|
|
|
+
|
|
|
int luat_vfs_ram_remove(void* userdata, const char *filename) {
|
|
|
(void)userdata;
|
|
|
for (size_t i = 0; i < RAM_FILE_MAX; i++)
|
|
|
@@ -242,12 +299,20 @@ int luat_vfs_ram_remove(void* userdata, const char *filename) {
|
|
|
if (files[i] == NULL)
|
|
|
continue;
|
|
|
if (!strcmp(filename, files[i]->name)) {
|
|
|
+ ram_file_block_t* block = files[i]->head;
|
|
|
+ while (block) {
|
|
|
+ ram_file_block_t* next = block->next;
|
|
|
+ luat_heap_free(block);
|
|
|
+ block = next;
|
|
|
+ }
|
|
|
luat_heap_free(files[i]);
|
|
|
files[i] = NULL;
|
|
|
+ return 0;
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
int luat_vfs_ram_rename(void* userdata, const char *old_filename, const char *new_filename) {
|
|
|
(void)userdata;
|
|
|
if (old_filename == NULL || new_filename == NULL)
|
|
|
@@ -265,6 +330,7 @@ int luat_vfs_ram_rename(void* userdata, const char *old_filename, const char *ne
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
int luat_vfs_ram_fexist(void* userdata, const char *filename) {
|
|
|
(void)userdata;
|
|
|
for (size_t i = 0; i < RAM_FILE_MAX; i++)
|
|
|
@@ -295,7 +361,7 @@ void* luat_vfs_ram_mmap(void* userdata, FILE *stream) {
|
|
|
(void)userdata;
|
|
|
luat_raw_fd_t *fd = (luat_raw_fd_t*)(stream);
|
|
|
//LLOGD("fsize %p %p %d %d", userdata, fd);
|
|
|
- return files[fd->fid]->ptr;
|
|
|
+ return files[fd->fid]->head->data;
|
|
|
}
|
|
|
|
|
|
int luat_vfs_ram_mkfs(void* userdata, luat_fs_conf_t *conf) {
|
|
|
@@ -365,8 +431,8 @@ int luat_vfs_ram_info(void* userdata, const char* path, luat_fs_info_t *conf) {
|
|
|
|
|
|
conf->type = 0;
|
|
|
conf->total_block = 64;
|
|
|
- conf->block_used = (ftotal + 1023) / 1024;
|
|
|
- conf->block_size = 1024;
|
|
|
+ conf->block_used = (ftotal + BLOCK_SIZE) / BLOCK_SIZE;
|
|
|
+ conf->block_size = BLOCK_SIZE;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
@@ -376,13 +442,16 @@ int luat_vfs_ram_truncate(void* fsdata, char const* path, size_t nsize) {
|
|
|
if (files[i] == NULL)
|
|
|
continue;
|
|
|
if (!strcmp(files[i]->name, path)) {
|
|
|
- if (files[i]->size > nsize) {
|
|
|
- files[i]->size = nsize;
|
|
|
- char* ptr = luat_heap_realloc(files[i], nsize + sizeof(ram_file_t));
|
|
|
- if (ptr) {
|
|
|
- files[i] = (ram_file_t*)ptr;
|
|
|
+ ram_file_block_t* block = files[i]->head;
|
|
|
+ size_t offset = 0;
|
|
|
+ while (block) {
|
|
|
+ if (offset + BLOCK_SIZE > nsize) {
|
|
|
+ memset(block->data + (nsize - offset), 0, BLOCK_SIZE - (nsize - offset));
|
|
|
}
|
|
|
+ offset += BLOCK_SIZE;
|
|
|
+ block = block->next;
|
|
|
}
|
|
|
+ files[i]->size = nsize;
|
|
|
return 0;
|
|
|
}
|
|
|
}
|