This commit is contained in:
Xuan-Son Nguyen 2026-02-03 22:09:52 +00:00 committed by GitHub
commit b8ec0b73c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 211 additions and 95 deletions

63
lib/hal/HalStorage.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "HalStorage.h"
#include <SDCardManager.h>
HalStorage HalStorage::instance;
HalStorage::HalStorage() {}
bool HalStorage::begin() { return SdMan.begin(); }
bool HalStorage::ready() const { return SdMan.ready(); }
std::vector<String> HalStorage::listFiles(const char* path, int maxFiles) { return SdMan.listFiles(path, maxFiles); }
String HalStorage::readFile(const char* path) { return SdMan.readFile(path); }
bool HalStorage::readFileToStream(const char* path, Print& out, size_t chunkSize) {
return SdMan.readFileToStream(path, out, chunkSize);
}
size_t HalStorage::readFileToBuffer(const char* path, char* buffer, size_t bufferSize, size_t maxBytes) {
return SdMan.readFileToBuffer(path, buffer, bufferSize, maxBytes);
}
bool HalStorage::writeFile(const char* path, const String& content) { return SdMan.writeFile(path, content); }
bool HalStorage::ensureDirectoryExists(const char* path) { return SdMan.ensureDirectoryExists(path); }
File HalStorage::open(const char* path, const oflag_t oflag) { return SdMan.open(path, oflag); }
bool HalStorage::mkdir(const char* path, const bool pFlag) { return SdMan.mkdir(path, pFlag); }
bool HalStorage::exists(const char* path) { return SdMan.exists(path); }
bool HalStorage::remove(const char* path) { return SdMan.remove(path); }
bool HalStorage::rmdir(const char* path) { return SdMan.rmdir(path); }
bool HalStorage::openFileForRead(const char* moduleName, const char* path, File& file) {
return SdMan.openFileForRead(moduleName, path, file);
}
bool HalStorage::openFileForRead(const char* moduleName, const std::string& path, File& file) {
return openFileForRead(moduleName, path.c_str(), file);
}
bool HalStorage::openFileForRead(const char* moduleName, const String& path, File& file) {
return openFileForRead(moduleName, path.c_str(), file);
}
bool HalStorage::openFileForWrite(const char* moduleName, const char* path, File& file) {
return SdMan.openFileForWrite(moduleName, path, file);
}
bool HalStorage::openFileForWrite(const char* moduleName, const std::string& path, File& file) {
return openFileForWrite(moduleName, path.c_str(), file);
}
bool HalStorage::openFileForWrite(const char* moduleName, const String& path, File& file) {
return openFileForWrite(moduleName, path.c_str(), file);
}
bool HalStorage::removeDir(const char* path) { return SdMan.removeDir(path); }

51
lib/hal/HalStorage.h Normal file
View File

@ -0,0 +1,51 @@
#pragma once
#include <SDCardManager.h>
#include <vector>
using File = FsFile;
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);
File 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 rmdir(const char* path);
bool openFileForRead(const char* moduleName, const char* path, File& file);
bool openFileForRead(const char* moduleName, const std::string& path, File& file);
bool openFileForRead(const char* moduleName, const String& path, File& file);
bool openFileForWrite(const char* moduleName, const char* path, File& file);
bool openFileForWrite(const char* moduleName, const std::string& path, File& file);
bool openFileForWrite(const char* moduleName, const String& path, File& file);
bool removeDir(const char* path);
static HalStorage& getInstance() { return instance; }
private:
static HalStorage instance;
bool initialized = false;
};
#define Storage HalStorage::getInstance()

View File

@ -1,7 +1,7 @@
#include "CrossPointSettings.h"
#include <HalStorage.h>
#include <HardwareSerial.h>
#include <SDCardManager.h>
#include <Serialization.h>
#include <cstring>
@ -11,7 +11,7 @@
// Initialize the static instance
CrossPointSettings CrossPointSettings::instance;
void readAndValidate(FsFile& file, uint8_t& member, const uint8_t maxValue) {
void readAndValidate(File& file, uint8_t& member, const uint8_t maxValue) {
uint8_t tempValue;
serialization::readPod(file, tempValue);
if (tempValue < maxValue) {
@ -28,10 +28,10 @@ constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin";
bool CrossPointSettings::saveToFile() const {
// Make sure the directory exists
SdMan.mkdir("/.crosspoint");
Storage.mkdir("/.crosspoint");
FsFile outputFile;
if (!SdMan.openFileForWrite("CPS", SETTINGS_FILE, outputFile)) {
File outputFile;
if (!Storage.openFileForWrite("CPS", SETTINGS_FILE, outputFile)) {
return false;
}
@ -68,8 +68,8 @@ bool CrossPointSettings::saveToFile() const {
}
bool CrossPointSettings::loadFromFile() {
FsFile inputFile;
if (!SdMan.openFileForRead("CPS", SETTINGS_FILE, inputFile)) {
File inputFile;
if (!Storage.openFileForRead("CPS", SETTINGS_FILE, inputFile)) {
return false;
}

View File

@ -1,7 +1,7 @@
#include "CrossPointState.h"
#include <HalStorage.h>
#include <HardwareSerial.h>
#include <SDCardManager.h>
#include <Serialization.h>
namespace {
@ -12,8 +12,8 @@ constexpr char STATE_FILE[] = "/.crosspoint/state.bin";
CrossPointState CrossPointState::instance;
bool CrossPointState::saveToFile() const {
FsFile outputFile;
if (!SdMan.openFileForWrite("CPS", STATE_FILE, outputFile)) {
File outputFile;
if (!Storage.openFileForWrite("CPS", STATE_FILE, outputFile)) {
return false;
}
@ -25,8 +25,8 @@ bool CrossPointState::saveToFile() const {
}
bool CrossPointState::loadFromFile() {
FsFile inputFile;
if (!SdMan.openFileForRead("CPS", STATE_FILE, inputFile)) {
File inputFile;
if (!Storage.openFileForRead("CPS", STATE_FILE, inputFile)) {
return false;
}

View File

@ -1,7 +1,7 @@
#include "RecentBooksStore.h"
#include <HalStorage.h>
#include <HardwareSerial.h>
#include <SDCardManager.h>
#include <Serialization.h>
#include <algorithm>
@ -35,10 +35,10 @@ void RecentBooksStore::addBook(const std::string& path, const std::string& title
bool RecentBooksStore::saveToFile() const {
// Make sure the directory exists
SdMan.mkdir("/.crosspoint");
Storage.mkdir("/.crosspoint");
FsFile outputFile;
if (!SdMan.openFileForWrite("RBS", RECENT_BOOKS_FILE, outputFile)) {
File outputFile;
if (!Storage.openFileForWrite("RBS", RECENT_BOOKS_FILE, outputFile)) {
return false;
}
@ -58,8 +58,8 @@ bool RecentBooksStore::saveToFile() const {
}
bool RecentBooksStore::loadFromFile() {
FsFile inputFile;
if (!SdMan.openFileForRead("RBS", RECENT_BOOKS_FILE, inputFile)) {
File inputFile;
if (!Storage.openFileForRead("RBS", RECENT_BOOKS_FILE, inputFile)) {
return false;
}

View File

@ -1,7 +1,7 @@
#include "WifiCredentialStore.h"
#include <HalStorage.h>
#include <HardwareSerial.h>
#include <SDCardManager.h>
#include <Serialization.h>
// Initialize the static instance
@ -29,10 +29,10 @@ void WifiCredentialStore::obfuscate(std::string& data) const {
bool WifiCredentialStore::saveToFile() const {
// Make sure the directory exists
SdMan.mkdir("/.crosspoint");
Storage.mkdir("/.crosspoint");
FsFile file;
if (!SdMan.openFileForWrite("WCS", WIFI_FILE, file)) {
File file;
if (!Storage.openFileForWrite("WCS", WIFI_FILE, file)) {
return false;
}
@ -59,8 +59,8 @@ bool WifiCredentialStore::saveToFile() const {
}
bool WifiCredentialStore::loadFromFile() {
FsFile file;
if (!SdMan.openFileForRead("WCS", WIFI_FILE, file)) {
File file;
if (!Storage.openFileForRead("WCS", WIFI_FILE, file)) {
return false;
}

View File

@ -2,7 +2,7 @@
#include <Epub.h>
#include <GfxRenderer.h>
#include <SDCardManager.h>
#include <HalStorage.h>
#include <Txt.h>
#include <Xtc.h>
@ -35,7 +35,7 @@ void SleepActivity::onEnter() {
void SleepActivity::renderCustomSleepScreen() const {
// Check if we have a /sleep directory
auto dir = SdMan.open("/sleep");
auto dir = Storage.open("/sleep");
if (dir && dir.isDirectory()) {
std::vector<std::string> files;
char name[500];
@ -77,8 +77,8 @@ void SleepActivity::renderCustomSleepScreen() const {
APP_STATE.lastSleepImage = randomFileIndex;
APP_STATE.saveToFile();
const auto filename = "/sleep/" + files[randomFileIndex];
FsFile file;
if (SdMan.openFileForRead("SLP", filename, file)) {
File file;
if (Storage.openFileForRead("SLP", filename, file)) {
Serial.printf("[%lu] [SLP] Randomly loading: /sleep/%s\n", millis(), files[randomFileIndex].c_str());
delay(100);
Bitmap bitmap(file, true);
@ -94,8 +94,8 @@ void SleepActivity::renderCustomSleepScreen() const {
// Look for sleep.bmp on the root of the sd card to determine if we should
// render a custom sleep screen instead of the default.
FsFile file;
if (SdMan.openFileForRead("SLP", "/sleep.bmp", file)) {
File file;
if (Storage.openFileForRead("SLP", "/sleep.bmp", file)) {
Bitmap bitmap(file, true);
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
Serial.printf("[%lu] [SLP] Loading: /sleep.bmp\n", millis());
@ -253,8 +253,8 @@ void SleepActivity::renderCoverSleepScreen() const {
return renderDefaultSleepScreen();
}
FsFile file;
if (SdMan.openFileForRead("SLP", coverBmpPath, file)) {
File file;
if (Storage.openFileForRead("SLP", coverBmpPath, file)) {
Bitmap bitmap(file);
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
Serial.printf("[SLP] Rendering sleep cover: %s\n", coverBmpPath);

View File

@ -3,7 +3,7 @@
#include <Bitmap.h>
#include <Epub.h>
#include <GfxRenderer.h>
#include <SDCardManager.h>
#include <HalStorage.h>
#include <Utf8.h>
#include <Xtc.h>
@ -36,7 +36,7 @@ void HomeActivity::onEnter() {
renderingMutex = xSemaphoreCreateMutex();
// Check if we have a book to continue reading
hasContinueReading = !APP_STATE.openEpubPath.empty() && SdMan.exists(APP_STATE.openEpubPath.c_str());
hasContinueReading = !APP_STATE.openEpubPath.empty() && Storage.exists(APP_STATE.openEpubPath.c_str());
// Check if OPDS browser URL is configured
hasOpdsUrl = strlen(SETTINGS.opdsServerUrl) > 0;
@ -242,8 +242,8 @@ void HomeActivity::render() {
// Only load from SD on first render, then use stored buffer
if (hasContinueReading && hasCoverImage && !coverBmpPath.empty() && !coverRendered) {
// First time: load cover from SD and render
FsFile file;
if (SdMan.openFileForRead("HOME", coverBmpPath, file)) {
File file;
if (Storage.openFileForRead("HOME", coverBmpPath, file)) {
Bitmap bitmap(file);
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
// Calculate position to center image within the book card

View File

@ -1,7 +1,7 @@
#include "MyLibraryActivity.h"
#include <GfxRenderer.h>
#include <SDCardManager.h>
#include <HalStorage.h>
#include <algorithm>
@ -72,7 +72,7 @@ void MyLibraryActivity::loadRecentBooks() {
for (const auto& book : books) {
// Skip if file no longer exists
if (!SdMan.exists(book.path.c_str())) {
if (!Storage.exists(book.path.c_str())) {
continue;
}
recentBooks.push_back(book);
@ -82,7 +82,7 @@ void MyLibraryActivity::loadRecentBooks() {
void MyLibraryActivity::loadFiles() {
files.clear();
auto root = SdMan.open(basepath.c_str());
auto root = Storage.open(basepath.c_str());
if (!root || !root.isDirectory()) {
if (root) root.close();
return;

View File

@ -3,7 +3,7 @@
#include <Epub/Page.h>
#include <FsHelpers.h>
#include <GfxRenderer.h>
#include <SDCardManager.h>
#include <HalStorage.h>
#include "CrossPointSettings.h"
#include "CrossPointState.h"
@ -56,8 +56,8 @@ void EpubReaderActivity::onEnter() {
epub->setupCacheDir();
FsFile f;
if (SdMan.openFileForRead("ERS", epub->getCachePath() + "/progress.bin", f)) {
File f;
if (Storage.openFileForRead("ERS", epub->getCachePath() + "/progress.bin", f)) {
uint8_t data[6];
int dataSize = f.read(data, 6);
if (dataSize == 4 || dataSize == 6) {
@ -435,7 +435,7 @@ void EpubReaderActivity::renderScreen() {
void EpubReaderActivity::saveProgress(int spineIndex, int currentPage, int pageCount) {
FsFile f;
if (SdMan.openFileForWrite("ERS", epub->getCachePath() + "/progress.bin", f)) {
if (Storage.openFileForWrite("ERS", epub->getCachePath() + "/progress.bin", f)) {
uint8_t data[6];
data[0] = currentSpineIndex & 0xFF;
data[1] = (currentSpineIndex >> 8) & 0xFF;

View File

@ -1,5 +1,7 @@
#include "ReaderActivity.h"
#include <HalStorage.h>
#include "Epub.h"
#include "EpubReaderActivity.h"
#include "Txt.h"
@ -27,7 +29,7 @@ bool ReaderActivity::isTxtFile(const std::string& path) {
}
std::unique_ptr<Epub> ReaderActivity::loadEpub(const std::string& path) {
if (!SdMan.exists(path.c_str())) {
if (!Storage.exists(path.c_str())) {
Serial.printf("[%lu] [ ] File does not exist: %s\n", millis(), path.c_str());
return nullptr;
}
@ -42,7 +44,7 @@ std::unique_ptr<Epub> ReaderActivity::loadEpub(const std::string& path) {
}
std::unique_ptr<Xtc> ReaderActivity::loadXtc(const std::string& path) {
if (!SdMan.exists(path.c_str())) {
if (!Storage.exists(path.c_str())) {
Serial.printf("[%lu] [ ] File does not exist: %s\n", millis(), path.c_str());
return nullptr;
}
@ -57,7 +59,7 @@ std::unique_ptr<Xtc> ReaderActivity::loadXtc(const std::string& path) {
}
std::unique_ptr<Txt> ReaderActivity::loadTxt(const std::string& path) {
if (!SdMan.exists(path.c_str())) {
if (!Storage.exists(path.c_str())) {
Serial.printf("[%lu] [ ] File does not exist: %s\n", millis(), path.c_str());
return nullptr;
}

View File

@ -1,7 +1,7 @@
#include "TxtReaderActivity.h"
#include <GfxRenderer.h>
#include <SDCardManager.h>
#include <HalStorage.h>
#include <Serialization.h>
#include <Utf8.h>
@ -543,8 +543,8 @@ void TxtReaderActivity::renderStatusBar(const int orientedMarginRight, const int
}
void TxtReaderActivity::saveProgress() const {
FsFile f;
if (SdMan.openFileForWrite("TRS", txt->getCachePath() + "/progress.bin", f)) {
File f;
if (Storage.openFileForWrite("TRS", txt->getCachePath() + "/progress.bin", f)) {
uint8_t data[4];
data[0] = currentPage & 0xFF;
data[1] = (currentPage >> 8) & 0xFF;
@ -556,8 +556,8 @@ void TxtReaderActivity::saveProgress() const {
}
void TxtReaderActivity::loadProgress() {
FsFile f;
if (SdMan.openFileForRead("TRS", txt->getCachePath() + "/progress.bin", f)) {
File f;
if (Storage.openFileForRead("TRS", txt->getCachePath() + "/progress.bin", f)) {
uint8_t data[4];
if (f.read(data, 4) == 4) {
currentPage = data[0] + (data[1] << 8);
@ -587,8 +587,8 @@ bool TxtReaderActivity::loadPageIndexCache() {
// - N * uint32_t: page offsets
std::string cachePath = txt->getCachePath() + "/index.bin";
FsFile f;
if (!SdMan.openFileForRead("TRS", cachePath, f)) {
File f;
if (!Storage.openFileForRead("TRS", cachePath, f)) {
Serial.printf("[%lu] [TRS] No page index cache found\n", millis());
return false;
}
@ -679,8 +679,8 @@ bool TxtReaderActivity::loadPageIndexCache() {
void TxtReaderActivity::savePageIndexCache() const {
std::string cachePath = txt->getCachePath() + "/index.bin";
FsFile f;
if (!SdMan.openFileForWrite("TRS", cachePath, f)) {
File f;
if (!Storage.openFileForWrite("TRS", cachePath, f)) {
Serial.printf("[%lu] [TRS] Failed to save page index cache\n", millis());
return;
}

View File

@ -9,7 +9,7 @@
#include <FsHelpers.h>
#include <GfxRenderer.h>
#include <SDCardManager.h>
#include <HalStorage.h>
#include "CrossPointSettings.h"
#include "CrossPointState.h"
@ -368,8 +368,8 @@ void XtcReaderActivity::renderPage() {
}
void XtcReaderActivity::saveProgress() const {
FsFile f;
if (SdMan.openFileForWrite("XTR", xtc->getCachePath() + "/progress.bin", f)) {
File f;
if (Storage.openFileForWrite("XTR", xtc->getCachePath() + "/progress.bin", f)) {
uint8_t data[4];
data[0] = currentPage & 0xFF;
data[1] = (currentPage >> 8) & 0xFF;
@ -381,8 +381,8 @@ void XtcReaderActivity::saveProgress() const {
}
void XtcReaderActivity::loadProgress() {
FsFile f;
if (SdMan.openFileForRead("XTR", xtc->getCachePath() + "/progress.bin", f)) {
File f;
if (Storage.openFileForRead("XTR", xtc->getCachePath() + "/progress.bin", f)) {
uint8_t data[4];
if (f.read(data, 4) == 4) {
currentPage = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);

View File

@ -1,8 +1,8 @@
#include "ClearCacheActivity.h"
#include <GfxRenderer.h>
#include <HalStorage.h>
#include <HardwareSerial.h>
#include <SDCardManager.h>
#include "MappedInputManager.h"
#include "fontIds.h"
@ -106,7 +106,7 @@ void ClearCacheActivity::clearCache() {
Serial.printf("[%lu] [CLEAR_CACHE] Clearing cache...\n", millis());
// Open .crosspoint directory
auto root = SdMan.open("/.crosspoint");
auto root = Storage.open("/.crosspoint");
if (!root || !root.isDirectory()) {
Serial.printf("[%lu] [CLEAR_CACHE] Failed to open cache directory\n", millis());
if (root) root.close();
@ -131,7 +131,7 @@ void ClearCacheActivity::clearCache() {
file.close(); // Close before attempting to delete
if (SdMan.removeDir(fullPath.c_str())) {
if (Storage.removeDir(fullPath.c_str())) {
clearedCount++;
} else {
Serial.printf("[%lu] [CLEAR_CACHE] Failed to remove: %s\n", millis(), fullPath.c_str());

View File

@ -3,7 +3,7 @@
#include <GfxRenderer.h>
#include <HalDisplay.h>
#include <HalGPIO.h>
#include <SDCardManager.h>
#include <HalStorage.h>
#include <SPI.h>
#include <builtinFonts/all.h>
@ -283,7 +283,7 @@ void setup() {
// SD Card Initialization
// We need 6 open files concurrently when parsing a new chapter
if (!SdMan.begin()) {
if (!Storage.begin()) {
Serial.printf("[%lu] [ ] SD card initialization failed\n", millis());
setupDisplayAndFonts();
exitActivity();

View File

@ -3,7 +3,7 @@
#include <ArduinoJson.h>
#include <Epub.h>
#include <FsHelpers.h>
#include <SDCardManager.h>
#include <HalStorage.h>
#include <WiFi.h>
#include <esp_task_wdt.h>
@ -25,7 +25,7 @@ constexpr uint16_t LOCAL_UDP_PORT = 8134;
CrossPointWebServer* wsInstance = nullptr;
// WebSocket upload state
FsFile wsUploadFile;
File wsUploadFile;
String wsUploadFileName;
String wsUploadPath;
size_t wsUploadSize = 0;
@ -280,7 +280,7 @@ void CrossPointWebServer::handleStatus() const {
}
void CrossPointWebServer::scanFiles(const char* path, const std::function<void(FileInfo)>& callback) const {
FsFile root = SdMan.open(path);
File root = Storage.open(path);
if (!root) {
Serial.printf("[%lu] [WEB] Failed to open directory: %s\n", millis(), path);
return;
@ -294,7 +294,7 @@ void CrossPointWebServer::scanFiles(const char* path, const std::function<void(F
Serial.printf("[%lu] [WEB] Scanning files in: %s\n", millis(), path);
FsFile file = root.openNextFile();
File file = root.openNextFile();
char name[500];
while (file) {
file.getName(name, sizeof(name));
@ -422,12 +422,12 @@ void CrossPointWebServer::handleDownload() const {
}
}
if (!SdMan.exists(itemPath.c_str())) {
if (!Storage.exists(itemPath.c_str())) {
server->send(404, "text/plain", "Item not found");
return;
}
FsFile file = SdMan.open(itemPath.c_str());
File file = Storage.open(itemPath.c_str());
if (!file) {
server->send(500, "text/plain", "Failed to open file");
return;
@ -459,7 +459,7 @@ void CrossPointWebServer::handleDownload() const {
}
// Static variables for upload handling
static FsFile uploadFile;
static File uploadFile;
static String uploadFileName;
static String uploadPath = "/";
static size_t uploadSize = 0;
@ -553,15 +553,15 @@ void CrossPointWebServer::handleUpload() const {
// Check if file already exists - SD operations can be slow
esp_task_wdt_reset();
if (SdMan.exists(filePath.c_str())) {
if (Storage.exists(filePath.c_str())) {
Serial.printf("[%lu] [WEB] [UPLOAD] Overwriting existing file: %s\n", millis(), filePath.c_str());
esp_task_wdt_reset();
SdMan.remove(filePath.c_str());
Storage.remove(filePath.c_str());
}
// Open file for writing - this can be slow due to FAT cluster allocation
esp_task_wdt_reset();
if (!SdMan.openFileForWrite("WEB", filePath, uploadFile)) {
if (!Storage.openFileForWrite("WEB", filePath, uploadFile)) {
uploadError = "Failed to create file on SD card";
Serial.printf("[%lu] [WEB] [UPLOAD] FAILED to create file: %s\n", millis(), filePath.c_str());
return;
@ -639,7 +639,7 @@ void CrossPointWebServer::handleUpload() const {
String filePath = uploadPath;
if (!filePath.endsWith("/")) filePath += "/";
filePath += uploadFileName;
SdMan.remove(filePath.c_str());
Storage.remove(filePath.c_str());
}
uploadError = "Upload aborted";
Serial.printf("[%lu] [WEB] Upload aborted\n", millis());
@ -690,13 +690,13 @@ void CrossPointWebServer::handleCreateFolder() const {
Serial.printf("[%lu] [WEB] Creating folder: %s\n", millis(), folderPath.c_str());
// Check if already exists
if (SdMan.exists(folderPath.c_str())) {
if (Storage.exists(folderPath.c_str())) {
server->send(400, "text/plain", "Folder already exists");
return;
}
// Create the folder
if (SdMan.mkdir(folderPath.c_str())) {
if (Storage.mkdir(folderPath.c_str())) {
Serial.printf("[%lu] [WEB] Folder created successfully: %s\n", millis(), folderPath.c_str());
server->send(200, "text/plain", "Folder created: " + folderName);
} else {
@ -746,7 +746,7 @@ void CrossPointWebServer::handleDelete() const {
}
// Check if item exists
if (!SdMan.exists(itemPath.c_str())) {
if (!Storage.exists(itemPath.c_str())) {
Serial.printf("[%lu] [WEB] Delete failed - item not found: %s\n", millis(), itemPath.c_str());
server->send(404, "text/plain", "Item not found");
return;
@ -758,10 +758,10 @@ void CrossPointWebServer::handleDelete() const {
if (itemType == "folder") {
// For folders, try to remove (will fail if not empty)
FsFile dir = SdMan.open(itemPath.c_str());
File dir = Storage.open(itemPath.c_str());
if (dir && dir.isDirectory()) {
// Check if folder is empty
FsFile entry = dir.openNextFile();
File entry = dir.openNextFile();
if (entry) {
// Folder is not empty
entry.close();
@ -772,10 +772,10 @@ void CrossPointWebServer::handleDelete() const {
}
dir.close();
}
success = SdMan.rmdir(itemPath.c_str());
success = Storage.rmdir(itemPath.c_str());
} else {
// For files, use remove
success = SdMan.remove(itemPath.c_str());
success = Storage.remove(itemPath.c_str());
}
if (success) {
@ -811,7 +811,7 @@ void CrossPointWebServer::onWebSocketEvent(uint8_t num, WStype_t type, uint8_t*
String filePath = wsUploadPath;
if (!filePath.endsWith("/")) filePath += "/";
filePath += wsUploadFileName;
SdMan.remove(filePath.c_str());
Storage.remove(filePath.c_str());
Serial.printf("[%lu] [WS] Deleted incomplete upload: %s\n", millis(), filePath.c_str());
}
wsUploadInProgress = false;
@ -855,13 +855,13 @@ void CrossPointWebServer::onWebSocketEvent(uint8_t num, WStype_t type, uint8_t*
// Check if file exists and remove it
esp_task_wdt_reset();
if (SdMan.exists(filePath.c_str())) {
SdMan.remove(filePath.c_str());
if (Storage.exists(filePath.c_str())) {
Storage.remove(filePath.c_str());
}
// Open file for writing
esp_task_wdt_reset();
if (!SdMan.openFileForWrite("WS", filePath, wsUploadFile)) {
if (!Storage.openFileForWrite("WS", filePath, wsUploadFile)) {
wsServer->sendTXT(num, "ERROR:Failed to create file");
wsUploadInProgress = false;
return;

View File

@ -100,13 +100,13 @@ HttpDownloader::DownloadError HttpDownloader::downloadToFile(const std::string&
Serial.printf("[%lu] [HTTP] Content-Length: %zu\n", millis(), contentLength);
// Remove existing file if present
if (SdMan.exists(destPath.c_str())) {
SdMan.remove(destPath.c_str());
if (Storage.exists(destPath.c_str())) {
Storage.remove(destPath.c_str());
}
// Open file for writing
FsFile file;
if (!SdMan.openFileForWrite("HTTP", destPath.c_str(), file)) {
File file;
if (!Storage.openFileForWrite("HTTP", destPath.c_str(), file)) {
Serial.printf("[%lu] [HTTP] Failed to open file for writing\n", millis());
http.end();
return FILE_ERROR;
@ -117,7 +117,7 @@ HttpDownloader::DownloadError HttpDownloader::downloadToFile(const std::string&
if (!stream) {
Serial.printf("[%lu] [HTTP] Failed to get stream\n", millis());
file.close();
SdMan.remove(destPath.c_str());
Storage.remove(destPath.c_str());
http.end();
return HTTP_ERROR;
}
@ -145,7 +145,7 @@ HttpDownloader::DownloadError HttpDownloader::downloadToFile(const std::string&
if (written != bytesRead) {
Serial.printf("[%lu] [HTTP] Write failed: wrote %zu of %zu bytes\n", millis(), written, bytesRead);
file.close();
SdMan.remove(destPath.c_str());
Storage.remove(destPath.c_str());
http.end();
return FILE_ERROR;
}
@ -165,7 +165,7 @@ HttpDownloader::DownloadError HttpDownloader::downloadToFile(const std::string&
// Verify download size if known
if (contentLength > 0 && downloaded != contentLength) {
Serial.printf("[%lu] [HTTP] Size mismatch: got %zu, expected %zu\n", millis(), downloaded, contentLength);
SdMan.remove(destPath.c_str());
Storage.remove(destPath.c_str());
return HTTP_ERROR;
}

View File

@ -1,5 +1,5 @@
#pragma once
#include <SDCardManager.h>
#include <HalStorage.h>
#include <functional>
#include <string>