summaryrefslogtreecommitdiffstatshomepage
path: root/extmod/vfs_fat_misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'extmod/vfs_fat_misc.c')
-rw-r--r--extmod/vfs_fat_misc.c103
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;