extmod/vfs: Introduce a C-level VFS protocol, with fast import_stat.
Following other C-level protocols, this VFS protocol is added to help abstract away implementation details of the underlying VFS in an efficient way. As a starting point, the import_stat function is put into this protocol so that the VFS sub-system does not need to know about every VFS implementation in order to do an efficient stat for importing files. In the future it might be worth adding other functions to this protocol.
This commit is contained in:
parent
fadd6bbe43
commit
c117effddd
17
extmod/vfs.c
17
extmod/vfs.c
|
@ -34,9 +34,6 @@
|
|||
|
||||
#if MICROPY_VFS
|
||||
|
||||
#if MICROPY_VFS_POSIX
|
||||
#include "extmod/vfs_posix.h"
|
||||
#endif
|
||||
#if MICROPY_VFS_FAT
|
||||
#include "extmod/vfs_fat.h"
|
||||
#endif
|
||||
|
@ -128,17 +125,11 @@ mp_import_stat_t mp_vfs_import_stat(const char *path) {
|
|||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
// Fast paths for known VFS types
|
||||
#if MICROPY_VFS_POSIX
|
||||
if (mp_obj_get_type(vfs->obj) == &mp_type_vfs_posix) {
|
||||
return mp_vfs_posix_import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
|
||||
// If the mounted object has the VFS protocol, call its import_stat helper
|
||||
const mp_vfs_proto_t *proto = mp_obj_get_type(vfs->obj)->protocol;
|
||||
if (proto != NULL) {
|
||||
return proto->import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
|
||||
}
|
||||
#endif
|
||||
#if MICROPY_VFS_FAT
|
||||
if (mp_obj_get_type(vfs->obj) == &mp_fat_vfs_type) {
|
||||
return fat_vfs_import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
|
||||
}
|
||||
#endif
|
||||
|
||||
// delegate to vfs.stat() method
|
||||
mp_obj_t path_o = mp_obj_new_str(path_out, strlen(path_out));
|
||||
|
|
|
@ -45,6 +45,11 @@
|
|||
#define BP_IOCTL_SEC_COUNT (4)
|
||||
#define BP_IOCTL_SEC_SIZE (5)
|
||||
|
||||
// At the moment the VFS protocol just has import_stat, but could be extended to other methods
|
||||
typedef struct _mp_vfs_proto_t {
|
||||
mp_import_stat_t (*import_stat)(void *self, const char *path);
|
||||
} mp_vfs_proto_t;
|
||||
|
||||
typedef struct _mp_vfs_mount_t {
|
||||
const char *str; // mount point with leading /
|
||||
size_t len;
|
||||
|
|
|
@ -47,7 +47,8 @@
|
|||
|
||||
#define mp_obj_fat_vfs_t fs_user_mount_t
|
||||
|
||||
mp_import_stat_t fat_vfs_import_stat(fs_user_mount_t *vfs, const char *path) {
|
||||
STATIC mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) {
|
||||
fs_user_mount_t *vfs = vfs_in;
|
||||
FILINFO fno;
|
||||
assert(vfs != NULL);
|
||||
FRESULT res = f_stat(&vfs->fatfs, path, &fno);
|
||||
|
@ -421,11 +422,17 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
|
|||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
|
||||
|
||||
STATIC const mp_vfs_proto_t fat_vfs_proto = {
|
||||
.import_stat = fat_vfs_import_stat,
|
||||
};
|
||||
|
||||
const mp_obj_type_t mp_fat_vfs_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_VfsFat,
|
||||
.make_new = fat_vfs_make_new,
|
||||
.protocol = &fat_vfs_proto,
|
||||
.locals_dict = (mp_obj_dict_t*)&fat_vfs_locals_dict,
|
||||
|
||||
};
|
||||
|
||||
#endif // MICROPY_VFS_FAT
|
||||
|
|
|
@ -58,7 +58,6 @@ extern const mp_obj_type_t mp_fat_vfs_type;
|
|||
extern const mp_obj_type_t mp_type_vfs_fat_fileio;
|
||||
extern const mp_obj_type_t mp_type_vfs_fat_textio;
|
||||
|
||||
mp_import_stat_t fat_vfs_import_stat(struct _fs_user_mount_t *vfs, const char *path);
|
||||
MP_DECLARE_CONST_FUN_OBJ_3(fat_vfs_open_obj);
|
||||
|
||||
#endif // MICROPY_INCLUDED_EXTMOD_VFS_FAT_H
|
||||
|
|
|
@ -71,7 +71,8 @@ STATIC mp_obj_t vfs_posix_fun1_helper(mp_obj_t self_in, mp_obj_t path_in, int (*
|
|||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_vfs_posix_import_stat(mp_obj_vfs_posix_t *self, const char *path) {
|
||||
STATIC mp_import_stat_t mp_vfs_posix_import_stat(void *self_in, const char *path) {
|
||||
mp_obj_vfs_posix_t *self = self_in;
|
||||
if (self->root_len != 0) {
|
||||
self->root.len = self->root_len;
|
||||
vstr_add_str(&self->root, path);
|
||||
|
@ -347,10 +348,15 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
|
|||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
|
||||
|
||||
STATIC const mp_vfs_proto_t vfs_posix_proto = {
|
||||
.import_stat = mp_vfs_posix_import_stat,
|
||||
};
|
||||
|
||||
const mp_obj_type_t mp_type_vfs_posix = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_VfsPosix,
|
||||
.make_new = vfs_posix_make_new,
|
||||
.protocol = &vfs_posix_proto,
|
||||
.locals_dict = (mp_obj_dict_t*)&vfs_posix_locals_dict,
|
||||
};
|
||||
|
||||
|
|
|
@ -29,13 +29,10 @@
|
|||
#include "py/lexer.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
struct _mp_obj_vfs_posix_t;
|
||||
|
||||
extern const mp_obj_type_t mp_type_vfs_posix;
|
||||
extern const mp_obj_type_t mp_type_vfs_posix_fileio;
|
||||
extern const mp_obj_type_t mp_type_vfs_posix_textio;
|
||||
|
||||
mp_import_stat_t mp_vfs_posix_import_stat(struct _mp_obj_vfs_posix_t *self, const char *path_in);
|
||||
mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_obj_t mode_in);
|
||||
|
||||
#endif // MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H
|
||||
|
|
Loading…
Reference in New Issue