Skip to content

Add time to filesystem API #6544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 31, 2019
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions cores/esp8266/FS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,19 @@ String File::readString()
return ret;
}

time_t File::getLastWrite() {
if (!_p)
return 0;

return _p->getLastWrite();
}

void File::setTimeCallback(time_t (*cb)(void)) {
if (!_p)
return;
_p->setTimeCallback(cb);
}

File Dir::openFile(const char* mode) {
if (!_impl) {
return File();
Expand All @@ -192,7 +205,9 @@ File Dir::openFile(const char* mode) {
return File();
}

return File(_impl->openFile(om, am), _baseFS);
File f(_impl->openFile(om, am), _baseFS);
f.setTimeCallback(timeCallback);
return f;
}

String Dir::fileName() {
Expand All @@ -203,6 +218,12 @@ String Dir::fileName() {
return _impl->fileName();
}

time_t Dir::fileTime() {
if (!_impl)
return 0;
return _impl->fileTime();
}

size_t Dir::fileSize() {
if (!_impl) {
return 0;
Expand Down Expand Up @@ -241,6 +262,20 @@ bool Dir::rewind() {
return _impl->rewind();
}

time_t Dir::getLastWrite() {
if (!_impl)
return 0;

return _impl->getLastWrite();
}

void Dir::setTimeCallback(time_t (*cb)(void)) {
if (!_impl)
return;
_impl->setTimeCallback(cb);
}


bool FS::setConfig(const FSConfig &cfg) {
if (!_impl) {
return false;
Expand Down Expand Up @@ -315,7 +350,9 @@ File FS::open(const char* path, const char* mode) {
DEBUGV("FS::open: invalid mode `%s`\r\n", mode);
return File();
}
return File(_impl->open(path, om, am), this);
File f(_impl->open(path, om, am), this);
f.setTimeCallback(timeCallback);
return f;
}

bool FS::exists(const char* path) {
Expand All @@ -334,7 +371,9 @@ Dir FS::openDir(const char* path) {
return Dir();
}
DirImplPtr p = _impl->openDir(path);
return Dir(p, this);
Dir d(p, this);
d.setTimeCallback(timeCallback);
return d;
}

Dir FS::openDir(const String& path) {
Expand Down Expand Up @@ -385,6 +424,11 @@ bool FS::rename(const String& pathFrom, const String& pathTo) {
return rename(pathFrom.c_str(), pathTo.c_str());
}

void FS::setTimeCallback(time_t (*cb)(void)) {
if (!_impl)
return;
_impl->setTimeCallback(cb);
}


static bool sflags(const char* mode, OpenMode& om, AccessMode& am) {
Expand Down
34 changes: 23 additions & 11 deletions cores/esp8266/FS.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,16 @@ class File : public Stream

String readString() override;

time_t getLastWrite();
void setTimeCallback(time_t (*cb)(void));

protected:
FileImplPtr _p;

// Arduino SD class emulation
std::shared_ptr<Dir> _fakeDir;
FS *_baseFS;
time_t (*timeCallback)(void) = nullptr;
};

class Dir {
Expand All @@ -126,15 +130,21 @@ class Dir {

String fileName();
size_t fileSize();
time_t fileTime();
bool isFile() const;
bool isDirectory() const;

bool next();
bool rewind();

time_t getLastWrite();
void setTimeCallback(time_t (*cb)(void));

protected:
DirImplPtr _impl;
FS *_baseFS;
time_t (*timeCallback)(void) = nullptr;

};

// Backwards compatible, <4GB filesystem usage
Expand All @@ -161,12 +171,10 @@ struct FSInfo64 {
class FSConfig
{
public:
FSConfig(bool autoFormat = true) {
_type = FSConfig::fsid::FSId;
_autoFormat = autoFormat;
}
static constexpr uint32_t FSId = 0x00000000;

FSConfig(uint32_t type = FSId, bool autoFormat = true) : _type(type), _autoFormat(autoFormat) { }

enum fsid { FSId = 0x00000000 };
FSConfig setAutoFormat(bool val = true) {
_autoFormat = val;
return *this;
Expand All @@ -179,17 +187,17 @@ class FSConfig
class SPIFFSConfig : public FSConfig
{
public:
SPIFFSConfig(bool autoFormat = true) {
_type = SPIFFSConfig::fsid::FSId;
_autoFormat = autoFormat;
}
enum fsid { FSId = 0x53504946 };
static constexpr uint32_t FSId = 0x53504946;
SPIFFSConfig(bool autoFormat = true) : FSConfig(FSId, autoFormat) { }

// Inherit _type and _autoFormat
// nothing yet, enableTime TBD when SPIFFS has metadate
};

class FS
{
public:
FS(FSImplPtr impl) : _impl(impl) { }
FS(FSImplPtr impl) : _impl(impl) { timeCallback = _defaultTimeCB; }

bool setConfig(const FSConfig &cfg);

Expand Down Expand Up @@ -225,10 +233,14 @@ class FS
bool gc();
bool check();

void setTimeCallback(time_t (*cb)(void));

friend class ::SDClass; // More of a frenemy, but SD needs internal implementation to get private FAT bits
protected:
FSImplPtr _impl;
FSImplPtr getImpl() { return _impl; }
time_t (*timeCallback)(void);
static time_t _defaultTimeCB(void) { return time(NULL); }
};

} // namespace fs
Expand Down
35 changes: 35 additions & 0 deletions cores/esp8266/FSImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ class FileImpl {
virtual const char* fullName() const = 0;
virtual bool isFile() const = 0;
virtual bool isDirectory() const = 0;

// Filesystems *may* support a timestamp per-file, so allow the user to override with
// their own callback for *this specific* file (as opposed to the FSImpl call of the
// same name. The default implementation simply returns time(&null)
virtual void setTimeCallback(time_t (*cb)(void)) { timeCallback = cb; }

// Return the last written time for a file. Undefined when called on a writable file
// as the FS is allowed to return either the time of the last write() operation or the
// time present in the filesystem metadata (often the last time the file was closed)
virtual time_t getLastWrite() { return 0; } // Default is to not support timestamps

protected:
time_t (*timeCallback)(void) = nullptr;
};

enum OpenMode {
Expand All @@ -62,10 +75,24 @@ class DirImpl {
virtual FileImplPtr openFile(OpenMode openMode, AccessMode accessMode) = 0;
virtual const char* fileName() = 0;
virtual size_t fileSize() = 0;
virtual time_t fileTime() { return 0; } // By default, FS doesn't report file times
virtual bool isFile() const = 0;
virtual bool isDirectory() const = 0;
virtual bool next() = 0;
virtual bool rewind() = 0;

// Filesystems *may* support a timestamp per-file, so allow the user to override with
// their own callback for *this specific* file (as opposed to the FSImpl call of the
// same name. The default implementation simply returns time(&null)
virtual void setTimeCallback(time_t (*cb)(void)) { timeCallback = cb; }

// Return the last written time for a file. Undefined when called on a writable file
// as the FS is allowed to return either the time of the last write() operation or the
// time present in the filesystem metadata (often the last time the file was closed)
virtual time_t getLastWrite() { return 0; } // Default is to not support timestamps

protected:
time_t (*timeCallback)(void) = nullptr;
};

class FSImpl {
Expand All @@ -86,6 +113,14 @@ class FSImpl {
virtual bool rmdir(const char* path) = 0;
virtual bool gc() { return true; } // May not be implemented in all file systems.
virtual bool check() { return true; } // May not be implemented in all file systems.

// Filesystems *may* support a timestamp per-file, so allow the user to override with
// their own callback for all files on this FS. The default implementation simply
// returns the present time as reported by time(&null)
virtual void setTimeCallback(time_t (*cb)(void)) { timeCallback = cb; }

protected:
time_t (*timeCallback)(void) = nullptr;
};

} // namespace fs
Expand Down
2 changes: 1 addition & 1 deletion cores/esp8266/spiffs_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class SPIFFSImpl : public FSImpl

bool setConfig(const FSConfig &cfg) override
{
if ((cfg._type != SPIFFSConfig::fsid::FSId) || (SPIFFS_mounted(&_fs) != 0)) {
if ((cfg._type != SPIFFSConfig::FSId) || (SPIFFS_mounted(&_fs) != 0)) {
return false;
}
_cfg = *static_cast<const SPIFFSConfig *>(&cfg);
Expand Down
Loading