| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- #include "luat_base.h"
- #include "luat_fs.h"
- #include "luat_spi.h"
- #include "luat_mem.h"
- #define LUAT_LOG_TAG "vfs.lfs2"
- #include "luat_log.h"
- #ifdef LUAT_USE_FS_VFS
- // #ifdef LUAT_VFS_USE_LFS2
- #include "lfs.h"
- FILE* luat_vfs_lfs2_fopen(void* userdata, const char *filename, const char *mode) {
- lfs_t* fs = (lfs_t*)userdata;
- lfs_file_t *file = (lfs_file_t*)luat_heap_malloc(sizeof(lfs_file_t));
- if (file == NULL) {
- LLOGD("out of memory when open file %s", filename);
- return NULL;
- }
- memset(file, 0, sizeof(lfs_file_t));
- int flag = 0;
- /*
- "r": 读模式(默认);
- "w": 写模式;
- "a": 追加模式;
- "r+": 更新模式,所有之前的数据都保留;
- "w+": 更新模式,所有之前的数据都删除;
- "a+": 追加更新模式,所有之前的数据都保留,只允许在文件尾部做写入。
- */
- if (!strcmp("r+", mode) || !strcmp("r+b", mode) || !strcmp("rb+", mode)) {
- flag = LFS_O_RDWR | LFS_O_CREAT;
- }
- else if(!strcmp("w+", mode) || !strcmp("w+b", mode) || !strcmp("wb+", mode)) {
- flag = LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC;
- }
- else if(!strcmp("a+", mode) || !strcmp("a+b", mode) || !strcmp("ab+", mode)) {
- flag = LFS_O_APPEND | LFS_O_CREAT | LFS_O_WRONLY;
- }
- else if(!strcmp("w", mode) || !strcmp("wb", mode)) {
- flag = LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC;
- }
- else if(!strcmp("r", mode) || !strcmp("rb", mode)) {
- flag = LFS_O_RDONLY;
- }
- else if(!strcmp("a", mode) || !strcmp("ab", mode)) {
- flag = LFS_O_APPEND | LFS_O_CREAT | LFS_O_WRONLY;
- }
- else {
- LLOGW("bad file open mode %s, fallback to 'r'", mode);
- flag = LFS_O_RDONLY;
- }
- int ret = lfs_file_open(fs, file, filename, flag);
- if (ret < 0) {
- luat_heap_free(file);
- return 0;
- }
- return (FILE*)file;
- }
- int luat_vfs_lfs2_getc(void* userdata, FILE* stream) {
- //LLOGD("posix_getc %p", stream);
- lfs_t* fs = (lfs_t*)userdata;
- lfs_file_t* file = (lfs_file_t*)stream;
- char buff = 0;
- int ret = lfs_file_read(fs, file, &buff, 1);
- if (ret != 1)
- return -1;
- return (int)buff;
- }
- int luat_vfs_lfs2_fseek(void* userdata, FILE* stream, long int offset, int origin) {
- lfs_t* fs = (lfs_t*)userdata;
- lfs_file_t* file = (lfs_file_t*)stream;
- int ret = lfs_file_seek(fs, file, offset, origin);
- return ret < 0 ? -1 : 0;
- }
- int luat_vfs_lfs2_ftell(void* userdata, FILE* stream) {
- lfs_t* fs = (lfs_t*)userdata;
- lfs_file_t* file = (lfs_file_t*)stream;
- int ret = lfs_file_tell(fs, file);
- return ret < 0 ? -1 : ret;
- }
- int luat_vfs_lfs2_fclose(void* userdata, FILE* stream) {
- lfs_t* fs = (lfs_t*)userdata;
- lfs_file_t* file = (lfs_file_t*)stream;
- lfs_file_close(fs, file);
- if (file != NULL)
- luat_heap_free(file);
- return 0;
- }
- int luat_vfs_lfs2_feof(void* userdata, FILE* stream) {
- lfs_t* fs = (lfs_t*)userdata;
- lfs_file_t* file = (lfs_file_t*)stream;
- if (lfs_file_size(fs, file) <= lfs_file_tell(fs, file))
- return 1;
- return 0;
- }
- int luat_vfs_lfs2_ferror(void* userdata, FILE *stream) {
- return 0;
- }
- size_t luat_vfs_lfs2_fread(void* userdata, void *ptr, size_t size, size_t nmemb, FILE *stream) {
- lfs_t* fs = (lfs_t*)userdata;
- lfs_file_t* file = (lfs_file_t*)stream;
- int ret = lfs_file_read(fs, file, ptr, size*nmemb);
- return ret < 0 ? 0 : ret;
- }
- size_t luat_vfs_lfs2_fwrite(void* userdata, const void *ptr, size_t size, size_t nmemb, FILE *stream) {
- lfs_t* fs = (lfs_t*)userdata;
- lfs_file_t* file = (lfs_file_t*)stream;
- if ((file->flags & LFS_O_WRONLY) != LFS_O_WRONLY && (file->flags & LFS_O_APPEND) != LFS_O_APPEND) {
- LLOGE("open file at readonly mode, reject for write flags=%08X", file->flags);
- return 0;
- }
- int ret = lfs_file_write(fs, file, ptr, size*nmemb);
- return ret < 0 ? 0 : ret;
- }
- int luat_vfs_lfs2_fflush(void* userdata, FILE *stream) {
- lfs_t* fs = (lfs_t*)userdata;
- lfs_file_t* file = (lfs_file_t*)stream;
- int ret = lfs_file_sync(fs, file);
- return ret < 0 ? 0 : ret;
- }
- int luat_vfs_lfs2_remove(void* userdata, const char *filename) {
- lfs_t* fs = (lfs_t*)userdata;
- return lfs_remove(fs, filename);
- }
- int luat_vfs_lfs2_rename(void* userdata, const char *old_filename, const char *new_filename) {
- lfs_t* fs = (lfs_t*)userdata;
- return lfs_rename(fs, old_filename, new_filename);
- }
- int luat_vfs_lfs2_fexist(void* userdata, const char *filename) {
- FILE* fd = luat_vfs_lfs2_fopen(userdata, filename, "rb");
- if (fd) {
- luat_vfs_lfs2_fclose(userdata, fd);
- return 1;
- }
- return 0;
- }
- size_t luat_vfs_lfs2_fsize(void* userdata, const char *filename) {
- FILE *fd;
- size_t size = 0;
- fd = luat_vfs_lfs2_fopen(userdata, filename, "rb");
- if (fd) {
- size = lfs_file_size((lfs_t*)userdata, (lfs_file_t*)fd);
- luat_vfs_lfs2_fclose(userdata, fd);
- }
- return size;
- }
- int luat_vfs_lfs2_mkfs(void* userdata, luat_fs_conf_t *conf) {
- int ret = 0;
- lfs_t* fs = (lfs_t*)userdata;
- if (fs != NULL && fs->cfg != NULL) {
- ret = lfs_format(fs, fs->cfg);
- // LLOGD("lfs2 format ret %d", ret);
- if (ret < 0)
- return ret;
- ret = lfs_mount(fs, fs->cfg);
- // LLOGD("lfs2 mount ret %d", ret);
- return ret;
- }
- return -1;
- }
- int luat_vfs_lfs2_mount(void** userdata, luat_fs_conf_t *conf) {
- *userdata = (void*)conf->busname;
- return 0;
- }
- int luat_vfs_lfs2_umount(void* userdata, luat_fs_conf_t *conf) {
- LLOGE("not support yet : umount");
- return 0;
- }
- static int dir2name(char* buff, char const* _DirName) {
- size_t dirlen = strlen(_DirName);
- if (dirlen > 63) {
- LLOGE("dir too long!! %s", _DirName);
- return -1;
- }
- else if (dirlen < 1) {
- LLOGE("dir too short!! %s", _DirName);
- return -1;
- }
- memcpy(buff, _DirName, dirlen);
- if (buff[dirlen -1] == '/') {
- buff[dirlen -1] = 0;
- }
- return 0;
- }
- int luat_vfs_lfs2_mkdir(void* userdata, char const* _DirName) {
- lfs_t* fs = (lfs_t*)userdata;
- char buff[64] = {0};
- if (dir2name(buff, _DirName)) {
- return -1;
- }
- int ret = lfs_mkdir(fs, buff);
- return ret == LFS_ERR_OK ? 0 : -1;
- }
- int luat_vfs_lfs2_rmdir(void* userdata, char const* _DirName) {
- lfs_t* fs = (lfs_t*)userdata;
- char buff[64] = {0};
- if (dir2name(buff, _DirName)) {
- return -1;
- }
- int ret = lfs_remove(fs, buff);
- return ret == LFS_ERR_OK ? 0 : -1;
- }
- int luat_vfs_lfs2_lsdir(void* userdata, char const* _DirName, luat_fs_dirent_t* ents, size_t offset, size_t len) {
- lfs_t* fs = (lfs_t*)userdata;
- int ret , num = 0;
- lfs_dir_t *dir;
- struct lfs_info info;
- char buff[64] = {0};
- if (strlen(_DirName) == 0) {
- // OK的, 根目录嘛
- }
- else if (dir2name(buff, _DirName)) {
- return -1;
- }
- // if (fs->filecount > offset) {
- // if (offset + len > fs->filecount)
- // len = fs->filecount - offset;
- dir = luat_heap_malloc(sizeof(lfs_dir_t));
- if (dir == NULL) {
- // LLOGE("out of memory when lsdir");
- return 0;
- }
- ret = lfs_dir_open(fs, dir, buff);
- if (ret < 0) {
- luat_heap_free(dir);
- // LLOGE("no such dir %s _DirName");
- return 0;
- }
- // TODO 使用seek/tell组合更快更省
- for (size_t i = 0; i < offset; i++)
- {
- ret = lfs_dir_read(fs, dir, &info);
- if (ret <= 0) {
- lfs_dir_close(fs, dir);
- luat_heap_free(dir);
- return 0;
- }
- }
- while (num < len)
- {
- ret = lfs_dir_read(fs, dir, &info);
- if (ret < 0) {
- lfs_dir_close(fs, dir);
- luat_heap_free(dir);
- return 0;
- }
- if (ret == 0) {
- break;
- }
- if (info.type == 2 && (memcmp(info.name, ".", 2) ==0 ||memcmp(info.name, "..", 3)==0))
- continue;
- ents[num].d_type = info.type - 1; // lfs file =1, dir=2
- strcpy(ents[num].d_name, info.name);
- num++;
- }
- lfs_dir_close(fs, dir);
- luat_heap_free(dir);
- return num;
- // }
- return 0;
- }
- int luat_vfs_lfs2_info(void* userdata, const char* path, luat_fs_info_t *conf) {
- //LLOGD("why ? luat_vfs_lfs2_info %p", userdata);
- lfs_t* fs = (lfs_t*)userdata;
- memcpy(conf->filesystem, "lfs", strlen("lfs")+1);
- conf->type = 0;
- conf->total_block = fs->cfg->block_count;
- conf->block_used = lfs_fs_size(fs);
- conf->block_size = fs->cfg->block_size;
- //LLOGD("total %d used %d size %d", conf->total_block, conf->block_used, conf->block_size);
- return 0;
- }
- int luat_vfs_lfs2_truncate(void* userdata, const char *filename, size_t len) {
- FILE *fd;
- int ret = -1;
- fd = luat_vfs_lfs2_fopen(userdata, filename, "wb");
- if (fd) {
- ret = lfs_file_truncate((lfs_t*)userdata, (lfs_file_t*)fd ,(lfs_off_t)len);
- luat_vfs_lfs2_fclose(userdata, fd);
- }
- return ret;
- }
- void* luat_vfs_lfs2_opendir(void* userdata, const char *_DirName) {
- lfs_dir_t *dir = (lfs_dir_t*)luat_heap_malloc(sizeof(lfs_dir_t));
- if (dir == NULL) {
- LLOGD("out of memory when open file %s", dir);
- return NULL;
- }
- memset(dir, 0, sizeof(lfs_dir_t));
- int ret = lfs_dir_open((lfs_t*)userdata, dir, _DirName);
- if (ret < 0) {
- luat_heap_free(dir);
- return NULL;
- }
- return (void*)dir;
- }
- int luat_vfs_lfs2_closedir(void* userdata, void* dir) {
- lfs_dir_close((lfs_t*)userdata, (lfs_dir_t *)dir);
- if (dir)luat_heap_free(dir);
- return 0;
- }
- #define T(name) .name = luat_vfs_lfs2_##name
- const struct luat_vfs_filesystem vfs_fs_lfs2 = {
- .name = "lfs2",
- .opts = {
- T(mkfs),
- T(mount),
- T(umount),
- T(mkdir),
- T(rmdir),
- T(lsdir),
- T(remove),
- T(rename),
- T(fsize),
- T(fexist),
- T(info),
- T(truncate),
- T(opendir),
- T(closedir)
- },
- .fopts = {
- T(fopen),
- T(getc),
- T(fseek),
- T(ftell),
- T(fclose),
- T(feof),
- T(ferror),
- T(fread),
- T(fwrite),
- T(fflush)
- }
- };
- // #endif
- #endif
|