Re-applied upstream PRs not yet merged to upstream/master: - #1055: Byte-level framebuffer writes (fillPhysicalHSpan*, optimized fillRect/drawLine/fillRectDither/fillPolygon) - #1027: Word-width cache (FNV-1a, 128-entry) and hyphenation early exit in ParsedText for 7-9% layout speedup - #1068: Already present in upstream — URL hyphenation fix - #1019: Already present in upstream — file extensions in browser - #1090/#1185/#1217: KOReader sync improvements — binary credential store, document hash caching, ChapterXPathIndexer integration - #1209: OPDS multi-server — OpdsBookBrowserActivity accepts OpdsServer, directory picker for downloads, download-complete prompt with open/back options - #857: Dictionary activities already ported in Phase 1/2 - #1003: Placeholder cover already integrated in Phase 2 Also fixed: STR_OFF i18n string, include paths, replaced Epub::isValidThumbnailBmp with Storage.exists, replaced StringUtils::checkFileExtension with FsHelpers equivalents. Made-with: Cursor
110 lines
3.6 KiB
C++
110 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include <Print.h>
|
|
#include <common/FsApiConstants.h> // for oflag_t
|
|
#include <freertos/semphr.h>
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
class HalFile;
|
|
|
|
class HalStorage {
|
|
public:
|
|
HalStorage();
|
|
bool begin();
|
|
bool ready() const;
|
|
std::vector<String> listFiles(const char* path = "/", int maxFiles = 200);
|
|
// Read the entire file at `path` into a String. Returns empty string on failure.
|
|
String readFile(const char* path);
|
|
// Low-memory helpers:
|
|
// Stream the file contents to a `Print` (e.g. `Serial`, or any `Print`-derived object).
|
|
// Returns true on success, false on failure.
|
|
bool readFileToStream(const char* path, Print& out, size_t chunkSize = 256);
|
|
// Read up to `bufferSize-1` bytes into `buffer`, null-terminating it. Returns bytes read.
|
|
size_t readFileToBuffer(const char* path, char* buffer, size_t bufferSize, size_t maxBytes = 0);
|
|
// Write a string to `path` on the SD card. Overwrites existing file.
|
|
// Returns true on success.
|
|
bool writeFile(const char* path, const String& content);
|
|
// Ensure a directory exists, creating it if necessary. Returns true on success.
|
|
bool ensureDirectoryExists(const char* path);
|
|
|
|
HalFile open(const char* path, const oflag_t oflag = O_RDONLY);
|
|
bool mkdir(const char* path, const bool pFlag = true);
|
|
bool exists(const char* path);
|
|
bool remove(const char* path);
|
|
bool rename(const char* oldPath, const char* newPath);
|
|
bool rmdir(const char* path);
|
|
|
|
bool openFileForRead(const char* moduleName, const char* path, HalFile& file);
|
|
bool openFileForRead(const char* moduleName, const std::string& path, HalFile& file);
|
|
bool openFileForRead(const char* moduleName, const String& path, HalFile& file);
|
|
bool openFileForWrite(const char* moduleName, const char* path, HalFile& file);
|
|
bool openFileForWrite(const char* moduleName, const std::string& path, HalFile& file);
|
|
bool openFileForWrite(const char* moduleName, const String& path, HalFile& file);
|
|
bool removeDir(const char* path);
|
|
|
|
static HalStorage& getInstance() { return instance; }
|
|
|
|
class StorageLock; // private class, used internally
|
|
|
|
private:
|
|
static HalStorage instance;
|
|
|
|
bool initialized = false;
|
|
SemaphoreHandle_t storageMutex = nullptr;
|
|
};
|
|
|
|
#define Storage HalStorage::getInstance()
|
|
|
|
class HalFile : public Print {
|
|
friend class HalStorage;
|
|
class Impl;
|
|
std::unique_ptr<Impl> impl;
|
|
explicit HalFile(std::unique_ptr<Impl> impl);
|
|
|
|
public:
|
|
HalFile();
|
|
~HalFile();
|
|
HalFile(HalFile&&);
|
|
HalFile& operator=(HalFile&&);
|
|
HalFile(const HalFile&) = delete;
|
|
HalFile& operator=(const HalFile&) = delete;
|
|
|
|
void flush();
|
|
size_t getName(char* name, size_t len);
|
|
size_t size();
|
|
size_t fileSize();
|
|
// Get modification date/time (FAT format: packed 16-bit date and time). Returns false if unavailable.
|
|
bool getModifyDateTime(uint16_t* pdate, uint16_t* ptime);
|
|
bool seek(size_t pos);
|
|
bool seekCur(int64_t offset);
|
|
bool seekSet(size_t offset);
|
|
int available() const;
|
|
size_t position() const;
|
|
int read(void* buf, size_t count);
|
|
int read(); // read a single byte
|
|
size_t write(const void* buf, size_t count);
|
|
size_t write(uint8_t b) override;
|
|
bool rename(const char* newPath);
|
|
bool isDirectory() const;
|
|
void rewindDirectory();
|
|
bool close();
|
|
HalFile openNextFile();
|
|
bool isOpen() const;
|
|
operator bool() const;
|
|
};
|
|
|
|
// Only do renaming FsFile to HalFile if this header is included by downstream code
|
|
// The renaming is to allow using the thread-safe HalFile instead of the raw FsFile, without needing to change the
|
|
// downstream code
|
|
#ifndef HAL_STORAGE_IMPL
|
|
using FsFile = HalFile;
|
|
#endif
|
|
|
|
// Downstream code must use Storage instead of SdMan
|
|
#ifdef SdMan
|
|
#undef SdMan
|
|
#endif
|