summaryrefslogtreecommitdiff
path: root/extmod/vfs_fat_file.c
diff options
context:
space:
mode:
authorJim Mussared <jim.mussared@gmail.com>2022-07-22 13:53:13 +1000
committerDamien George <damien@micropython.org>2022-07-26 17:58:01 +1000
commite65d1e69e88268145ff0e7e73240f028885915be (patch)
tree3e4e19afc776fb319b535f6fdee3d4953bc39924 /extmod/vfs_fat_file.c
parentc0fa903d6b2ed5131ae60f8faff2c6ad5276b3a2 (diff)
py/modio: Remove FileIO and TextIOWrapper from io module.
On ports with more than one filesystem, the type will be wrong, for example if using LFS but FAT enabled, then the type will be FAT. So it's not possible to use these classes to identify a file object type. Furthermore, constructing an io.FileIO currently crashes on FAT, and make_new isn't supported on LFS. And the io.TextIOWrapper class does not match CPython at all. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
Diffstat (limited to 'extmod/vfs_fat_file.c')
-rw-r--r--extmod/vfs_fat_file.c127
1 files changed, 51 insertions, 76 deletions
diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c
index 537101d00..ebf36fc39 100644
--- a/extmod/vfs_fat_file.c
+++ b/extmod/vfs_fat_file.c
@@ -151,72 +151,6 @@ STATIC mp_uint_t file_obj_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg,
}
}
-// Note: encoding is ignored for now; it's also not a valid kwarg for CPython's FileIO,
-// but by adding it here we can use one single mp_arg_t array for open() and FileIO's constructor
-STATIC const mp_arg_t file_open_args[] = {
- { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE} },
- { MP_QSTR_mode, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_QSTR(MP_QSTR_r)} },
- { MP_QSTR_encoding, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
-};
-#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
-
-STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) {
- int mode = 0;
- const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
- // TODO make sure only one of r, w, x, a, and b, t are specified
- while (*mode_s) {
- switch (*mode_s++) {
- case 'r':
- mode |= FA_READ;
- break;
- case 'w':
- mode |= FA_WRITE | FA_CREATE_ALWAYS;
- break;
- case 'x':
- mode |= FA_WRITE | FA_CREATE_NEW;
- break;
- case 'a':
- mode |= FA_WRITE | FA_OPEN_ALWAYS;
- break;
- case '+':
- mode |= FA_READ | FA_WRITE;
- break;
- #if MICROPY_PY_IO_FILEIO
- case 'b':
- type = &mp_type_vfs_fat_fileio;
- break;
- #endif
- case 't':
- type = &mp_type_vfs_fat_textio;
- break;
- }
- }
-
- pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t);
- o->base.type = type;
-
- const char *fname = mp_obj_str_get_str(args[0].u_obj);
- assert(vfs != NULL);
- FRESULT res = f_open(&vfs->fatfs, &o->fp, fname, mode);
- if (res != FR_OK) {
- m_del_obj(pyb_file_obj_t, o);
- mp_raise_OSError(fresult_to_errno_table[res]);
- }
-
- // for 'a' mode, we must begin at the end of the file
- if ((mode & FA_OPEN_ALWAYS) != 0) {
- f_lseek(&o->fp, f_size(&o->fp));
- }
-
- return MP_OBJ_FROM_PTR(o);
-}
-
-STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
- mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
- return file_open(NULL, type, arg_vals);
-}
-
// TODO gc hook to close the file if not already closed
STATIC const mp_rom_map_elem_t vfs_fat_rawfile_locals_dict_table[] = {
@@ -247,7 +181,6 @@ const mp_obj_type_t mp_type_vfs_fat_fileio = {
{ &mp_type_type },
.name = MP_QSTR_FileIO,
.print = file_obj_print,
- .make_new = file_obj_make_new,
.getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter,
.protocol = &vfs_fat_fileio_stream_p,
@@ -266,7 +199,6 @@ const mp_obj_type_t mp_type_vfs_fat_textio = {
{ &mp_type_type },
.name = MP_QSTR_TextIOWrapper,
.print = file_obj_print,
- .make_new = file_obj_make_new,
.getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter,
.protocol = &vfs_fat_textio_stream_p,
@@ -274,15 +206,58 @@ const mp_obj_type_t mp_type_vfs_fat_textio = {
};
// Factory function for I/O stream classes
-STATIC mp_obj_t fatfs_builtin_open_self(mp_obj_t self_in, mp_obj_t path, mp_obj_t mode) {
- // TODO: analyze buffering args and instantiate appropriate type
+STATIC mp_obj_t fat_vfs_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_in) {
fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
- mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
- arg_vals[0].u_obj = path;
- arg_vals[1].u_obj = mode;
- arg_vals[2].u_obj = mp_const_none;
- return file_open(self, &mp_type_vfs_fat_textio, arg_vals);
+
+ const mp_obj_type_t *type = &mp_type_vfs_fat_textio;
+ int mode = 0;
+ const char *mode_s = mp_obj_str_get_str(mode_in);
+ // TODO make sure only one of r, w, x, a, and b, t are specified
+ while (*mode_s) {
+ switch (*mode_s++) {
+ case 'r':
+ mode |= FA_READ;
+ break;
+ case 'w':
+ mode |= FA_WRITE | FA_CREATE_ALWAYS;
+ break;
+ case 'x':
+ mode |= FA_WRITE | FA_CREATE_NEW;
+ break;
+ case 'a':
+ mode |= FA_WRITE | FA_OPEN_ALWAYS;
+ break;
+ case '+':
+ mode |= FA_READ | FA_WRITE;
+ break;
+ #if MICROPY_PY_IO_FILEIO
+ case 'b':
+ type = &mp_type_vfs_fat_fileio;
+ break;
+ #endif
+ case 't':
+ type = &mp_type_vfs_fat_textio;
+ break;
+ }
+ }
+
+ pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t);
+ o->base.type = type;
+
+ const char *fname = mp_obj_str_get_str(path_in);
+ FRESULT res = f_open(&self->fatfs, &o->fp, fname, mode);
+ if (res != FR_OK) {
+ m_del_obj(pyb_file_obj_t, o);
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
+
+ // for 'a' mode, we must begin at the end of the file
+ if ((mode & FA_OPEN_ALWAYS) != 0) {
+ f_lseek(&o->fp, f_size(&o->fp));
+ }
+
+ return MP_OBJ_FROM_PTR(o);
}
-MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_open_obj, fatfs_builtin_open_self);
+MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_open_obj, fat_vfs_open);
#endif // MICROPY_VFS && MICROPY_VFS_FAT