2828#include "py/mpconfig.h"
2929#if MICROPY_VFS_FAT
3030
31+ #if !MICROPY_FATFS_OO
32+ #error "with MICROPY_VFS_FAT enabled, must also enable MICROPY_FATFS_OO"
33+ #endif
34+
3135#include <string.h>
3236#include "py/nlr.h"
3337#include "py/runtime.h"
3438#include "py/mperrno.h"
35- #include "lib/fatfs/ff.h"
36- #include "lib/fatfs/diskio.h"
39+ #include "lib/oofatfs/ff.h"
3740#include "extmod/vfs_fat_file.h"
3841#include "extmod/fsusermount.h"
3942#include "timeutils.h"
@@ -55,13 +58,10 @@ STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) {
5558STATIC MP_DEFINE_CONST_FUN_OBJ_1 (fat_vfs_mkfs_fun_obj , fat_vfs_mkfs );
5659STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ (fat_vfs_mkfs_obj , MP_ROM_PTR (& fat_vfs_mkfs_fun_obj ));
5760
58- STATIC mp_obj_t fat_vfs_open (size_t n_args , const mp_obj_t * args , mp_map_t * kwargs ) {
59- // Skip self
60- return fatfs_builtin_open (n_args - 1 , args + 1 , kwargs );
61- }
62- MP_DEFINE_CONST_FUN_OBJ_KW (fat_vfs_open_obj , 2 , fat_vfs_open );
61+ STATIC MP_DEFINE_CONST_FUN_OBJ_KW (fat_vfs_open_obj , 2 , fatfs_builtin_open_self );
6362
6463STATIC mp_obj_t fat_vfs_listdir_func (size_t n_args , const mp_obj_t * args ) {
64+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR (args [0 ]);
6565 bool is_str_type = true;
6666 const char * path ;
6767 if (n_args == 2 ) {
@@ -73,27 +73,24 @@ STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
7373 path = "" ;
7474 }
7575
76- return fat_vfs_listdir ( path , is_str_type );
76+ return fat_vfs_listdir2 ( self , path , is_str_type );
7777}
7878STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (fat_vfs_listdir_obj , 1 , 2 , fat_vfs_listdir_func );
7979
80- STATIC mp_obj_t fat_vfs_remove_internal (mp_obj_t path_in , mp_int_t attr ) {
80+ STATIC mp_obj_t fat_vfs_remove_internal (mp_obj_t vfs_in , mp_obj_t path_in , mp_int_t attr ) {
81+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR (vfs_in );
8182 const char * path = mp_obj_str_get_str (path_in );
8283
8384 FILINFO fno ;
84- #if _USE_LFN
85- fno .lfname = NULL ;
86- fno .lfsize = 0 ;
87- #endif
88- FRESULT res = f_stat (path , & fno );
85+ FRESULT res = f_stat (& self -> fatfs , path , & fno );
8986
9087 if (res != FR_OK ) {
9188 mp_raise_OSError (fresult_to_errno_table [res ]);
9289 }
9390
9491 // check if path is a file or directory
9592 if ((fno .fattrib & AM_DIR ) == attr ) {
96- res = f_unlink (path );
93+ res = f_unlink (& self -> fatfs , path );
9794
9895 if (res != FR_OK ) {
9996 mp_raise_OSError (fresult_to_errno_table [res ]);
@@ -105,27 +102,25 @@ STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t path_in, mp_int_t attr) {
105102}
106103
107104STATIC mp_obj_t fat_vfs_remove (mp_obj_t vfs_in , mp_obj_t path_in ) {
108- (void )vfs_in ;
109- return fat_vfs_remove_internal (path_in , 0 ); // 0 == file attribute
105+ return fat_vfs_remove_internal (vfs_in , path_in , 0 ); // 0 == file attribute
110106}
111107STATIC MP_DEFINE_CONST_FUN_OBJ_2 (fat_vfs_remove_obj , fat_vfs_remove );
112108
113109STATIC mp_obj_t fat_vfs_rmdir (mp_obj_t vfs_in , mp_obj_t path_in ) {
114- (void ) vfs_in ;
115- return fat_vfs_remove_internal (path_in , AM_DIR );
110+ return fat_vfs_remove_internal (vfs_in , path_in , AM_DIR );
116111}
117112STATIC MP_DEFINE_CONST_FUN_OBJ_2 (fat_vfs_rmdir_obj , fat_vfs_rmdir );
118113
119114STATIC mp_obj_t fat_vfs_rename (mp_obj_t vfs_in , mp_obj_t path_in , mp_obj_t path_out ) {
120- ( void ) vfs_in ;
115+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
121116 const char * old_path = mp_obj_str_get_str (path_in );
122117 const char * new_path = mp_obj_str_get_str (path_out );
123- FRESULT res = f_rename (old_path , new_path );
118+ FRESULT res = f_rename (& self -> fatfs , old_path , new_path );
124119 if (res == FR_EXIST ) {
125120 // if new_path exists then try removing it (but only if it's a file)
126- fat_vfs_remove_internal (path_out , 0 ); // 0 == file attribute
121+ fat_vfs_remove_internal (vfs_in , path_out , 0 ); // 0 == file attribute
127122 // try to rename again
128- res = f_rename (old_path , new_path );
123+ res = f_rename (& self -> fatfs , old_path , new_path );
129124 }
130125 if (res == FR_OK ) {
131126 return mp_const_none ;
@@ -137,9 +132,9 @@ STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_
137132STATIC MP_DEFINE_CONST_FUN_OBJ_3 (fat_vfs_rename_obj , fat_vfs_rename );
138133
139134STATIC mp_obj_t fat_vfs_mkdir (mp_obj_t vfs_in , mp_obj_t path_o ) {
140- ( void ) vfs_in ;
135+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
141136 const char * path = mp_obj_str_get_str (path_o );
142- FRESULT res = f_mkdir (path );
137+ FRESULT res = f_mkdir (& self -> fatfs , path );
143138 if (res == FR_OK ) {
144139 return mp_const_none ;
145140 } else {
@@ -150,15 +145,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_mkdir_obj, fat_vfs_mkdir);
150145
151146/// Change current directory.
152147STATIC mp_obj_t fat_vfs_chdir (mp_obj_t vfs_in , mp_obj_t path_in ) {
153- ( void ) vfs_in ;
148+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
154149 const char * path ;
155150 path = mp_obj_str_get_str (path_in );
156151
157- FRESULT res = f_chdrive (path );
158-
159- if (res == FR_OK ) {
160- res = f_chdir (path );
161- }
152+ FRESULT res = f_chdir (& self -> fatfs , path );
162153
163154 if (res != FR_OK ) {
164155 mp_raise_OSError (fresult_to_errno_table [res ]);
@@ -170,14 +161,18 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_chdir_obj, fat_vfs_chdir);
170161
171162/// Get the current directory.
172163STATIC mp_obj_t fat_vfs_getcwd (mp_obj_t vfs_in ) {
173- ( void ) vfs_in ;
164+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
174165 char buf [MICROPY_ALLOC_PATH_MAX + 1 ];
175- FRESULT res = f_getcwd (buf , sizeof buf );
176-
166+ memcpy (buf , self -> str , self -> len );
167+ FRESULT res = f_getcwd ( & self -> fatfs , buf + self -> len , sizeof ( buf ) - self -> len );
177168 if (res != FR_OK ) {
178169 mp_raise_OSError (fresult_to_errno_table [res ]);
179170 }
180-
171+ // remove trailing / if in root dir, because we prepended the mount point
172+ size_t l = strlen (buf );
173+ if (res == FR_OK && buf [l - 1 ] == '/' ) {
174+ buf [l - 1 ] = 0 ;
175+ }
181176 return mp_obj_new_str (buf , strlen (buf ), false);
182177}
183178STATIC MP_DEFINE_CONST_FUN_OBJ_1 (fat_vfs_getcwd_obj , fat_vfs_getcwd );
@@ -202,14 +197,10 @@ STATIC bool path_equal(const char *path, const char *path_canonical) {
202197/// \function stat(path)
203198/// Get the status of a file or directory.
204199STATIC mp_obj_t fat_vfs_stat (mp_obj_t vfs_in , mp_obj_t path_in ) {
205- ( void ) vfs_in ;
200+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
206201 const char * path = mp_obj_str_get_str (path_in );
207202
208203 FILINFO fno ;
209- #if _USE_LFN
210- fno .lfname = NULL ;
211- fno .lfsize = 0 ;
212- #endif
213204 FRESULT res ;
214205
215206 if (path_equal (path , "/" )) {
@@ -233,7 +224,7 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
233224 }
234225 if (res == FR_NO_PATH ) {
235226 // stat normal file
236- res = f_stat (path , & fno );
227+ res = f_stat (& self -> fatfs , path , & fno );
237228 }
238229 if (res != FR_OK ) {
239230 mp_raise_OSError (fresult_to_errno_table [res ]);
@@ -272,12 +263,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_stat_obj, fat_vfs_stat);
272263
273264// Get the status of a VFS.
274265STATIC mp_obj_t fat_vfs_statvfs (mp_obj_t vfs_in , mp_obj_t path_in ) {
275- ( void ) vfs_in ;
276- const char * path = mp_obj_str_get_str ( path_in ) ;
266+ mp_obj_fat_vfs_t * self = MP_OBJ_TO_PTR ( vfs_in ) ;
267+ ( void ) path_in ;
277268
278- FATFS * fatfs ;
279269 DWORD nclst ;
280- FRESULT res = f_getfree (path , & nclst , & fatfs );
270+ FATFS * fatfs = & self -> fatfs ;
271+ FRESULT res = f_getfree (fatfs , & nclst );
281272 if (FR_OK != res ) {
282273 mp_raise_OSError (fresult_to_errno_table [res ]);
283274 }
0 commit comments