From 7f40c3f477a383c122b8496c55f250b257777821 Mon Sep 17 00:00:00 2001 From: Xuan-Son Nguyen Date: Sun, 8 Feb 2026 21:29:14 +0100 Subject: [PATCH] feat: add HalStorage (#656) ## Summary Continue my changes to introduce the HAL infrastructure from https://github.com/crosspoint-reader/crosspoint-reader/pull/522 This PR touches quite a lot of files, but most of them are just name changing. It should not have any impacts to the end behavior. ## Additional Context My plan is to firstly add this small shim layer, which sounds useless at first, but then I'll implement an emulated driver which can be helpful for testing and for development. Currently, on my fork, I'm using a FS driver that allow "mounting" a local directory from my computer to the device, much like the `-v` mount option on docker. This allows me to quickly reset `.crosspoint` directory if anything goes wrong. I plan to upstream this feature when this PR get merged. --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? NO --- lib/Epub/Epub.cpp | 62 +++++++++--------- lib/Epub/Epub/BookMetadataCache.cpp | 22 +++---- lib/Epub/Epub/BookMetadataCache.h | 2 +- lib/Epub/Epub/Page.h | 2 +- lib/Epub/Epub/Section.cpp | 30 ++++----- lib/Epub/Epub/blocks/TextBlock.h | 2 +- lib/Epub/Epub/css/CssParser.h | 2 +- .../Epub/parsers/ChapterHtmlSlimParser.cpp | 4 +- lib/Epub/Epub/parsers/ContentOpfParser.cpp | 10 +-- lib/GfxRenderer/Bitmap.h | 2 +- lib/JpegToBmpConverter/JpegToBmpConverter.cpp | 2 +- lib/KOReaderSync/KOReaderCredentialStore.cpp | 8 +-- lib/KOReaderSync/KOReaderDocumentId.cpp | 4 +- lib/Serialization/Serialization.h | 2 +- lib/Txt/Txt.cpp | 30 ++++----- lib/Txt/Txt.h | 2 +- lib/Xtc/Xtc.cpp | 26 ++++---- lib/Xtc/Xtc/XtcParser.cpp | 6 +- lib/Xtc/Xtc/XtcParser.h | 2 +- lib/ZipFile/ZipFile.cpp | 4 +- lib/ZipFile/ZipFile.h | 2 +- lib/hal/HalStorage.cpp | 65 +++++++++++++++++++ lib/hal/HalStorage.h | 54 +++++++++++++++ src/CrossPointSettings.cpp | 8 +-- src/CrossPointState.cpp | 6 +- src/RecentBooksStore.cpp | 8 +-- src/WifiCredentialStore.cpp | 8 +-- src/activities/boot_sleep/SleepActivity.cpp | 10 +-- src/activities/home/HomeActivity.cpp | 6 +- src/activities/home/MyLibraryActivity.cpp | 4 +- src/activities/home/RecentBooksActivity.cpp | 4 +- src/activities/reader/EpubReaderActivity.cpp | 6 +- src/activities/reader/ReaderActivity.cpp | 8 ++- src/activities/reader/TxtReaderActivity.cpp | 10 +-- src/activities/reader/XtcReaderActivity.cpp | 6 +- .../settings/ClearCacheActivity.cpp | 6 +- src/components/themes/BaseTheme.cpp | 4 +- src/components/themes/lyra/LyraTheme.cpp | 4 +- src/main.cpp | 4 +- src/network/CrossPointWebServer.cpp | 52 +++++++-------- src/network/CrossPointWebServer.h | 2 +- src/network/HttpDownloader.cpp | 12 ++-- src/network/HttpDownloader.h | 2 +- 43 files changed, 318 insertions(+), 197 deletions(-) create mode 100644 lib/hal/HalStorage.cpp create mode 100644 lib/hal/HalStorage.h diff --git a/lib/Epub/Epub.cpp b/lib/Epub/Epub.cpp index 64890ac0..e003f45c 100644 --- a/lib/Epub/Epub.cpp +++ b/lib/Epub/Epub.cpp @@ -1,9 +1,9 @@ #include "Epub.h" #include +#include #include #include -#include #include #include "Epub/parsers/ContainerParser.h" @@ -105,12 +105,12 @@ bool Epub::parseTocNcxFile() const { const auto tmpNcxPath = getCachePath() + "/toc.ncx"; FsFile tempNcxFile; - if (!SdMan.openFileForWrite("EBP", tmpNcxPath, tempNcxFile)) { + if (!Storage.openFileForWrite("EBP", tmpNcxPath, tempNcxFile)) { return false; } readItemContentsToStream(tocNcxItem, tempNcxFile, 1024); tempNcxFile.close(); - if (!SdMan.openFileForRead("EBP", tmpNcxPath, tempNcxFile)) { + if (!Storage.openFileForRead("EBP", tmpNcxPath, tempNcxFile)) { return false; } const auto ncxSize = tempNcxFile.size(); @@ -145,7 +145,7 @@ bool Epub::parseTocNcxFile() const { free(ncxBuffer); tempNcxFile.close(); - SdMan.remove(tmpNcxPath.c_str()); + Storage.remove(tmpNcxPath.c_str()); Serial.printf("[%lu] [EBP] Parsed TOC items\n", millis()); return true; @@ -162,12 +162,12 @@ bool Epub::parseTocNavFile() const { const auto tmpNavPath = getCachePath() + "/toc.nav"; FsFile tempNavFile; - if (!SdMan.openFileForWrite("EBP", tmpNavPath, tempNavFile)) { + if (!Storage.openFileForWrite("EBP", tmpNavPath, tempNavFile)) { return false; } readItemContentsToStream(tocNavItem, tempNavFile, 1024); tempNavFile.close(); - if (!SdMan.openFileForRead("EBP", tmpNavPath, tempNavFile)) { + if (!Storage.openFileForRead("EBP", tmpNavPath, tempNavFile)) { return false; } const auto navSize = tempNavFile.size(); @@ -202,7 +202,7 @@ bool Epub::parseTocNavFile() const { free(navBuffer); tempNavFile.close(); - SdMan.remove(tmpNavPath.c_str()); + Storage.remove(tmpNavPath.c_str()); Serial.printf("[%lu] [EBP] Parsed TOC nav items\n", millis()); return true; @@ -212,7 +212,7 @@ std::string Epub::getCssRulesCache() const { return cachePath + "/css_rules.cach bool Epub::loadCssRulesFromCache() const { FsFile cssCacheFile; - if (SdMan.openFileForRead("EBP", getCssRulesCache(), cssCacheFile)) { + if (Storage.openFileForRead("EBP", getCssRulesCache(), cssCacheFile)) { if (cssParser->loadFromCache(cssCacheFile)) { cssCacheFile.close(); Serial.printf("[%lu] [EBP] Loaded CSS rules from cache\n", millis()); @@ -238,32 +238,32 @@ void Epub::parseCssFiles() const { // Extract CSS file to temp location const auto tmpCssPath = getCachePath() + "/.tmp.css"; FsFile tempCssFile; - if (!SdMan.openFileForWrite("EBP", tmpCssPath, tempCssFile)) { + if (!Storage.openFileForWrite("EBP", tmpCssPath, tempCssFile)) { Serial.printf("[%lu] [EBP] Could not create temp CSS file\n", millis()); continue; } if (!readItemContentsToStream(cssPath, tempCssFile, 1024)) { Serial.printf("[%lu] [EBP] Could not read CSS file: %s\n", millis(), cssPath.c_str()); tempCssFile.close(); - SdMan.remove(tmpCssPath.c_str()); + Storage.remove(tmpCssPath.c_str()); continue; } tempCssFile.close(); // Parse the CSS file - if (!SdMan.openFileForRead("EBP", tmpCssPath, tempCssFile)) { + if (!Storage.openFileForRead("EBP", tmpCssPath, tempCssFile)) { Serial.printf("[%lu] [EBP] Could not open temp CSS file for reading\n", millis()); - SdMan.remove(tmpCssPath.c_str()); + Storage.remove(tmpCssPath.c_str()); continue; } cssParser->loadFromStream(tempCssFile); tempCssFile.close(); - SdMan.remove(tmpCssPath.c_str()); + Storage.remove(tmpCssPath.c_str()); } // Save to cache for next time FsFile cssCacheFile; - if (SdMan.openFileForWrite("EBP", getCssRulesCache(), cssCacheFile)) { + if (Storage.openFileForWrite("EBP", getCssRulesCache(), cssCacheFile)) { cssParser->saveToCache(cssCacheFile); cssCacheFile.close(); } @@ -399,12 +399,12 @@ bool Epub::load(const bool buildIfMissing, const bool skipLoadingCss) { } bool Epub::clearCache() const { - if (!SdMan.exists(cachePath.c_str())) { + if (!Storage.exists(cachePath.c_str())) { Serial.printf("[%lu] [EPB] Cache does not exist, no action needed\n", millis()); return true; } - if (!SdMan.removeDir(cachePath.c_str())) { + if (!Storage.removeDir(cachePath.c_str())) { Serial.printf("[%lu] [EPB] Failed to clear cache\n", millis()); return false; } @@ -414,11 +414,11 @@ bool Epub::clearCache() const { } void Epub::setupCacheDir() const { - if (SdMan.exists(cachePath.c_str())) { + if (Storage.exists(cachePath.c_str())) { return; } - SdMan.mkdir(cachePath.c_str()); + Storage.mkdir(cachePath.c_str()); } const std::string& Epub::getCachePath() const { return cachePath; } @@ -459,7 +459,7 @@ std::string Epub::getCoverBmpPath(bool cropped) const { bool Epub::generateCoverBmp(bool cropped) const { // Already generated, return true - if (SdMan.exists(getCoverBmpPath(cropped).c_str())) { + if (Storage.exists(getCoverBmpPath(cropped).c_str())) { return true; } @@ -480,29 +480,29 @@ bool Epub::generateCoverBmp(bool cropped) const { const auto coverJpgTempPath = getCachePath() + "/.cover.jpg"; FsFile coverJpg; - if (!SdMan.openFileForWrite("EBP", coverJpgTempPath, coverJpg)) { + if (!Storage.openFileForWrite("EBP", coverJpgTempPath, coverJpg)) { return false; } readItemContentsToStream(coverImageHref, coverJpg, 1024); coverJpg.close(); - if (!SdMan.openFileForRead("EBP", coverJpgTempPath, coverJpg)) { + if (!Storage.openFileForRead("EBP", coverJpgTempPath, coverJpg)) { return false; } FsFile coverBmp; - if (!SdMan.openFileForWrite("EBP", getCoverBmpPath(cropped), coverBmp)) { + if (!Storage.openFileForWrite("EBP", getCoverBmpPath(cropped), coverBmp)) { coverJpg.close(); return false; } const bool success = JpegToBmpConverter::jpegFileToBmpStream(coverJpg, coverBmp, cropped); coverJpg.close(); coverBmp.close(); - SdMan.remove(coverJpgTempPath.c_str()); + Storage.remove(coverJpgTempPath.c_str()); if (!success) { Serial.printf("[%lu] [EBP] Failed to generate BMP from JPG cover image\n", millis()); - SdMan.remove(getCoverBmpPath(cropped).c_str()); + Storage.remove(getCoverBmpPath(cropped).c_str()); } Serial.printf("[%lu] [EBP] Generated BMP from JPG cover image, success: %s\n", millis(), success ? "yes" : "no"); return success; @@ -518,7 +518,7 @@ std::string Epub::getThumbBmpPath(int height) const { return cachePath + "/thumb bool Epub::generateThumbBmp(int height) const { // Already generated, return true - if (SdMan.exists(getThumbBmpPath(height).c_str())) { + if (Storage.exists(getThumbBmpPath(height).c_str())) { return true; } @@ -536,18 +536,18 @@ bool Epub::generateThumbBmp(int height) const { const auto coverJpgTempPath = getCachePath() + "/.cover.jpg"; FsFile coverJpg; - if (!SdMan.openFileForWrite("EBP", coverJpgTempPath, coverJpg)) { + if (!Storage.openFileForWrite("EBP", coverJpgTempPath, coverJpg)) { return false; } readItemContentsToStream(coverImageHref, coverJpg, 1024); coverJpg.close(); - if (!SdMan.openFileForRead("EBP", coverJpgTempPath, coverJpg)) { + if (!Storage.openFileForRead("EBP", coverJpgTempPath, coverJpg)) { return false; } FsFile thumbBmp; - if (!SdMan.openFileForWrite("EBP", getThumbBmpPath(height), thumbBmp)) { + if (!Storage.openFileForWrite("EBP", getThumbBmpPath(height), thumbBmp)) { coverJpg.close(); return false; } @@ -559,11 +559,11 @@ bool Epub::generateThumbBmp(int height) const { THUMB_TARGET_HEIGHT); coverJpg.close(); thumbBmp.close(); - SdMan.remove(coverJpgTempPath.c_str()); + Storage.remove(coverJpgTempPath.c_str()); if (!success) { Serial.printf("[%lu] [EBP] Failed to generate thumb BMP from JPG cover image\n", millis()); - SdMan.remove(getThumbBmpPath(height).c_str()); + Storage.remove(getThumbBmpPath(height).c_str()); } Serial.printf("[%lu] [EBP] Generated thumb BMP from JPG cover image, success: %s\n", millis(), success ? "yes" : "no"); @@ -574,7 +574,7 @@ bool Epub::generateThumbBmp(int height) const { // Write an empty bmp file to avoid generation attempts in the future FsFile thumbBmp; - SdMan.openFileForWrite("EBP", getThumbBmpPath(height), thumbBmp); + Storage.openFileForWrite("EBP", getThumbBmpPath(height), thumbBmp); thumbBmp.close(); return false; } diff --git a/lib/Epub/Epub/BookMetadataCache.cpp b/lib/Epub/Epub/BookMetadataCache.cpp index e7242138..c8ba7db5 100644 --- a/lib/Epub/Epub/BookMetadataCache.cpp +++ b/lib/Epub/Epub/BookMetadataCache.cpp @@ -29,7 +29,7 @@ bool BookMetadataCache::beginContentOpfPass() { Serial.printf("[%lu] [BMC] Beginning content opf pass\n", millis()); // Open spine file for writing - return SdMan.openFileForWrite("BMC", cachePath + tmpSpineBinFile, spineFile); + return Storage.openFileForWrite("BMC", cachePath + tmpSpineBinFile, spineFile); } bool BookMetadataCache::endContentOpfPass() { @@ -40,10 +40,10 @@ bool BookMetadataCache::endContentOpfPass() { bool BookMetadataCache::beginTocPass() { Serial.printf("[%lu] [BMC] Beginning toc pass\n", millis()); - if (!SdMan.openFileForRead("BMC", cachePath + tmpSpineBinFile, spineFile)) { + if (!Storage.openFileForRead("BMC", cachePath + tmpSpineBinFile, spineFile)) { return false; } - if (!SdMan.openFileForWrite("BMC", cachePath + tmpTocBinFile, tocFile)) { + if (!Storage.openFileForWrite("BMC", cachePath + tmpTocBinFile, tocFile)) { spineFile.close(); return false; } @@ -98,16 +98,16 @@ bool BookMetadataCache::endWrite() { bool BookMetadataCache::buildBookBin(const std::string& epubPath, const BookMetadata& metadata) { // Open all three files, writing to meta, reading from spine and toc - if (!SdMan.openFileForWrite("BMC", cachePath + bookBinFile, bookFile)) { + if (!Storage.openFileForWrite("BMC", cachePath + bookBinFile, bookFile)) { return false; } - if (!SdMan.openFileForRead("BMC", cachePath + tmpSpineBinFile, spineFile)) { + if (!Storage.openFileForRead("BMC", cachePath + tmpSpineBinFile, spineFile)) { bookFile.close(); return false; } - if (!SdMan.openFileForRead("BMC", cachePath + tmpTocBinFile, tocFile)) { + if (!Storage.openFileForRead("BMC", cachePath + tmpTocBinFile, tocFile)) { bookFile.close(); spineFile.close(); return false; @@ -275,11 +275,11 @@ bool BookMetadataCache::buildBookBin(const std::string& epubPath, const BookMeta } bool BookMetadataCache::cleanupTmpFiles() const { - if (SdMan.exists((cachePath + tmpSpineBinFile).c_str())) { - SdMan.remove((cachePath + tmpSpineBinFile).c_str()); + if (Storage.exists((cachePath + tmpSpineBinFile).c_str())) { + Storage.remove((cachePath + tmpSpineBinFile).c_str()); } - if (SdMan.exists((cachePath + tmpTocBinFile).c_str())) { - SdMan.remove((cachePath + tmpTocBinFile).c_str()); + if (Storage.exists((cachePath + tmpTocBinFile).c_str())) { + Storage.remove((cachePath + tmpTocBinFile).c_str()); } return true; } @@ -364,7 +364,7 @@ void BookMetadataCache::createTocEntry(const std::string& title, const std::stri /* ============= READING / LOADING FUNCTIONS ================ */ bool BookMetadataCache::load() { - if (!SdMan.openFileForRead("BMC", cachePath + bookBinFile, bookFile)) { + if (!Storage.openFileForRead("BMC", cachePath + bookBinFile, bookFile)) { return false; } diff --git a/lib/Epub/Epub/BookMetadataCache.h b/lib/Epub/Epub/BookMetadataCache.h index 20ce6559..9439b37f 100644 --- a/lib/Epub/Epub/BookMetadataCache.h +++ b/lib/Epub/Epub/BookMetadataCache.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/lib/Epub/Epub/Page.h b/lib/Epub/Epub/Page.h index 20061941..590e288d 100644 --- a/lib/Epub/Epub/Page.h +++ b/lib/Epub/Epub/Page.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include #include diff --git a/lib/Epub/Epub/Section.cpp b/lib/Epub/Epub/Section.cpp index 18e0faef..6b9b49fd 100644 --- a/lib/Epub/Epub/Section.cpp +++ b/lib/Epub/Epub/Section.cpp @@ -1,6 +1,6 @@ #include "Section.h" -#include +#include #include #include "Page.h" @@ -60,7 +60,7 @@ void Section::writeSectionFileHeader(const int fontId, const float lineCompressi bool Section::loadSectionFile(const int fontId, const float lineCompression, const bool extraParagraphSpacing, const uint8_t paragraphAlignment, const uint16_t viewportWidth, const uint16_t viewportHeight, const bool hyphenationEnabled, const bool embeddedStyle) { - if (!SdMan.openFileForRead("SCT", filePath, file)) { + if (!Storage.openFileForRead("SCT", filePath, file)) { return false; } @@ -110,12 +110,12 @@ bool Section::loadSectionFile(const int fontId, const float lineCompression, con // Your updated class method (assuming you are using the 'SD' object, which is a wrapper for a specific filesystem) bool Section::clearCache() const { - if (!SdMan.exists(filePath.c_str())) { + if (!Storage.exists(filePath.c_str())) { Serial.printf("[%lu] [SCT] Cache does not exist, no action needed\n", millis()); return true; } - if (!SdMan.remove(filePath.c_str())) { + if (!Storage.remove(filePath.c_str())) { Serial.printf("[%lu] [SCT] Failed to clear cache\n", millis()); return false; } @@ -134,7 +134,7 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c // Create cache directory if it doesn't exist { const auto sectionsDir = epub->getCachePath() + "/sections"; - SdMan.mkdir(sectionsDir.c_str()); + Storage.mkdir(sectionsDir.c_str()); } // Retry logic for SD card timing issues @@ -147,12 +147,12 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c } // Remove any incomplete file from previous attempt before retrying - if (SdMan.exists(tmpHtmlPath.c_str())) { - SdMan.remove(tmpHtmlPath.c_str()); + if (Storage.exists(tmpHtmlPath.c_str())) { + Storage.remove(tmpHtmlPath.c_str()); } FsFile tmpHtml; - if (!SdMan.openFileForWrite("SCT", tmpHtmlPath, tmpHtml)) { + if (!Storage.openFileForWrite("SCT", tmpHtmlPath, tmpHtml)) { continue; } success = epub->readItemContentsToStream(localPath, tmpHtml, 1024); @@ -160,8 +160,8 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c tmpHtml.close(); // If streaming failed, remove the incomplete file immediately - if (!success && SdMan.exists(tmpHtmlPath.c_str())) { - SdMan.remove(tmpHtmlPath.c_str()); + if (!success && Storage.exists(tmpHtmlPath.c_str())) { + Storage.remove(tmpHtmlPath.c_str()); Serial.printf("[%lu] [SCT] Removed incomplete temp file after failed attempt\n", millis()); } } @@ -173,7 +173,7 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c Serial.printf("[%lu] [SCT] Streamed temp HTML to %s (%d bytes)\n", millis(), tmpHtmlPath.c_str(), fileSize); - if (!SdMan.openFileForWrite("SCT", filePath, file)) { + if (!Storage.openFileForWrite("SCT", filePath, file)) { return false; } writeSectionFileHeader(fontId, lineCompression, extraParagraphSpacing, paragraphAlignment, viewportWidth, @@ -188,11 +188,11 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c Hyphenator::setPreferredLanguage(epub->getLanguage()); success = visitor.parseAndBuildPages(); - SdMan.remove(tmpHtmlPath.c_str()); + Storage.remove(tmpHtmlPath.c_str()); if (!success) { Serial.printf("[%lu] [SCT] Failed to parse XML and build pages\n", millis()); file.close(); - SdMan.remove(filePath.c_str()); + Storage.remove(filePath.c_str()); return false; } @@ -210,7 +210,7 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c if (hasFailedLutRecords) { Serial.printf("[%lu] [SCT] Failed to write LUT due to invalid page positions\n", millis()); file.close(); - SdMan.remove(filePath.c_str()); + Storage.remove(filePath.c_str()); return false; } @@ -223,7 +223,7 @@ bool Section::createSectionFile(const int fontId, const float lineCompression, c } std::unique_ptr Section::loadPageFromSectionFile() { - if (!SdMan.openFileForRead("SCT", filePath, file)) { + if (!Storage.openFileForRead("SCT", filePath, file)) { return nullptr; } diff --git a/lib/Epub/Epub/blocks/TextBlock.h b/lib/Epub/Epub/blocks/TextBlock.h index e233f77f..059d136a 100644 --- a/lib/Epub/Epub/blocks/TextBlock.h +++ b/lib/Epub/Epub/blocks/TextBlock.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include diff --git a/lib/Epub/Epub/css/CssParser.h b/lib/Epub/Epub/css/CssParser.h index 0e5a1b34..5605553d 100644 --- a/lib/Epub/Epub/css/CssParser.h +++ b/lib/Epub/Epub/css/CssParser.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp index 043cfca7..6022e0ee 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp @@ -1,8 +1,8 @@ #include "ChapterHtmlSlimParser.h" #include +#include #include -#include #include #include "../Page.h" @@ -482,7 +482,7 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() { } FsFile file; - if (!SdMan.openFileForRead("EHP", filepath, file)) { + if (!Storage.openFileForRead("EHP", filepath, file)) { XML_ParserFree(parser); return false; } diff --git a/lib/Epub/Epub/parsers/ContentOpfParser.cpp b/lib/Epub/Epub/parsers/ContentOpfParser.cpp index c6cdec4e..ae7e61a5 100644 --- a/lib/Epub/Epub/parsers/ContentOpfParser.cpp +++ b/lib/Epub/Epub/parsers/ContentOpfParser.cpp @@ -36,8 +36,8 @@ ContentOpfParser::~ContentOpfParser() { if (tempItemStore) { tempItemStore.close(); } - if (SdMan.exists((cachePath + itemCacheFile).c_str())) { - SdMan.remove((cachePath + itemCacheFile).c_str()); + if (Storage.exists((cachePath + itemCacheFile).c_str())) { + Storage.remove((cachePath + itemCacheFile).c_str()); } itemIndex.clear(); itemIndex.shrink_to_fit(); @@ -118,7 +118,7 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name if (self->state == IN_PACKAGE && (strcmp(name, "manifest") == 0 || strcmp(name, "opf:manifest") == 0)) { self->state = IN_MANIFEST; - if (!SdMan.openFileForWrite("COF", self->cachePath + itemCacheFile, self->tempItemStore)) { + if (!Storage.openFileForWrite("COF", self->cachePath + itemCacheFile, self->tempItemStore)) { Serial.printf( "[%lu] [COF] Couldn't open temp items file for writing. This is probably going to be a fatal error.\n", millis()); @@ -128,7 +128,7 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name if (self->state == IN_PACKAGE && (strcmp(name, "spine") == 0 || strcmp(name, "opf:spine") == 0)) { self->state = IN_SPINE; - if (!SdMan.openFileForRead("COF", self->cachePath + itemCacheFile, self->tempItemStore)) { + if (!Storage.openFileForRead("COF", self->cachePath + itemCacheFile, self->tempItemStore)) { Serial.printf( "[%lu] [COF] Couldn't open temp items file for reading. This is probably going to be a fatal error.\n", millis()); @@ -149,7 +149,7 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name self->state = IN_GUIDE; // TODO Remove print Serial.printf("[%lu] [COF] Entering guide state.\n", millis()); - if (!SdMan.openFileForRead("COF", self->cachePath + itemCacheFile, self->tempItemStore)) { + if (!Storage.openFileForRead("COF", self->cachePath + itemCacheFile, self->tempItemStore)) { Serial.printf( "[%lu] [COF] Couldn't open temp items file for reading. This is probably going to be a fatal error.\n", millis()); diff --git a/lib/GfxRenderer/Bitmap.h b/lib/GfxRenderer/Bitmap.h index 544869c1..102283de 100644 --- a/lib/GfxRenderer/Bitmap.h +++ b/lib/GfxRenderer/Bitmap.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include diff --git a/lib/JpegToBmpConverter/JpegToBmpConverter.cpp b/lib/JpegToBmpConverter/JpegToBmpConverter.cpp index 0b1541b4..e2125661 100644 --- a/lib/JpegToBmpConverter/JpegToBmpConverter.cpp +++ b/lib/JpegToBmpConverter/JpegToBmpConverter.cpp @@ -1,7 +1,7 @@ #include "JpegToBmpConverter.h" +#include #include -#include #include #include diff --git a/lib/KOReaderSync/KOReaderCredentialStore.cpp b/lib/KOReaderSync/KOReaderCredentialStore.cpp index c5737809..01cb6c6b 100644 --- a/lib/KOReaderSync/KOReaderCredentialStore.cpp +++ b/lib/KOReaderSync/KOReaderCredentialStore.cpp @@ -1,8 +1,8 @@ #include "KOReaderCredentialStore.h" +#include #include #include -#include #include // Initialize the static instance @@ -32,10 +32,10 @@ void KOReaderCredentialStore::obfuscate(std::string& data) const { bool KOReaderCredentialStore::saveToFile() const { // Make sure the directory exists - SdMan.mkdir("/.crosspoint"); + Storage.mkdir("/.crosspoint"); FsFile file; - if (!SdMan.openFileForWrite("KRS", KOREADER_FILE, file)) { + if (!Storage.openFileForWrite("KRS", KOREADER_FILE, file)) { return false; } @@ -64,7 +64,7 @@ bool KOReaderCredentialStore::saveToFile() const { bool KOReaderCredentialStore::loadFromFile() { FsFile file; - if (!SdMan.openFileForRead("KRS", KOREADER_FILE, file)) { + if (!Storage.openFileForRead("KRS", KOREADER_FILE, file)) { Serial.printf("[%lu] [KRS] No credentials file found\n", millis()); return false; } diff --git a/lib/KOReaderSync/KOReaderDocumentId.cpp b/lib/KOReaderSync/KOReaderDocumentId.cpp index b33beb75..4cc259ce 100644 --- a/lib/KOReaderSync/KOReaderDocumentId.cpp +++ b/lib/KOReaderSync/KOReaderDocumentId.cpp @@ -1,8 +1,8 @@ #include "KOReaderDocumentId.h" +#include #include #include -#include namespace { // Extract filename from path (everything after last '/') @@ -43,7 +43,7 @@ size_t KOReaderDocumentId::getOffset(int i) { std::string KOReaderDocumentId::calculate(const std::string& filePath) { FsFile file; - if (!SdMan.openFileForRead("KODoc", filePath, file)) { + if (!Storage.openFileForRead("KODoc", filePath, file)) { Serial.printf("[%lu] [KODoc] Failed to open file: %s\n", millis(), filePath.c_str()); return ""; } diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h index afea5646..1308822f 100644 --- a/lib/Serialization/Serialization.h +++ b/lib/Serialization/Serialization.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include diff --git a/lib/Txt/Txt.cpp b/lib/Txt/Txt.cpp index 52c75ed7..28bb9395 100644 --- a/lib/Txt/Txt.cpp +++ b/lib/Txt/Txt.cpp @@ -15,13 +15,13 @@ bool Txt::load() { return true; } - if (!SdMan.exists(filepath.c_str())) { + if (!Storage.exists(filepath.c_str())) { Serial.printf("[%lu] [TXT] File does not exist: %s\n", millis(), filepath.c_str()); return false; } FsFile file; - if (!SdMan.openFileForRead("TXT", filepath, file)) { + if (!Storage.openFileForRead("TXT", filepath, file)) { Serial.printf("[%lu] [TXT] Failed to open file: %s\n", millis(), filepath.c_str()); return false; } @@ -48,11 +48,11 @@ std::string Txt::getTitle() const { } void Txt::setupCacheDir() const { - if (!SdMan.exists(cacheBasePath.c_str())) { - SdMan.mkdir(cacheBasePath.c_str()); + if (!Storage.exists(cacheBasePath.c_str())) { + Storage.mkdir(cacheBasePath.c_str()); } - if (!SdMan.exists(cachePath.c_str())) { - SdMan.mkdir(cachePath.c_str()); + if (!Storage.exists(cachePath.c_str())) { + Storage.mkdir(cachePath.c_str()); } } @@ -73,7 +73,7 @@ std::string Txt::findCoverImage() const { // First priority: look for image with same name as txt file (e.g., mybook.jpg) for (const auto& ext : extensions) { std::string coverPath = folder + "/" + baseName + ext; - if (SdMan.exists(coverPath.c_str())) { + if (Storage.exists(coverPath.c_str())) { Serial.printf("[%lu] [TXT] Found matching cover image: %s\n", millis(), coverPath.c_str()); return coverPath; } @@ -84,7 +84,7 @@ std::string Txt::findCoverImage() const { for (const auto& name : coverNames) { for (const auto& ext : extensions) { std::string coverPath = folder + "/" + std::string(name) + ext; - if (SdMan.exists(coverPath.c_str())) { + if (Storage.exists(coverPath.c_str())) { Serial.printf("[%lu] [TXT] Found fallback cover image: %s\n", millis(), coverPath.c_str()); return coverPath; } @@ -98,7 +98,7 @@ std::string Txt::getCoverBmpPath() const { return cachePath + "/cover.bmp"; } bool Txt::generateCoverBmp() const { // Already generated, return true - if (SdMan.exists(getCoverBmpPath().c_str())) { + if (Storage.exists(getCoverBmpPath().c_str())) { return true; } @@ -122,10 +122,10 @@ bool Txt::generateCoverBmp() const { // Copy BMP file to cache Serial.printf("[%lu] [TXT] Copying BMP cover image to cache\n", millis()); FsFile src, dst; - if (!SdMan.openFileForRead("TXT", coverImagePath, src)) { + if (!Storage.openFileForRead("TXT", coverImagePath, src)) { return false; } - if (!SdMan.openFileForWrite("TXT", getCoverBmpPath(), dst)) { + if (!Storage.openFileForWrite("TXT", getCoverBmpPath(), dst)) { src.close(); return false; } @@ -144,10 +144,10 @@ bool Txt::generateCoverBmp() const { // Convert JPG/JPEG to BMP (same approach as Epub) Serial.printf("[%lu] [TXT] Generating BMP from JPG cover image\n", millis()); FsFile coverJpg, coverBmp; - if (!SdMan.openFileForRead("TXT", coverImagePath, coverJpg)) { + if (!Storage.openFileForRead("TXT", coverImagePath, coverJpg)) { return false; } - if (!SdMan.openFileForWrite("TXT", getCoverBmpPath(), coverBmp)) { + if (!Storage.openFileForWrite("TXT", getCoverBmpPath(), coverBmp)) { coverJpg.close(); return false; } @@ -157,7 +157,7 @@ bool Txt::generateCoverBmp() const { if (!success) { Serial.printf("[%lu] [TXT] Failed to generate BMP from JPG cover image\n", millis()); - SdMan.remove(getCoverBmpPath().c_str()); + Storage.remove(getCoverBmpPath().c_str()); } else { Serial.printf("[%lu] [TXT] Generated BMP from JPG cover image\n", millis()); } @@ -175,7 +175,7 @@ bool Txt::readContent(uint8_t* buffer, size_t offset, size_t length) const { } FsFile file; - if (!SdMan.openFileForRead("TXT", filepath, file)) { + if (!Storage.openFileForRead("TXT", filepath, file)) { return false; } diff --git a/lib/Txt/Txt.h b/lib/Txt/Txt.h index b75c7738..b342ca88 100644 --- a/lib/Txt/Txt.h +++ b/lib/Txt/Txt.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/lib/Xtc/Xtc.cpp b/lib/Xtc/Xtc.cpp index 717bb670..e01e4f0a 100644 --- a/lib/Xtc/Xtc.cpp +++ b/lib/Xtc/Xtc.cpp @@ -7,8 +7,8 @@ #include "Xtc.h" +#include #include -#include bool Xtc::load() { Serial.printf("[%lu] [XTC] Loading XTC: %s\n", millis(), filepath.c_str()); @@ -30,12 +30,12 @@ bool Xtc::load() { } bool Xtc::clearCache() const { - if (!SdMan.exists(cachePath.c_str())) { + if (!Storage.exists(cachePath.c_str())) { Serial.printf("[%lu] [XTC] Cache does not exist, no action needed\n", millis()); return true; } - if (!SdMan.removeDir(cachePath.c_str())) { + if (!Storage.removeDir(cachePath.c_str())) { Serial.printf("[%lu] [XTC] Failed to clear cache\n", millis()); return false; } @@ -45,17 +45,17 @@ bool Xtc::clearCache() const { } void Xtc::setupCacheDir() const { - if (SdMan.exists(cachePath.c_str())) { + if (Storage.exists(cachePath.c_str())) { return; } // Create directories recursively for (size_t i = 1; i < cachePath.length(); i++) { if (cachePath[i] == '/') { - SdMan.mkdir(cachePath.substr(0, i).c_str()); + Storage.mkdir(cachePath.substr(0, i).c_str()); } } - SdMan.mkdir(cachePath.c_str()); + Storage.mkdir(cachePath.c_str()); } std::string Xtc::getTitle() const { @@ -114,7 +114,7 @@ std::string Xtc::getCoverBmpPath() const { return cachePath + "/cover.bmp"; } bool Xtc::generateCoverBmp() const { // Already generated - if (SdMan.exists(getCoverBmpPath().c_str())) { + if (Storage.exists(getCoverBmpPath().c_str())) { return true; } @@ -166,7 +166,7 @@ bool Xtc::generateCoverBmp() const { // Create BMP file FsFile coverBmp; - if (!SdMan.openFileForWrite("XTC", getCoverBmpPath(), coverBmp)) { + if (!Storage.openFileForWrite("XTC", getCoverBmpPath(), coverBmp)) { Serial.printf("[%lu] [XTC] Failed to create cover BMP file\n", millis()); free(pageBuffer); return false; @@ -306,7 +306,7 @@ std::string Xtc::getThumbBmpPath(int height) const { return cachePath + "/thumb_ bool Xtc::generateThumbBmp(int height) const { // Already generated - if (SdMan.exists(getThumbBmpPath(height).c_str())) { + if (Storage.exists(getThumbBmpPath(height).c_str())) { return true; } @@ -348,8 +348,8 @@ bool Xtc::generateThumbBmp(int height) const { // Copy cover.bmp to thumb.bmp if (generateCoverBmp()) { FsFile src, dst; - if (SdMan.openFileForRead("XTC", getCoverBmpPath(), src)) { - if (SdMan.openFileForWrite("XTC", getThumbBmpPath(height), dst)) { + if (Storage.openFileForRead("XTC", getCoverBmpPath(), src)) { + if (Storage.openFileForWrite("XTC", getThumbBmpPath(height), dst)) { uint8_t buffer[512]; while (src.available()) { size_t bytesRead = src.read(buffer, sizeof(buffer)); @@ -360,7 +360,7 @@ bool Xtc::generateThumbBmp(int height) const { src.close(); } Serial.printf("[%lu] [XTC] Copied cover to thumb (no scaling needed)\n", millis()); - return SdMan.exists(getThumbBmpPath(height).c_str()); + return Storage.exists(getThumbBmpPath(height).c_str()); } return false; } @@ -394,7 +394,7 @@ bool Xtc::generateThumbBmp(int height) const { // Create thumbnail BMP file - use 1-bit format for fast home screen rendering (no gray passes) FsFile thumbBmp; - if (!SdMan.openFileForWrite("XTC", getThumbBmpPath(height), thumbBmp)) { + if (!Storage.openFileForWrite("XTC", getThumbBmpPath(height), thumbBmp)) { Serial.printf("[%lu] [XTC] Failed to create thumb BMP file\n", millis()); free(pageBuffer); return false; diff --git a/lib/Xtc/Xtc/XtcParser.cpp b/lib/Xtc/Xtc/XtcParser.cpp index 8db3dead..a604b645 100644 --- a/lib/Xtc/Xtc/XtcParser.cpp +++ b/lib/Xtc/Xtc/XtcParser.cpp @@ -8,8 +8,8 @@ #include "XtcParser.h" #include +#include #include -#include #include @@ -34,7 +34,7 @@ XtcError XtcParser::open(const char* filepath) { } // Open file - if (!SdMan.openFileForRead("XTC", filepath, m_file)) { + if (!Storage.openFileForRead("XTC", filepath, m_file)) { m_lastError = XtcError::FILE_NOT_FOUND; return m_lastError; } @@ -444,7 +444,7 @@ XtcError XtcParser::loadPageStreaming(uint32_t pageIndex, bool XtcParser::isValidXtcFile(const char* filepath) { FsFile file; - if (!SdMan.openFileForRead("XTC", filepath, file)) { + if (!Storage.openFileForRead("XTC", filepath, file)) { return false; } diff --git a/lib/Xtc/Xtc/XtcParser.h b/lib/Xtc/Xtc/XtcParser.h index b0033542..19f3b75d 100644 --- a/lib/Xtc/Xtc/XtcParser.h +++ b/lib/Xtc/Xtc/XtcParser.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include diff --git a/lib/ZipFile/ZipFile.cpp b/lib/ZipFile/ZipFile.cpp index a5f65ea3..a2e92762 100644 --- a/lib/ZipFile/ZipFile.cpp +++ b/lib/ZipFile/ZipFile.cpp @@ -1,7 +1,7 @@ #include "ZipFile.h" +#include #include -#include #include #include @@ -279,7 +279,7 @@ bool ZipFile::loadZipDetails() { } bool ZipFile::open() { - if (!SdMan.openFileForRead("ZIP", filePath, file)) { + if (!Storage.openFileForRead("ZIP", filePath, file)) { return false; } return true; diff --git a/lib/ZipFile/ZipFile.h b/lib/ZipFile/ZipFile.h index 0c82e5a0..bc97559d 100644 --- a/lib/ZipFile/ZipFile.h +++ b/lib/ZipFile/ZipFile.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include #include diff --git a/lib/hal/HalStorage.cpp b/lib/hal/HalStorage.cpp new file mode 100644 index 00000000..fa5d7f41 --- /dev/null +++ b/lib/hal/HalStorage.cpp @@ -0,0 +1,65 @@ +#include "HalStorage.h" + +#include + +#define SDCard SDCardManager::getInstance() + +HalStorage HalStorage::instance; + +HalStorage::HalStorage() {} + +bool HalStorage::begin() { return SDCard.begin(); } + +bool HalStorage::ready() const { return SDCard.ready(); } + +std::vector HalStorage::listFiles(const char* path, int maxFiles) { return SDCard.listFiles(path, maxFiles); } + +String HalStorage::readFile(const char* path) { return SDCard.readFile(path); } + +bool HalStorage::readFileToStream(const char* path, Print& out, size_t chunkSize) { + return SDCard.readFileToStream(path, out, chunkSize); +} + +size_t HalStorage::readFileToBuffer(const char* path, char* buffer, size_t bufferSize, size_t maxBytes) { + return SDCard.readFileToBuffer(path, buffer, bufferSize, maxBytes); +} + +bool HalStorage::writeFile(const char* path, const String& content) { return SDCard.writeFile(path, content); } + +bool HalStorage::ensureDirectoryExists(const char* path) { return SDCard.ensureDirectoryExists(path); } + +FsFile HalStorage::open(const char* path, const oflag_t oflag) { return SDCard.open(path, oflag); } + +bool HalStorage::mkdir(const char* path, const bool pFlag) { return SDCard.mkdir(path, pFlag); } + +bool HalStorage::exists(const char* path) { return SDCard.exists(path); } + +bool HalStorage::remove(const char* path) { return SDCard.remove(path); } + +bool HalStorage::rmdir(const char* path) { return SDCard.rmdir(path); } + +bool HalStorage::openFileForRead(const char* moduleName, const char* path, FsFile& file) { + return SDCard.openFileForRead(moduleName, path, file); +} + +bool HalStorage::openFileForRead(const char* moduleName, const std::string& path, FsFile& file) { + return openFileForRead(moduleName, path.c_str(), file); +} + +bool HalStorage::openFileForRead(const char* moduleName, const String& path, FsFile& file) { + return openFileForRead(moduleName, path.c_str(), file); +} + +bool HalStorage::openFileForWrite(const char* moduleName, const char* path, FsFile& file) { + return SDCard.openFileForWrite(moduleName, path, file); +} + +bool HalStorage::openFileForWrite(const char* moduleName, const std::string& path, FsFile& file) { + return openFileForWrite(moduleName, path.c_str(), file); +} + +bool HalStorage::openFileForWrite(const char* moduleName, const String& path, FsFile& file) { + return openFileForWrite(moduleName, path.c_str(), file); +} + +bool HalStorage::removeDir(const char* path) { return SDCard.removeDir(path); } \ No newline at end of file diff --git a/lib/hal/HalStorage.h b/lib/hal/HalStorage.h new file mode 100644 index 00000000..02f8eb44 --- /dev/null +++ b/lib/hal/HalStorage.h @@ -0,0 +1,54 @@ +#pragma once + +#include + +#include + +class HalStorage { + public: + HalStorage(); + bool begin(); + bool ready() const; + std::vector 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); + + FsFile 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, FsFile& file); + bool openFileForRead(const char* moduleName, const std::string& path, FsFile& file); + bool openFileForRead(const char* moduleName, const String& path, FsFile& file); + bool openFileForWrite(const char* moduleName, const char* path, FsFile& file); + bool openFileForWrite(const char* moduleName, const std::string& path, FsFile& file); + bool openFileForWrite(const char* moduleName, const String& path, FsFile& file); + bool removeDir(const char* path); + + static HalStorage& getInstance() { return instance; } + + private: + static HalStorage instance; + + bool initialized = false; +}; + +#define Storage HalStorage::getInstance() + +// Downstream code must use Storage instead of SdMan +#ifdef SdMan +#undef SdMan +#endif diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp index 28a357e9..ffeef2b9 100644 --- a/src/CrossPointSettings.cpp +++ b/src/CrossPointSettings.cpp @@ -1,7 +1,7 @@ #include "CrossPointSettings.h" +#include #include -#include #include #include @@ -79,10 +79,10 @@ void applyLegacyFrontButtonLayout(CrossPointSettings& settings) { bool CrossPointSettings::saveToFile() const { // Make sure the directory exists - SdMan.mkdir("/.crosspoint"); + Storage.mkdir("/.crosspoint"); FsFile outputFile; - if (!SdMan.openFileForWrite("CPS", SETTINGS_FILE, outputFile)) { + if (!Storage.openFileForWrite("CPS", SETTINGS_FILE, outputFile)) { return false; } @@ -127,7 +127,7 @@ bool CrossPointSettings::saveToFile() const { bool CrossPointSettings::loadFromFile() { FsFile inputFile; - if (!SdMan.openFileForRead("CPS", SETTINGS_FILE, inputFile)) { + if (!Storage.openFileForRead("CPS", SETTINGS_FILE, inputFile)) { return false; } diff --git a/src/CrossPointState.cpp b/src/CrossPointState.cpp index d97344f2..5ca3cb45 100644 --- a/src/CrossPointState.cpp +++ b/src/CrossPointState.cpp @@ -1,7 +1,7 @@ #include "CrossPointState.h" +#include #include -#include #include namespace { @@ -13,7 +13,7 @@ CrossPointState CrossPointState::instance; bool CrossPointState::saveToFile() const { FsFile outputFile; - if (!SdMan.openFileForWrite("CPS", STATE_FILE, outputFile)) { + if (!Storage.openFileForWrite("CPS", STATE_FILE, outputFile)) { return false; } @@ -28,7 +28,7 @@ bool CrossPointState::saveToFile() const { bool CrossPointState::loadFromFile() { FsFile inputFile; - if (!SdMan.openFileForRead("CPS", STATE_FILE, inputFile)) { + if (!Storage.openFileForRead("CPS", STATE_FILE, inputFile)) { return false; } diff --git a/src/RecentBooksStore.cpp b/src/RecentBooksStore.cpp index 99586b79..9885fcdb 100644 --- a/src/RecentBooksStore.cpp +++ b/src/RecentBooksStore.cpp @@ -1,8 +1,8 @@ #include "RecentBooksStore.h" #include +#include #include -#include #include #include @@ -53,10 +53,10 @@ void RecentBooksStore::updateBook(const std::string& path, const std::string& ti 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)) { + if (!Storage.openFileForWrite("RBS", RECENT_BOOKS_FILE, outputFile)) { return false; } @@ -106,7 +106,7 @@ RecentBook RecentBooksStore::getDataFromBook(std::string path) const { bool RecentBooksStore::loadFromFile() { FsFile inputFile; - if (!SdMan.openFileForRead("RBS", RECENT_BOOKS_FILE, inputFile)) { + if (!Storage.openFileForRead("RBS", RECENT_BOOKS_FILE, inputFile)) { return false; } diff --git a/src/WifiCredentialStore.cpp b/src/WifiCredentialStore.cpp index be865b86..59c3a7d3 100644 --- a/src/WifiCredentialStore.cpp +++ b/src/WifiCredentialStore.cpp @@ -1,7 +1,7 @@ #include "WifiCredentialStore.h" +#include #include -#include #include // 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)) { + if (!Storage.openFileForWrite("WCS", WIFI_FILE, file)) { return false; } @@ -60,7 +60,7 @@ bool WifiCredentialStore::saveToFile() const { bool WifiCredentialStore::loadFromFile() { FsFile file; - if (!SdMan.openFileForRead("WCS", WIFI_FILE, file)) { + if (!Storage.openFileForRead("WCS", WIFI_FILE, file)) { return false; } diff --git a/src/activities/boot_sleep/SleepActivity.cpp b/src/activities/boot_sleep/SleepActivity.cpp index 81b55cc6..846df22d 100644 --- a/src/activities/boot_sleep/SleepActivity.cpp +++ b/src/activities/boot_sleep/SleepActivity.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include @@ -32,7 +32,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 files; char name[500]; @@ -75,7 +75,7 @@ void SleepActivity::renderCustomSleepScreen() const { APP_STATE.saveToFile(); const auto filename = "/sleep/" + files[randomFileIndex]; FsFile file; - if (SdMan.openFileForRead("SLP", filename, 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); @@ -92,7 +92,7 @@ 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)) { + 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()); @@ -262,7 +262,7 @@ void SleepActivity::renderCoverSleepScreen() const { } FsFile file; - if (SdMan.openFileForRead("SLP", coverBmpPath, file)) { + if (Storage.openFileForRead("SLP", coverBmpPath, file)) { Bitmap bitmap(file); if (bitmap.parseHeaders() == BmpReaderError::Ok) { Serial.printf("[SLP] Rendering sleep cover: %s\n", coverBmpPath.c_str()); diff --git a/src/activities/home/HomeActivity.cpp b/src/activities/home/HomeActivity.cpp index 15a59bfc..4155799c 100644 --- a/src/activities/home/HomeActivity.cpp +++ b/src/activities/home/HomeActivity.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -47,7 +47,7 @@ void HomeActivity::loadRecentBooks(int maxBooks) { } // Skip if file no longer exists - if (!SdMan.exists(book.path.c_str())) { + if (!Storage.exists(book.path.c_str())) { continue; } @@ -64,7 +64,7 @@ void HomeActivity::loadRecentCovers(int coverHeight) { for (RecentBook& book : recentBooks) { if (!book.coverBmpPath.empty()) { std::string coverPath = UITheme::getCoverThumbPath(book.coverBmpPath, coverHeight); - if (!SdMan.exists(coverPath.c_str())) { + if (!Storage.exists(coverPath.c_str())) { // If epub, try to load the metadata for title/author and cover if (StringUtils::checkFileExtension(book.path, ".epub")) { Epub epub(book.path, "/.crosspoint"); diff --git a/src/activities/home/MyLibraryActivity.cpp b/src/activities/home/MyLibraryActivity.cpp index 7523e542..e0a36b97 100644 --- a/src/activities/home/MyLibraryActivity.cpp +++ b/src/activities/home/MyLibraryActivity.cpp @@ -1,7 +1,7 @@ #include "MyLibraryActivity.h" #include -#include +#include #include @@ -33,7 +33,7 @@ void MyLibraryActivity::taskTrampoline(void* param) { 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; diff --git a/src/activities/home/RecentBooksActivity.cpp b/src/activities/home/RecentBooksActivity.cpp index 1be0e1e0..4add9b84 100644 --- a/src/activities/home/RecentBooksActivity.cpp +++ b/src/activities/home/RecentBooksActivity.cpp @@ -1,7 +1,7 @@ #include "RecentBooksActivity.h" #include -#include +#include #include @@ -28,7 +28,7 @@ void RecentBooksActivity::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); diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index cd045c8e..fb68d62b 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include "CrossPointSettings.h" #include "CrossPointState.h" @@ -77,7 +77,7 @@ void EpubReaderActivity::onEnter() { epub->setupCacheDir(); FsFile f; - if (SdMan.openFileForRead("ERS", epub->getCachePath() + "/progress.bin", 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) { @@ -654,7 +654,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; diff --git a/src/activities/reader/ReaderActivity.cpp b/src/activities/reader/ReaderActivity.cpp index 0b004f34..dd3ea2e9 100644 --- a/src/activities/reader/ReaderActivity.cpp +++ b/src/activities/reader/ReaderActivity.cpp @@ -1,5 +1,7 @@ #include "ReaderActivity.h" +#include + #include "Epub.h" #include "EpubReaderActivity.h" #include "Txt.h" @@ -27,7 +29,7 @@ bool ReaderActivity::isTxtFile(const std::string& path) { } std::unique_ptr 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 ReaderActivity::loadEpub(const std::string& path) { } std::unique_ptr 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 ReaderActivity::loadXtc(const std::string& path) { } std::unique_ptr 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; } diff --git a/src/activities/reader/TxtReaderActivity.cpp b/src/activities/reader/TxtReaderActivity.cpp index 2032518a..441d5700 100644 --- a/src/activities/reader/TxtReaderActivity.cpp +++ b/src/activities/reader/TxtReaderActivity.cpp @@ -1,7 +1,7 @@ #include "TxtReaderActivity.h" #include -#include +#include #include #include @@ -565,7 +565,7 @@ void TxtReaderActivity::renderStatusBar(const int orientedMarginRight, const int void TxtReaderActivity::saveProgress() const { FsFile f; - if (SdMan.openFileForWrite("TRS", txt->getCachePath() + "/progress.bin", f)) { + if (Storage.openFileForWrite("TRS", txt->getCachePath() + "/progress.bin", f)) { uint8_t data[4]; data[0] = currentPage & 0xFF; data[1] = (currentPage >> 8) & 0xFF; @@ -578,7 +578,7 @@ void TxtReaderActivity::saveProgress() const { void TxtReaderActivity::loadProgress() { FsFile f; - if (SdMan.openFileForRead("TRS", txt->getCachePath() + "/progress.bin", 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); @@ -609,7 +609,7 @@ bool TxtReaderActivity::loadPageIndexCache() { std::string cachePath = txt->getCachePath() + "/index.bin"; FsFile f; - if (!SdMan.openFileForRead("TRS", cachePath, f)) { + if (!Storage.openFileForRead("TRS", cachePath, f)) { Serial.printf("[%lu] [TRS] No page index cache found\n", millis()); return false; } @@ -701,7 +701,7 @@ bool TxtReaderActivity::loadPageIndexCache() { void TxtReaderActivity::savePageIndexCache() const { std::string cachePath = txt->getCachePath() + "/index.bin"; FsFile f; - if (!SdMan.openFileForWrite("TRS", cachePath, f)) { + if (!Storage.openFileForWrite("TRS", cachePath, f)) { Serial.printf("[%lu] [TRS] Failed to save page index cache\n", millis()); return; } diff --git a/src/activities/reader/XtcReaderActivity.cpp b/src/activities/reader/XtcReaderActivity.cpp index c28f6f44..31795fa8 100644 --- a/src/activities/reader/XtcReaderActivity.cpp +++ b/src/activities/reader/XtcReaderActivity.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include "CrossPointSettings.h" #include "CrossPointState.h" @@ -372,7 +372,7 @@ void XtcReaderActivity::renderPage() { void XtcReaderActivity::saveProgress() const { FsFile f; - if (SdMan.openFileForWrite("XTR", xtc->getCachePath() + "/progress.bin", f)) { + if (Storage.openFileForWrite("XTR", xtc->getCachePath() + "/progress.bin", f)) { uint8_t data[4]; data[0] = currentPage & 0xFF; data[1] = (currentPage >> 8) & 0xFF; @@ -385,7 +385,7 @@ void XtcReaderActivity::saveProgress() const { void XtcReaderActivity::loadProgress() { FsFile f; - if (SdMan.openFileForRead("XTR", xtc->getCachePath() + "/progress.bin", 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); diff --git a/src/activities/settings/ClearCacheActivity.cpp b/src/activities/settings/ClearCacheActivity.cpp index f00472b1..b17627dc 100644 --- a/src/activities/settings/ClearCacheActivity.cpp +++ b/src/activities/settings/ClearCacheActivity.cpp @@ -1,8 +1,8 @@ #include "ClearCacheActivity.h" #include +#include #include -#include #include "MappedInputManager.h" #include "components/UITheme.h" @@ -107,7 +107,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(); @@ -132,7 +132,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()); diff --git a/src/components/themes/BaseTheme.cpp b/src/components/themes/BaseTheme.cpp index 9253953e..14783e55 100644 --- a/src/components/themes/BaseTheme.cpp +++ b/src/components/themes/BaseTheme.cpp @@ -1,7 +1,7 @@ #include "BaseTheme.h" #include -#include +#include #include #include @@ -308,7 +308,7 @@ void BaseTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std: // First time: load cover from SD and render FsFile file; - if (SdMan.openFileForRead("HOME", coverBmpPath, file)) { + if (Storage.openFileForRead("HOME", coverBmpPath, file)) { Bitmap bitmap(file); if (bitmap.parseHeaders() == BmpReaderError::Ok) { Serial.printf("Rendering bmp\n"); diff --git a/src/components/themes/lyra/LyraTheme.cpp b/src/components/themes/lyra/LyraTheme.cpp index c07e7a5f..2e3ad4cd 100644 --- a/src/components/themes/lyra/LyraTheme.cpp +++ b/src/components/themes/lyra/LyraTheme.cpp @@ -1,7 +1,7 @@ #include "LyraTheme.h" #include -#include +#include #include #include @@ -283,7 +283,7 @@ void LyraTheme::drawRecentBookCover(GfxRenderer& renderer, Rect rect, const std: // First time: load cover from SD and render FsFile file; - if (SdMan.openFileForRead("HOME", coverBmpPath, file)) { + if (Storage.openFileForRead("HOME", coverBmpPath, file)) { Bitmap bitmap(file); if (bitmap.parseHeaders() == BmpReaderError::Ok) { float coverHeight = static_cast(bitmap.getHeight()); diff --git a/src/main.cpp b/src/main.cpp index 4895be38..33515bce 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -293,7 +293,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(); diff --git a/src/network/CrossPointWebServer.cpp b/src/network/CrossPointWebServer.cpp index 6a0c2e86..d29edb5a 100644 --- a/src/network/CrossPointWebServer.cpp +++ b/src/network/CrossPointWebServer.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -316,7 +316,7 @@ void CrossPointWebServer::handleStatus() const { } void CrossPointWebServer::scanFiles(const char* path, const std::function& callback) const { - FsFile root = SdMan.open(path); + FsFile root = Storage.open(path); if (!root) { Serial.printf("[%lu] [WEB] Failed to open directory: %s\n", millis(), path); return; @@ -458,12 +458,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()); + FsFile file = Storage.open(itemPath.c_str()); if (!file) { server->send(500, "text/plain", "Failed to open file"); return; @@ -574,15 +574,15 @@ void CrossPointWebServer::handleUpload(UploadState& state) 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, state.file)) { + if (!Storage.openFileForWrite("WEB", filePath, state.file)) { state.error = "Failed to create file on SD card"; Serial.printf("[%lu] [WEB] [UPLOAD] FAILED to create file: %s\n", millis(), filePath.c_str()); return; @@ -660,7 +660,7 @@ void CrossPointWebServer::handleUpload(UploadState& state) const { String filePath = state.path; if (!filePath.endsWith("/")) filePath += "/"; filePath += state.fileName; - SdMan.remove(filePath.c_str()); + Storage.remove(filePath.c_str()); } state.error = "Upload aborted"; Serial.printf("[%lu] [WEB] Upload aborted\n", millis()); @@ -711,13 +711,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 { @@ -763,12 +763,12 @@ void CrossPointWebServer::handleRename() const { return; } - 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()); + FsFile file = Storage.open(itemPath.c_str()); if (!file) { server->send(500, "text/plain", "Failed to open file"); return; @@ -789,7 +789,7 @@ void CrossPointWebServer::handleRename() const { } newPath += newName; - if (SdMan.exists(newPath.c_str())) { + if (Storage.exists(newPath.c_str())) { file.close(); server->send(409, "text/plain", "Target already exists"); return; @@ -839,12 +839,12 @@ void CrossPointWebServer::handleMove() 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()); + FsFile file = Storage.open(itemPath.c_str()); if (!file) { server->send(500, "text/plain", "Failed to open file"); return; @@ -855,12 +855,12 @@ void CrossPointWebServer::handleMove() const { return; } - if (!SdMan.exists(destPath.c_str())) { + if (!Storage.exists(destPath.c_str())) { file.close(); server->send(404, "text/plain", "Destination not found"); return; } - FsFile destDir = SdMan.open(destPath.c_str()); + FsFile destDir = Storage.open(destPath.c_str()); if (!destDir || !destDir.isDirectory()) { if (destDir) { destDir.close(); @@ -882,7 +882,7 @@ void CrossPointWebServer::handleMove() const { server->send(200, "text/plain", "Already in destination"); return; } - if (SdMan.exists(newPath.c_str())) { + if (Storage.exists(newPath.c_str())) { file.close(); server->send(409, "text/plain", "Target already exists"); return; @@ -942,7 +942,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; @@ -954,7 +954,7 @@ void CrossPointWebServer::handleDelete() const { if (itemType == "folder") { // For folders, try to remove (will fail if not empty) - FsFile dir = SdMan.open(itemPath.c_str()); + FsFile dir = Storage.open(itemPath.c_str()); if (dir && dir.isDirectory()) { // Check if folder is empty FsFile entry = dir.openNextFile(); @@ -968,10 +968,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) { @@ -1007,7 +1007,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; @@ -1051,13 +1051,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; diff --git a/src/network/CrossPointWebServer.h b/src/network/CrossPointWebServer.h index f7bc8586..db318d0a 100644 --- a/src/network/CrossPointWebServer.h +++ b/src/network/CrossPointWebServer.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/src/network/HttpDownloader.cpp b/src/network/HttpDownloader.cpp index b7718c2d..8ca07b2b 100644 --- a/src/network/HttpDownloader.cpp +++ b/src/network/HttpDownloader.cpp @@ -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)) { + 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; } diff --git a/src/network/HttpDownloader.h b/src/network/HttpDownloader.h index ac520a42..fd18dd4c 100644 --- a/src/network/HttpDownloader.h +++ b/src/network/HttpDownloader.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include #include