Something went wrong. Try again.
A fork of https://github.com/crosspoint-reader/crosspoint-reader
Something went wrong. Try again.
6.5 kB · 159 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160#define HAL_STORAGE_IMPL#include "HalStorage.h"
#include <FS.h> // need to be included before SdFat.h for compatibility with FS.h's File class#include <Logging.h>#include <SDCardManager.h>
#include <cassert>
#define SDCard SDCardManager::getInstance()
HalStorage HalStorage::instance;
HalStorage::HalStorage() { storageMutex = xSemaphoreCreateMutex(); assert(storageMutex != nullptr);}
// begin() and ready() are only called from setup, no need to acquire mutex for them
bool HalStorage::begin() { return SDCard.begin(); }
bool HalStorage::ready() const { return SDCard.ready(); }
// For the rest of the methods, we acquire the mutex to ensure thread safety
class HalStorage::StorageLock { public: StorageLock() { xSemaphoreTake(HalStorage::getInstance().storageMutex, portMAX_DELAY); } ~StorageLock() { xSemaphoreGive(HalStorage::getInstance().storageMutex); }};
#define HAL_STORAGE_WRAPPED_CALL(method, ...) \ HalStorage::StorageLock lock; \ return SDCard.method(__VA_ARGS__);
std::vector<String> HalStorage::listFiles(const char* path, int maxFiles) { HAL_STORAGE_WRAPPED_CALL(listFiles, path, maxFiles);}
String HalStorage::readFile(const char* path) { HAL_STORAGE_WRAPPED_CALL(readFile, path); }
bool HalStorage::readFileToStream(const char* path, Print& out, size_t chunkSize) { HAL_STORAGE_WRAPPED_CALL(readFileToStream, path, out, chunkSize);}
size_t HalStorage::readFileToBuffer(const char* path, char* buffer, size_t bufferSize, size_t maxBytes) { HAL_STORAGE_WRAPPED_CALL(readFileToBuffer, path, buffer, bufferSize, maxBytes);}
bool HalStorage::writeFile(const char* path, const String& content) { HAL_STORAGE_WRAPPED_CALL(writeFile, path, content);}
bool HalStorage::ensureDirectoryExists(const char* path) { HAL_STORAGE_WRAPPED_CALL(ensureDirectoryExists, path); }
class HalFile::Impl { public: Impl(FsFile&& fsFile) : file(std::move(fsFile)) {} FsFile file;};
HalFile::HalFile() = default;
HalFile::HalFile(std::unique_ptr<Impl> impl) : impl(std::move(impl)) {}
HalFile::~HalFile() = default;
HalFile::HalFile(HalFile&&) = default;
HalFile& HalFile::operator=(HalFile&&) = default;
HalFile HalStorage::open(const char* path, const oflag_t oflag) { StorageLock lock; // ensure thread safety for the duration of this function return HalFile(std::make_unique<HalFile::Impl>(SDCard.open(path, oflag)));}
bool HalStorage::mkdir(const char* path, const bool pFlag) { HAL_STORAGE_WRAPPED_CALL(mkdir, path, pFlag); }
bool HalStorage::exists(const char* path) { HAL_STORAGE_WRAPPED_CALL(exists, path); }
bool HalStorage::remove(const char* path) { HAL_STORAGE_WRAPPED_CALL(remove, path); }bool HalStorage::rename(const char* oldPath, const char* newPath) { HAL_STORAGE_WRAPPED_CALL(rename, oldPath, newPath);}
bool HalStorage::rmdir(const char* path) { HAL_STORAGE_WRAPPED_CALL(rmdir, path); }
bool HalStorage::openFileForRead(const char* moduleName, const char* path, HalFile& file) { StorageLock lock; // ensure thread safety for the duration of this function FsFile fsFile; bool ok = SDCard.openFileForRead(moduleName, path, fsFile); file = HalFile(std::make_unique<HalFile::Impl>(std::move(fsFile))); return ok;}
bool HalStorage::openFileForRead(const char* moduleName, const std::string& path, HalFile& file) { return openFileForRead(moduleName, path.c_str(), file);}
bool HalStorage::openFileForRead(const char* moduleName, const String& path, HalFile& file) { return openFileForRead(moduleName, path.c_str(), file);}
bool HalStorage::openFileForWrite(const char* moduleName, const char* path, HalFile& file) { StorageLock lock; // ensure thread safety for the duration of this function FsFile fsFile; bool ok = SDCard.openFileForWrite(moduleName, path, fsFile); file = HalFile(std::make_unique<HalFile::Impl>(std::move(fsFile))); return ok;}
bool HalStorage::openFileForWrite(const char* moduleName, const std::string& path, HalFile& file) { return openFileForWrite(moduleName, path.c_str(), file);}
bool HalStorage::openFileForWrite(const char* moduleName, const String& path, HalFile& file) { return openFileForWrite(moduleName, path.c_str(), file);}
bool HalStorage::removeDir(const char* path) { HAL_STORAGE_WRAPPED_CALL(removeDir, path); }
// HalFile implementation// Allow doing file operations while ensuring thread safety via HalStorage's mutex.// Please keep the list below in sync with the HalFile.h header
#define HAL_FILE_WRAPPED_CALL(method, ...) \ HalStorage::StorageLock lock; \ assert(impl != nullptr); \ return impl->file.method(__VA_ARGS__);
#define HAL_FILE_FORWARD_CALL(method, ...) \ assert(impl != nullptr); \ return impl->file.method(__VA_ARGS__);
void HalFile::flush() { HAL_FILE_WRAPPED_CALL(flush, ); }size_t HalFile::getName(char* name, size_t len) { HAL_FILE_WRAPPED_CALL(getName, name, len); }size_t HalFile::size() { HAL_FILE_FORWARD_CALL(size, ); } // already thread-safe, no need to wrapsize_t HalFile::fileSize() { HAL_FILE_FORWARD_CALL(fileSize, ); } // already thread-safe, no need to wrapbool HalFile::seek(size_t pos) { HAL_FILE_WRAPPED_CALL(seekSet, pos); }bool HalFile::seekCur(int64_t offset) { HAL_FILE_WRAPPED_CALL(seekCur, offset); }bool HalFile::seekSet(size_t offset) { HAL_FILE_WRAPPED_CALL(seekSet, offset); }int HalFile::available() const { HAL_FILE_WRAPPED_CALL(available, ); }size_t HalFile::position() const { HAL_FILE_WRAPPED_CALL(position, ); }int HalFile::read(void* buf, size_t count) { HAL_FILE_WRAPPED_CALL(read, buf, count); }int HalFile::read() { HAL_FILE_WRAPPED_CALL(read, ); }size_t HalFile::write(const void* buf, size_t count) { HAL_FILE_WRAPPED_CALL(write, buf, count); }size_t HalFile::write(uint8_t b) { HAL_FILE_WRAPPED_CALL(write, b); }bool HalFile::rename(const char* newPath) { HAL_FILE_WRAPPED_CALL(rename, newPath); }bool HalFile::isDirectory() const { HAL_FILE_FORWARD_CALL(isDirectory, ); } // already thread-safe, no need to wrapvoid HalFile::rewindDirectory() { HAL_FILE_WRAPPED_CALL(rewindDirectory, ); }bool HalFile::close() { HAL_FILE_WRAPPED_CALL(close, ); }HalFile HalFile::openNextFile() { HalStorage::StorageLock lock; assert(impl != nullptr); return HalFile(std::make_unique<Impl>(impl->file.openNextFile()));}bool HalFile::isOpen() const { return impl != nullptr && impl->file.isOpen(); } // already thread-safe, no need to wrapHalFile::operator bool() const { return isOpen(); }