diff --git a/lib/EpdFont/EpdFont.cpp b/lib/EpdFont/EpdFont.cpp index 661317d6..7dde633f 100644 --- a/lib/EpdFont/EpdFont.cpp +++ b/lib/EpdFont/EpdFont.cpp @@ -2,8 +2,7 @@ #include -inline int min(const int a, const int b) { return a < b ? a : b; } -inline int max(const int a, const int b) { return a < b ? b : a; } +#include void EpdFont::getTextBounds(const char* string, const int startX, const int startY, int* minX, int* minY, int* maxX, int* maxY) const { @@ -32,10 +31,10 @@ void EpdFont::getTextBounds(const char* string, const int startX, const int star continue; } - *minX = min(*minX, cursorX + glyph->left); - *maxX = max(*maxX, cursorX + glyph->left + glyph->width); - *minY = min(*minY, cursorY + glyph->top - glyph->height); - *maxY = max(*maxY, cursorY + glyph->top); + *minX = std::min(*minX, cursorX + glyph->left); + *maxX = std::max(*maxX, cursorX + glyph->left + glyph->width); + *minY = std::min(*minY, cursorY + glyph->top - glyph->height); + *maxY = std::max(*maxY, cursorY + glyph->top); cursorX += glyph->advanceX; } } diff --git a/lib/Epub/Epub.cpp b/lib/Epub/Epub.cpp index ec009832..fde2e16a 100644 --- a/lib/Epub/Epub.cpp +++ b/lib/Epub/Epub.cpp @@ -109,17 +109,20 @@ bool Epub::parseTocNcxFile() const { if (!ncxParser.setup()) { Serial.printf("[%lu] [EBP] Could not setup toc ncx parser\n", millis()); + tempNcxFile.close(); return false; } const auto ncxBuffer = static_cast(malloc(1024)); if (!ncxBuffer) { Serial.printf("[%lu] [EBP] Could not allocate memory for toc ncx parser\n", millis()); + tempNcxFile.close(); return false; } while (tempNcxFile.available()) { const auto readSize = tempNcxFile.read(ncxBuffer, 1024); + if (readSize == 0) break; const auto processedSize = ncxParser.write(ncxBuffer, readSize); if (processedSize != readSize) { diff --git a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp index a2b61899..9f7fed9f 100644 --- a/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp +++ b/lib/Epub/Epub/parsers/ChapterHtmlSlimParser.cpp @@ -57,7 +57,6 @@ void ChapterHtmlSlimParser::startNewTextBlock(const TextBlock::BLOCK_STYLE style void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* name, const XML_Char** atts) { auto* self = static_cast(userData); - (void)atts; // Middle of skip if (self->skipUntilDepth < self->depth) { @@ -93,7 +92,7 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* if (matches(name, HEADER_TAGS, NUM_HEADER_TAGS)) { self->startNewTextBlock(TextBlock::CENTER_ALIGN); - self->boldUntilDepth = min(self->boldUntilDepth, self->depth); + self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth); } else if (matches(name, BLOCK_TAGS, NUM_BLOCK_TAGS)) { if (strcmp(name, "br") == 0) { self->startNewTextBlock(self->currentTextBlock->getStyle()); @@ -101,9 +100,9 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* self->startNewTextBlock(TextBlock::JUSTIFIED); } } else if (matches(name, BOLD_TAGS, NUM_BOLD_TAGS)) { - self->boldUntilDepth = min(self->boldUntilDepth, self->depth); + self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth); } else if (matches(name, ITALIC_TAGS, NUM_ITALIC_TAGS)) { - self->italicUntilDepth = min(self->italicUntilDepth, self->depth); + self->italicUntilDepth = std::min(self->italicUntilDepth, self->depth); } self->depth += 1; @@ -162,7 +161,6 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* name) { auto* self = static_cast(userData); - (void)name; if (self->partWordBufferIndex > 0) { // Only flush out part word buffer if we're closing a block tag or are at the top of the HTML file. @@ -245,9 +243,9 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() { return false; } - const size_t len = file.read(static_cast(buf), 1024); + const size_t len = file.read(buf, 1024); - if (len == 0) { + if (len == 0 && file.available() > 0) { Serial.printf("[%lu] [EHP] File read error\n", millis()); XML_StopParser(parser, XML_FALSE); // Stop any pending processing XML_SetElementHandler(parser, nullptr, nullptr); // Clear callbacks diff --git a/lib/GfxRenderer/GfxRenderer.h b/lib/GfxRenderer/GfxRenderer.h index f6f5fe0c..0d7bb885 100644 --- a/lib/GfxRenderer/GfxRenderer.h +++ b/lib/GfxRenderer/GfxRenderer.h @@ -37,7 +37,7 @@ class GfxRenderer { public: explicit GfxRenderer(EInkDisplay& einkDisplay) : einkDisplay(einkDisplay), renderMode(BW), orientation(Portrait) {} - ~GfxRenderer() = default; + ~GfxRenderer() { freeBwBufferChunks(); } static constexpr int VIEWABLE_MARGIN_TOP = 9; static constexpr int VIEWABLE_MARGIN_RIGHT = 3; diff --git a/src/network/CrossPointWebServer.cpp b/src/network/CrossPointWebServer.cpp index 916f6a26..3a26a736 100644 --- a/src/network/CrossPointWebServer.cpp +++ b/src/network/CrossPointWebServer.cpp @@ -50,6 +50,14 @@ void CrossPointWebServer::begin() { Serial.printf("[%lu] [WEB] Creating web server on port %d...\n", millis(), port); server.reset(new WebServer(port)); + + // Disable WiFi sleep to improve responsiveness and prevent 'unreachable' errors. + // This is critical for reliable web server operation on ESP32. + WiFi.setSleep(false); + + // Note: WebServer class doesn't have setNoDelay() in the standard ESP32 library. + // We rely on disabling WiFi sleep for responsiveness. + Serial.printf("[%lu] [WEB] [MEM] Free heap after WebServer allocation: %d bytes\n", millis(), ESP.getFreeHeap()); if (!server) { @@ -157,15 +165,16 @@ void CrossPointWebServer::handleStatus() const { // Get correct IP based on AP vs STA mode const String ipAddr = apMode ? WiFi.softAPIP().toString() : WiFi.localIP().toString(); - String json = "{"; - json += "\"version\":\"" + String(CROSSPOINT_VERSION) + "\","; - json += "\"ip\":\"" + ipAddr + "\","; - json += "\"mode\":\"" + String(apMode ? "AP" : "STA") + "\","; - json += "\"rssi\":" + String(apMode ? 0 : WiFi.RSSI()) + ","; // RSSI not applicable in AP mode - json += "\"freeHeap\":" + String(ESP.getFreeHeap()) + ","; - json += "\"uptime\":" + String(millis() / 1000); - json += "}"; + JsonDocument doc; + doc["version"] = CROSSPOINT_VERSION; + doc["ip"] = ipAddr; + doc["mode"] = apMode ? "AP" : "STA"; + doc["rssi"] = apMode ? 0 : WiFi.RSSI(); + doc["freeHeap"] = ESP.getFreeHeap(); + doc["uptime"] = millis() / 1000; + String json; + serializeJson(doc, json); server->send(200, "application/json", json); } @@ -220,6 +229,7 @@ void CrossPointWebServer::scanFiles(const char* path, const std::function= outputSize) { // JSON output truncated; skip this entry to avoid sending malformed JSON