Files
crosspoint-reader-mod/lib/hal/HalStorage.h
cottongin 60a3e21c0e mod: Phase 3 — Re-port unmerged upstream PRs
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
2026-03-07 16:15:42 -05:00

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