diff --git a/cores/esp8266/FS.cpp b/cores/esp8266/FS.cpp index b2d32fbb5..18eda0c86 100644 --- a/cores/esp8266/FS.cpp +++ b/cores/esp8266/FS.cpp @@ -143,7 +143,16 @@ bool Dir::next() { return _impl->next(); } +bool FS::begin() { + if (!_impl) { + return false; + } + return _impl->begin(); +} +File FS::open(const String& path, const char* mode) { + return open(path.c_str(), mode); +} File FS::open(const char* path, const char* mode) { if (!_impl) { @@ -160,46 +169,40 @@ File FS::open(const char* path, const char* mode) { return File(_impl->open(path, om, am)); } -File FS::open(const String& path, const char* mode) { - return FS::open(path.c_str(), mode); -} - Dir FS::openDir(const char* path) { if (!_impl) { return Dir(); } - return Dir(_impl->openDir(path)); } Dir FS::openDir(const String& path) { - return FS::openDir(path.c_str()); + return openDir(path.c_str()); } -struct MountEntry { - FSImplPtr fs; - String path; - MountEntry* next; -}; - -static MountEntry* s_mounted = nullptr; - -template<> -bool mount(FS& fs, const char* mountPoint) { - FSImplPtr p = fs._impl; - if (!p || !p->mount()) { - DEBUGV("FSImpl mount failed\r\n"); +bool FS::remove(const char* path) { + if (!_impl) { return false; } - - MountEntry* entry = new MountEntry; - entry->fs = p; - entry->path = mountPoint; - entry->next = s_mounted; - s_mounted = entry; - return true; + return _impl->remove(path); } +bool FS::remove(const String& path) { + return remove(path.c_str()); +} + +bool FS::rename(const char* pathFrom, const char* pathTo) { + if (!_impl) { + return false; + } + return _impl->rename(pathFrom, pathTo); +} + +bool FS::rename(const String& pathFrom, const String& pathTo) { + return rename(pathFrom.c_str(), pathTo.c_str()); +} + + static bool sflags(const char* mode, OpenMode& om, AccessMode& am) { switch (mode[0]) { case 'r': @@ -228,3 +231,80 @@ static bool sflags(const char* mode, OpenMode& om, AccessMode& am) { } return true; } + + +#if defined(FS_FREESTANDING_FUNCTIONS) + +/* +TODO: move these functions to public API: +*/ +File open(const char* path, const char* mode); +File open(String& path, const char* mode); + +Dir openDir(const char* path); +Dir openDir(String& path); + +template<> +bool mount(FS& fs, const char* mountPoint); +/* +*/ + + +struct MountEntry { + FSImplPtr fs; + String path; + MountEntry* next; +}; + +static MountEntry* s_mounted = nullptr; + +template<> +bool mount(FS& fs, const char* mountPoint) { + FSImplPtr p = fs._impl; + if (!p || !p->mount()) { + DEBUGV("FSImpl mount failed\r\n"); + return false; + } + + !make sure mountPoint has trailing '/' here + + MountEntry* entry = new MountEntry; + entry->fs = p; + entry->path = mountPoint; + entry->next = s_mounted; + s_mounted = entry; + return true; +} + + +/* + iterate over MountEntries and look for the ones which match the path +*/ +File open(const char* path, const char* mode) { + OpenMode om; + AccessMode am; + if (!sflags(mode, om, am)) { + DEBUGV("open: invalid mode `%s`\r\n", mode); + return File(); + } + + for (MountEntry* entry = s_mounted; entry; entry = entry->next) { + size_t offset = entry->path.length(); + if (strstr(path, entry->path.c_str())) { + File result = entry->fs->open(path + offset); + if (result) + return result; + } + } + + return File(); +} + +File open(const String& path, const char* mode) { + return FS::open(path.c_str(), mode); +} + +Dir openDir(const String& path) { + return openDir(path.c_str()); +} +#endif diff --git a/cores/esp8266/FS.h b/cores/esp8266/FS.h index e45871a62..ce6d220ba 100644 --- a/cores/esp8266/FS.h +++ b/cores/esp8266/FS.h @@ -24,6 +24,9 @@ #include #include +class File; +class Dir; + class FileImpl; typedef std::shared_ptr FileImplPtr; class FSImpl; @@ -82,25 +85,26 @@ class FS { public: FS(FSImplPtr impl) : _impl(impl) { } + + bool begin(); + File open(const char* path, const char* mode); File open(const String& path, const char* mode); + Dir openDir(const char* path); Dir openDir(const String& path); + bool remove(const char* path); + bool remove(const String& path); + + bool rename(const char* pathFrom, const char* pathTo); + bool rename(const String& pathFrom, const String& pathTo); + protected: FSImplPtr _impl; - template - friend bool mount(Tfs& fs, const char* mountPoint); }; extern FS SPIFFS; -template<> -bool mount(FS& fs, const char* mountPoint); - -File open(const char* path, const char* mode); - -Dir openDir(const char* path); - #endif //FS_H diff --git a/cores/esp8266/FSImpl.h b/cores/esp8266/FSImpl.h index 1bc6992d7..8977e64c0 100644 --- a/cores/esp8266/FSImpl.h +++ b/cores/esp8266/FSImpl.h @@ -50,6 +50,7 @@ enum AccessMode { class DirImpl { public: + virtual ~DirImpl() { } virtual FileImplPtr openFile(OpenMode openMode, AccessMode accessMode) = 0; virtual const char* fileName() = 0; virtual bool next() = 0; @@ -57,9 +58,11 @@ public: class FSImpl { public: + virtual bool begin() = 0; virtual FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) = 0; virtual DirImplPtr openDir(const char* path) = 0; - virtual bool mount() = 0; + virtual bool rename(const char* pathFrom, const char* pathTo) = 0; + virtual bool remove(const char* path) = 0; }; diff --git a/cores/esp8266/spiffs_api.cpp b/cores/esp8266/spiffs_api.cpp index d86f18272..d63a1bcd4 100644 --- a/cores/esp8266/spiffs_api.cpp +++ b/cores/esp8266/spiffs_api.cpp @@ -57,21 +57,43 @@ public: DirImplPtr openDir(const char* path) override; - bool mount() override { + bool rename(const char* pathFrom, const char* pathTo) override { + char tmpNameFrom[SPIFFS_OBJ_NAME_LEN]; + strlcpy(tmpNameFrom, pathFrom, sizeof(tmpNameFrom)); + char tmpNameTo[SPIFFS_OBJ_NAME_LEN]; + strlcpy(tmpNameTo, pathTo, sizeof(tmpNameTo)); + auto rc = SPIFFS_rename(&_fs, tmpNameFrom, tmpNameTo); + if (rc != SPIFFS_OK) { + DEBUGV("SPIFFS_rename: rc=%d, from=`%s`, to=`%s`\r\n", rc, + pathFrom, pathTo); + return false; + } + return true; + } + + bool remove(const char* path) override { + char tmpName[SPIFFS_OBJ_NAME_LEN]; + strlcpy(tmpName, path, sizeof(tmpName)); + auto rc = SPIFFS_remove(&_fs, tmpName); + if (rc != SPIFFS_OK) { + DEBUGV("SPIFFS_remove: rc=%d path=`%s`\r\n", rc, path); + return false; + } + return true; + } + + bool begin() override { if (SPIFFS_mounted(&_fs) != 0) { return true; } - if (_tryMount()) { return true; } - auto rc = SPIFFS_format(&_fs); if (rc != SPIFFS_OK) { DEBUGV("SPIFFS_format: rc=%d, err=%d\r\n", rc, _fs.err_code); return false; } - return _tryMount(); } @@ -252,6 +274,10 @@ public: { } + ~SPIFFSDirImpl() override { + SPIFFS_closedir(&_dir); + } + FileImplPtr openFile(OpenMode openMode, AccessMode accessMode) override { if (!_valid) { return FileImplPtr();