From f2a20e8a38a3a0e4b5fd43d31519d7984b868678 Mon Sep 17 00:00:00 2001 From: P-R-O-C-H-Y <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 1 Oct 2021 16:16:59 +0200 Subject: [PATCH] SD.open() new feature for creating all folders in path (#5721) * SD.open() new feature for creating all folders in path This PR adds to the SD.open() function option to create all folders to the file. SD.open(const char* path, const char* mode, const bool create) Default value of create is false. When true folders are created. From issue #5019 * Update vfs_api.cpp memccpy -> memcpy * File f = open() edit added false for create --- libraries/FFat/src/FFat.cpp | 2 +- libraries/FS/src/FS.cpp | 8 ++--- libraries/FS/src/FS.h | 4 +-- libraries/FS/src/FSImpl.h | 2 +- libraries/FS/src/vfs_api.cpp | 56 ++++++++++++++++++++++++----- libraries/FS/src/vfs_api.h | 2 +- libraries/LittleFS/src/LittleFS.cpp | 2 +- libraries/SPIFFS/src/SPIFFS.cpp | 2 +- 8 files changed, 58 insertions(+), 20 deletions(-) diff --git a/libraries/FFat/src/FFat.cpp b/libraries/FFat/src/FFat.cpp index 6441dfca..f58bc444 100644 --- a/libraries/FFat/src/FFat.cpp +++ b/libraries/FFat/src/FFat.cpp @@ -168,7 +168,7 @@ size_t F_Fat::freeBytes() bool F_Fat::exists(const char* path) { - File f = open(path, "r"); + File f = open(path, "r",false); return (f == true) && !f.isDirectory(); } diff --git a/libraries/FS/src/FS.cpp b/libraries/FS/src/FS.cpp index 3050ec41..f5e9a8ab 100644 --- a/libraries/FS/src/FS.cpp +++ b/libraries/FS/src/FS.cpp @@ -186,18 +186,18 @@ void File::rewindDirectory(void) _p->rewindDirectory(); } -File FS::open(const String& path, const char* mode) +File FS::open(const String& path, const char* mode, const bool create) { - return open(path.c_str(), mode); + return open(path.c_str(), mode, create); } -File FS::open(const char* path, const char* mode) +File FS::open(const char* path, const char* mode, const bool create) { if (!_impl) { return File(); } - return File(_impl->open(path, mode)); + return File(_impl->open(path, mode, create)); } bool FS::exists(const char* path) diff --git a/libraries/FS/src/FS.h b/libraries/FS/src/FS.h index 2c4aa301..c3a1c51c 100644 --- a/libraries/FS/src/FS.h +++ b/libraries/FS/src/FS.h @@ -89,8 +89,8 @@ class FS public: FS(FSImplPtr impl) : _impl(impl) { } - File open(const char* path, const char* mode = FILE_READ); - File open(const String& path, const char* mode = FILE_READ); + File open(const char* path, const char* mode = FILE_READ, const bool create = false); + File open(const String& path, const char* mode = FILE_READ, const bool create = false); bool exists(const char* path); bool exists(const String& path); diff --git a/libraries/FS/src/FSImpl.h b/libraries/FS/src/FSImpl.h index 51c5915a..4c5c9786 100644 --- a/libraries/FS/src/FSImpl.h +++ b/libraries/FS/src/FSImpl.h @@ -53,7 +53,7 @@ protected: public: FSImpl() : _mountpoint(NULL) { } virtual ~FSImpl() { } - virtual FileImplPtr open(const char* path, const char* mode) = 0; + virtual FileImplPtr open(const char* path, const char* mode, const bool create) = 0; virtual bool exists(const char* path) = 0; virtual bool rename(const char* pathFrom, const char* pathTo) = 0; virtual bool remove(const char* path) = 0; diff --git a/libraries/FS/src/vfs_api.cpp b/libraries/FS/src/vfs_api.cpp index aea37b1e..e43b4397 100644 --- a/libraries/FS/src/vfs_api.cpp +++ b/libraries/FS/src/vfs_api.cpp @@ -16,7 +16,7 @@ using namespace fs; -FileImplPtr VFSImpl::open(const char* fpath, const char* mode) +FileImplPtr VFSImpl::open(const char* fpath, const char* mode, const bool create) { if(!_mountpoint) { log_e("File system is not mounted"); @@ -37,7 +37,7 @@ FileImplPtr VFSImpl::open(const char* fpath, const char* mode) sprintf(temp,"%s%s", _mountpoint, fpath); struct stat st; - //file lound + //file found if(!stat(temp, &st)) { free(temp); if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) { @@ -47,12 +47,6 @@ FileImplPtr VFSImpl::open(const char* fpath, const char* mode) return FileImplPtr(); } - //file not found but mode permits creation - if(mode && mode[0] != 'r') { - free(temp); - return std::make_shared(this, fpath, mode); - } - //try to open this as directory (might be mount point) DIR * d = opendir(temp); if(d) { @@ -61,7 +55,51 @@ FileImplPtr VFSImpl::open(const char* fpath, const char* mode) return std::make_shared(this, fpath, mode); } - log_e("%s does not exist", temp); + //file not found but mode permits file creation without folder creation + if((mode && mode[0] != 'r') && (!create)){ + free(temp); + return std::make_shared(this, fpath, mode); + } + + ////file not found but mode permits file creation and folder creation + if((mode && mode[0] != 'r') && create){ + + char *token; + char *folder = (char *)malloc(strlen(fpath)); + + int start_index = 0; + int end_index = 0; + + token = strchr(fpath+1,'/'); + end_index = (token-fpath); + + while (token != NULL) + { + memcpy(folder,fpath + start_index, end_index-start_index); + folder[end_index-start_index] = '\0'; + + if(!VFSImpl::mkdir(folder)) + { + log_e("Creating folder: %s failed!",folder); + return FileImplPtr(); + } + + token=strchr(token+1,'/'); + if(token != NULL) + { + end_index = (token-fpath); + memset(folder, 0, strlen(folder)); + } + + } + + free(folder); + free(temp); + return std::make_shared(this, fpath, mode); + + } + + log_e("%s does not exist, no permits for creation", temp); free(temp); return FileImplPtr(); } diff --git a/libraries/FS/src/vfs_api.h b/libraries/FS/src/vfs_api.h index 58fd86fd..f79852cd 100644 --- a/libraries/FS/src/vfs_api.h +++ b/libraries/FS/src/vfs_api.h @@ -35,7 +35,7 @@ protected: friend class VFSFileImpl; public: - FileImplPtr open(const char* path, const char* mode) override; + FileImplPtr open(const char* path, const char* mode, const bool create) override; bool exists(const char* path) override; bool rename(const char* pathFrom, const char* pathTo) override; bool remove(const char* path) override; diff --git a/libraries/LittleFS/src/LittleFS.cpp b/libraries/LittleFS/src/LittleFS.cpp index 7989dcb6..9ea2320e 100644 --- a/libraries/LittleFS/src/LittleFS.cpp +++ b/libraries/LittleFS/src/LittleFS.cpp @@ -45,7 +45,7 @@ LittleFSImpl::LittleFSImpl() bool LittleFSImpl::exists(const char* path) { - File f = open(path, "r"); + File f = open(path, "r",false); return (f == true); } diff --git a/libraries/SPIFFS/src/SPIFFS.cpp b/libraries/SPIFFS/src/SPIFFS.cpp index d3e16654..0fb2eff0 100644 --- a/libraries/SPIFFS/src/SPIFFS.cpp +++ b/libraries/SPIFFS/src/SPIFFS.cpp @@ -39,7 +39,7 @@ SPIFFSImpl::SPIFFSImpl() bool SPIFFSImpl::exists(const char* path) { - File f = open(path, "r"); + File f = open(path, "r",false); return (f == true) && !f.isDirectory(); }