diff options
Diffstat (limited to 'extmod/vfs_fat_misc.c')
-rw-r--r-- | extmod/vfs_fat_misc.c | 103 |
1 files changed, 47 insertions, 56 deletions
diff --git a/extmod/vfs_fat_misc.c b/extmod/vfs_fat_misc.c index d3507a85f3..7c16db7e5b 100644 --- a/extmod/vfs_fat_misc.c +++ b/extmod/vfs_fat_misc.c @@ -25,86 +25,77 @@ */ #include "py/mpconfig.h" -// *_ADHOC part is for cc3200 port which doesn't use general uPy -// infrastructure and instead duplicates code. TODO: Resolve. -#if MICROPY_VFS_FAT || MICROPY_FSUSERMOUNT || MICROPY_FSUSERMOUNT_ADHOC +#if MICROPY_VFS_FAT #include <string.h> #include "py/nlr.h" #include "py/runtime.h" -#include "lib/fatfs/ff.h" -#include "lib/fatfs/diskio.h" -#include "extmod/vfs_fat_file.h" -#include "extmod/fsusermount.h" +#include "lib/oofatfs/ff.h" +#include "extmod/vfs_fat.h" #include "py/lexer.h" -#if _USE_LFN -STATIC char lfn[_MAX_LFN + 1]; /* Buffer to store the LFN */ -#endif +typedef struct _mp_vfs_fat_ilistdir_it_t { + mp_obj_base_t base; + mp_fun_1_t iternext; + bool is_str; + FF_DIR dir; +} mp_vfs_fat_ilistdir_it_t; -// TODO: actually, the core function should be ilistdir() -mp_obj_t fat_vfs_listdir(const char *path, bool is_str_type) { - FRESULT res; - FILINFO fno; - DIR dir; -#if _USE_LFN - fno.lfname = lfn; - fno.lfsize = sizeof lfn; -#endif - - res = f_opendir(&dir, path); /* Open the directory */ - if (res != FR_OK) { - mp_raise_OSError(fresult_to_errno_table[res]); - } - - mp_obj_t dir_list = mp_obj_new_list(0, NULL); +STATIC mp_obj_t mp_vfs_fat_ilistdir_it_iternext(mp_obj_t self_in) { + mp_vfs_fat_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in); for (;;) { - res = f_readdir(&dir, &fno); /* Read a directory item */ - if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ - if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */ - if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */ - -#if _USE_LFN - char *fn = *fno.lfname ? fno.lfname : fno.fname; -#else + FILINFO fno; + FRESULT res = f_readdir(&self->dir, &fno); char *fn = fno.fname; -#endif + if (res != FR_OK || fn[0] == 0) { + // stop on error or end of dir + break; + } + + // Note that FatFS already filters . and .., so we don't need to - /* + // make 3-tuple with info about this entry + mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)); + if (self->is_str) { + t->items[0] = mp_obj_new_str(fn, strlen(fn), false); + } else { + t->items[0] = mp_obj_new_bytes((const byte*)fn, strlen(fn)); + } if (fno.fattrib & AM_DIR) { // dir + t->items[1] = MP_OBJ_NEW_SMALL_INT(MP_S_IFDIR); } else { // file + t->items[1] = MP_OBJ_NEW_SMALL_INT(MP_S_IFREG); } - */ - - // make a string object for this entry - mp_obj_t entry_o; - if (is_str_type) { - entry_o = mp_obj_new_str(fn, strlen(fn), false); - } else { - entry_o = mp_obj_new_bytes((const byte*)fn, strlen(fn)); - } + t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // no inode number - // add the entry to the list - mp_obj_list_append(dir_list, entry_o); + return MP_OBJ_FROM_PTR(t); } - f_closedir(&dir); + // ignore error because we may be closing a second time + f_closedir(&self->dir); - return dir_list; + return MP_OBJ_STOP_ITERATION; } -mp_import_stat_t fat_vfs_import_stat(const char *path); +mp_obj_t fat_vfs_ilistdir2(fs_user_mount_t *vfs, const char *path, bool is_str_type) { + mp_vfs_fat_ilistdir_it_t *iter = m_new_obj(mp_vfs_fat_ilistdir_it_t); + iter->base.type = &mp_type_polymorph_iter; + iter->iternext = mp_vfs_fat_ilistdir_it_iternext; + iter->is_str = is_str_type; + FRESULT res = f_opendir(&vfs->fatfs, &iter->dir, path); + if (res != FR_OK) { + mp_raise_OSError(fresult_to_errno_table[res]); + } + return MP_OBJ_FROM_PTR(iter); +} -mp_import_stat_t fat_vfs_import_stat(const char *path) { +mp_import_stat_t fat_vfs_import_stat(fs_user_mount_t *vfs, const char *path) { FILINFO fno; -#if _USE_LFN - fno.lfname = NULL; - fno.lfsize = 0; -#endif - FRESULT res = f_stat(path, &fno); + assert(vfs != NULL); + FRESULT res = f_stat(&vfs->fatfs, path, &fno); if (res == FR_OK) { if ((fno.fattrib & AM_DIR) != 0) { return MP_IMPORT_STAT_DIR; |