extmod/vfs_fat: Replace listdir() with implementation of ilistdir().

VfsFat no longer has the listdir() method.  Rather, if listdir()
functionality is needed then one should use uos.listdir() which will call
VfsFat.ilistdir().
This commit is contained in:
Damien George 2017-05-05 23:32:44 +10:00
parent 87283c1974
commit d4cd4831b0
3 changed files with 58 additions and 45 deletions

View File

@ -91,7 +91,7 @@ STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(fat_vfs_mkfs_obj, MP_ROM_PTR(&fat_vfs_mk
STATIC MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_open_obj, fatfs_builtin_open_self);
STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) {
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(args[0]);
bool is_str_type = true;
const char *path;
@ -104,9 +104,9 @@ STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
path = "";
}
return fat_vfs_listdir2(self, path, is_str_type);
return fat_vfs_ilistdir2(self, path, is_str_type);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_listdir_obj, 1, 2, fat_vfs_listdir_func);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_ilistdir_obj, 1, 2, fat_vfs_ilistdir_func);
STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t vfs_in, mp_obj_t path_in, mp_int_t attr) {
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
@ -321,7 +321,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_umount_obj, vfs_fat_umount);
STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&fat_vfs_mkfs_obj) },
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&fat_vfs_open_obj) },
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&fat_vfs_listdir_obj) },
{ MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&fat_vfs_ilistdir_obj) },
{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&fat_vfs_mkdir_obj) },
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&fat_vfs_rmdir_obj) },
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&fat_vfs_chdir_obj) },

View File

@ -57,4 +57,4 @@ mp_import_stat_t fat_vfs_import_stat(struct _fs_user_mount_t *vfs, const char *p
mp_obj_t fatfs_builtin_open_self(mp_obj_t self_in, mp_obj_t path, mp_obj_t mode);
MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_open_obj);
mp_obj_t fat_vfs_listdir2(struct _fs_user_mount_t *vfs, const char *path, bool is_str_type);
mp_obj_t fat_vfs_ilistdir2(struct _fs_user_mount_t *vfs, const char *path, bool is_str_type);

View File

@ -34,51 +34,64 @@
#include "extmod/vfs_fat.h"
#include "py/lexer.h"
// TODO: actually, the core function should be ilistdir()
mp_obj_t fat_vfs_listdir2(fs_user_mount_t *vfs, const char *path, bool is_str_type) {
FRESULT res;
FILINFO fno;
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;
res = f_opendir(&vfs->fatfs, &dir, path);
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 (;;) {
FILINFO fno;
FRESULT res = f_readdir(&self->dir, &fno);
char *fn = fno.fname;
if (res != FR_OK || fn[0] == 0) {
// stop on error or end of dir
break;
}
if (fn[0] == '.' && (fn[1] == 0 || (fn[1] == '.' && fn[2] == 0))) {
// skip . and ..
continue;
}
// 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);
}
t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // no inode number
return MP_OBJ_FROM_PTR(t);
}
// ignore error because we may be closing a second time
f_closedir(&self->dir);
return MP_OBJ_STOP_ITERATION;
}
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]);
}
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
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 */
char *fn = fno.fname;
/*
if (fno.fattrib & AM_DIR) {
// dir
} else {
// file
}
*/
// 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));
}
// add the entry to the list
mp_obj_list_append(dir_list, entry_o);
}
f_closedir(&dir);
return dir_list;
return MP_OBJ_FROM_PTR(iter);
}
mp_import_stat_t fat_vfs_import_stat(fs_user_mount_t *vfs, const char *path) {