1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-16 00:43:00 +03:00

FileSystem: interface changes and some additions

- rename mount to begin to be more in line with other libraries
- add rename and remove methods
- remove freestanding functions (mount,open,openDir) from public API until that part is ready
- fix resource leak in SPIFFSDirImpl
This commit is contained in:
Ivan Grokhotkov
2015-07-30 13:44:34 +03:00
parent 544734bdc5
commit 4aa8e1b8d5
4 changed files with 153 additions and 40 deletions

View File

@ -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& 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& fs, const char* mountPoint);
/*
*/
struct MountEntry {
FSImplPtr fs;
String path;
MountEntry* next;
};
static MountEntry* s_mounted = nullptr;
template<>
bool mount<FS>(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

View File

@ -24,6 +24,9 @@
#include <Arduino.h>
#include <memory>
class File;
class Dir;
class FileImpl;
typedef std::shared_ptr<FileImpl> 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 <typename Tfs>
friend bool mount(Tfs& fs, const char* mountPoint);
};
extern FS SPIFFS;
template<>
bool mount<FS>(FS& fs, const char* mountPoint);
File open(const char* path, const char* mode);
Dir openDir(const char* path);
#endif //FS_H

View File

@ -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;
};

View File

@ -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();