Skip to content
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

Add LittleFS libs from ESP8266 project #189

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
459 changes: 393 additions & 66 deletions cores/common/arduino/libraries/common/FS/FS.cpp

Large diffs are not rendered by default.

244 changes: 197 additions & 47 deletions cores/common/arduino/libraries/common/FS/FS.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,53 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#pragma once
#ifndef FS_H
#define FS_H

#include <../include/time.h> // See issue #6714
#include <Arduino.h>
#include <memory>

namespace fs {
class SDClass;

#define FILE_READ "r"
#define FILE_WRITE "w"
#define FILE_APPEND "a"
namespace fs {

class File;
class Dir;
class FS;

class FileImpl;
typedef std::shared_ptr<FileImpl> FileImplPtr;
class FSImpl;
typedef std::shared_ptr<FSImpl> FSImplPtr;
class DirImpl;
typedef std::shared_ptr<DirImpl> DirImplPtr;

template <typename Tfs>
bool mount(Tfs &fs, const char *mountPoint);

enum SeekMode { SeekSet = 0, SeekCur = 1, SeekEnd = 2 };

class File : public Stream {
public:
File(FileImplPtr p = FileImplPtr()) : _p(p) {
_timeout = 0;
}
File(FileImplPtr p = FileImplPtr(), FS *baseFS = nullptr) : _p(p), _fakeDir(nullptr), _baseFS(baseFS) {}

// Print methods:
size_t write(uint8_t) override;
size_t write(const uint8_t *buf, size_t size) override;
int availableForWrite() override;

// Stream methods:
int available() override;
int read() override;
int peek() override;
void flush() override;
size_t read(uint8_t *buf, size_t size);

size_t readBytes(char *buffer, size_t length) {
return read((uint8_t *)buffer, length);
}

int read(uint8_t *buf, size_t size);
bool seek(uint32_t pos, SeekMode mode);

bool seek(uint32_t pos) {
Expand All @@ -64,52 +73,170 @@ class File : public Stream {

size_t position() const;
size_t size() const;
bool setBufferSize(size_t size);

virtual ssize_t streamRemaining() {
return (ssize_t)size() - (ssize_t)position();
}

void close();
operator bool() const;
time_t getLastWrite();
const char *path() const;
const char *name() const;
const char *fullName() const; // Includes path
bool truncate(uint32_t size);

bool isFile() const;
bool isDirectory() const;

// Arduino "class SD" methods for compatibility
// TODO use stream::send / check read(buf,size) result
template <typename T>
size_t write(T &src) {
uint8_t obuf[256];
size_t doneLen = 0;
size_t sentLen;

while (src.available() > (int)sizeof(obuf)) {
src.read(obuf, sizeof(obuf));
sentLen = write(obuf, sizeof(obuf));
doneLen = doneLen + sentLen;
if (sentLen != sizeof(obuf)) {
return doneLen;
}
}

size_t leftLen = src.available();
src.read(obuf, leftLen);
sentLen = write(obuf, leftLen);
doneLen = doneLen + sentLen;
return doneLen;
}

using Print::write;

void rewindDirectory();
File openNextFile();

String readString();

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

boolean isDirectory(void);
File openNextFile(const char *mode = FILE_READ);
void rewindDirectory(void);
// Stream::send configuration

bool inputCanTimeout() {
// unavailable data can't become later available
return false;
}

bool outputCanTimeout() {
// free space for write can't increase later
return false;
}

protected:
FileImplPtr _p;
time_t (*_timeCallback)(void) = nullptr;

// Arduino SD class emulation
std::shared_ptr<Dir> _fakeDir;
FS *_baseFS;
};

class Dir {
public:
Dir(DirImplPtr impl = DirImplPtr(), FS *baseFS = nullptr) : _impl(impl), _baseFS(baseFS) {}

File openFile(const char *mode);

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

bool next();
bool rewind();

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

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

class FileImpl {
// Backwards compatible, <4GB filesystem usage
struct FSInfo {
size_t totalBytes;
size_t usedBytes;
size_t blockSize;
size_t pageSize;
size_t maxOpenFiles;
size_t maxPathLength;
};

// Support > 4GB filesystems (SD, etc.)
struct FSInfo64 {
uint64_t totalBytes;
uint64_t usedBytes;
size_t blockSize;
size_t pageSize;
size_t maxOpenFiles;
size_t maxPathLength;
};

class FSConfig {
public:
virtual ~FileImpl() {}

virtual size_t write(const uint8_t *buf, size_t size) = 0;
virtual size_t read(uint8_t *buf, size_t size) = 0;
virtual void flush() = 0;
virtual bool seek(uint32_t pos, SeekMode mode) = 0;
virtual size_t position() const = 0;
virtual size_t size() const = 0;
virtual bool setBufferSize(size_t size) = 0;
virtual void close() = 0;
virtual time_t getLastWrite() = 0;
virtual const char *path() const = 0;
virtual const char *name() const = 0;
virtual boolean isDirectory(void) = 0;
virtual FileImplPtr openNextFile(const char *mode) = 0;
virtual void rewindDirectory(void) = 0;
virtual operator bool() = 0;
static constexpr uint32_t FSId = 0x00000000;

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

FSConfig setAutoFormat(bool val = true) {
_autoFormat = val;
return *this;
}

uint32_t _type;
bool _autoFormat;
};

class SPIFFSConfig : public FSConfig {
public:
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);

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 begin();
void end();

bool format();
bool info(FSInfo &info);
bool info64(FSInfo64 &info);

File open(const char *path, const char *mode = "r");
// File open(const char* path, const char* mode);
File open(const String &path, const char *mode);

bool exists(const char *path);
bool exists(const String &path);

Dir openDir(const char *path);
Dir openDir(const String &path);

bool remove(const char *path);
bool remove(const String &path);

Expand All @@ -122,31 +249,54 @@ class FS {
bool rmdir(const char *path);
bool rmdir(const String &path);

// Low-level FS routines, not needed by most applications
bool gc();
bool check();

time_t getCreationTime();

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

class FSImpl {
public:
FSImpl() {}
FSImplPtr getImpl() {
return _impl;
}

virtual ~FSImpl() {}
time_t (*_timeCallback)(void) = nullptr;

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;
virtual bool mkdir(const char *path) = 0;
virtual bool rmdir(const char *path) = 0;
static time_t _defaultTimeCB(void) {
return time(NULL);
}
};

} // namespace fs

extern "C" {
void close_all_fs(void);
void littlefs_request_end(void);
void spiffs_request_end(void);
}

#ifndef FS_NO_GLOBALS
using fs::Dir;
using fs::File;
using fs::FS;
using fs::FSConfig;
using fs::FSInfo;
using fs::SeekCur;
using fs::SeekEnd;
using fs::SeekMode;
using fs::SeekSet;
using fs::SPIFFSConfig;
#endif // FS_NO_GLOBALS

#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SPIFFS)
extern fs::FS SPIFFS
__attribute__((deprecated("SPIFFS has been deprecated. Please consider moving to LittleFS or other filesystems.")));
#endif

#endif // FS_H
Loading
Loading