From c22a2b56fbe1fcbe751e46070fb43943d7d8d690 Mon Sep 17 00:00:00 2001 From: Konstantin Vukolov Date: Tue, 20 Jan 2026 16:27:45 +0300 Subject: [PATCH] Change opds parser interface --- lib/OpdsParser/OpdsParser.cpp | 17 +++++++++++------ lib/OpdsParser/OpdsParser.h | 14 +++++++++++--- lib/OpdsParser/OpdsStream.cpp | 8 +++----- .../browser/OpdsBookBrowserActivity.cpp | 4 ++-- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/lib/OpdsParser/OpdsParser.cpp b/lib/OpdsParser/OpdsParser.cpp index c95d295..7c3f309 100644 --- a/lib/OpdsParser/OpdsParser.cpp +++ b/lib/OpdsParser/OpdsParser.cpp @@ -22,9 +22,14 @@ OpdsParser::~OpdsParser() { } } -void OpdsParser::push(const char* xmlData, const size_t length) { +size_t OpdsParser::write(uint8_t c) { + return write(&c, 1); +} + +size_t OpdsParser::write(const uint8_t* xmlData, const size_t length) { + Serial.printf("Got %d bytes to parse\n", length); if (errorOccured) { - return; + return length; } XML_SetUserData(parser, this); @@ -32,7 +37,7 @@ void OpdsParser::push(const char* xmlData, const size_t length) { XML_SetCharacterDataHandler(parser, characterData); // Parse in chunks to avoid large buffer allocations - const char* currentPos = xmlData; + const char* currentPos = reinterpret_cast(xmlData); size_t remaining = length; constexpr size_t chunkSize = 1024; @@ -43,7 +48,7 @@ void OpdsParser::push(const char* xmlData, const size_t length) { Serial.printf("[%lu] [OPDS] Couldn't allocate memory for buffer\n", millis()); XML_ParserFree(parser); parser = nullptr; - return; + return length; } const size_t toRead = remaining < chunkSize ? remaining : chunkSize; @@ -55,7 +60,7 @@ void OpdsParser::push(const char* xmlData, const size_t length) { XML_ErrorString(XML_GetErrorCode(parser))); XML_ParserFree(parser); parser = nullptr; - return; + return length; } currentPos += toRead; @@ -63,7 +68,7 @@ void OpdsParser::push(const char* xmlData, const size_t length) { } } -void OpdsParser::finish() { +void OpdsParser::flush() { if (XML_Parse(parser, nullptr, 0, XML_TRUE) != XML_STATUS_OK) { errorOccured = true; XML_ParserFree(parser); diff --git a/lib/OpdsParser/OpdsParser.h b/lib/OpdsParser/OpdsParser.h index 5d50836..aa898f7 100644 --- a/lib/OpdsParser/OpdsParser.h +++ b/lib/OpdsParser/OpdsParser.h @@ -3,6 +3,7 @@ #include #include +#include "Print.h" /** * Type of OPDS entry. @@ -42,7 +43,7 @@ using OpdsBook = OpdsEntry; * } * } */ -class OpdsParser { +class OpdsParser final : public Print { public: OpdsParser(); ~OpdsParser(); @@ -51,10 +52,17 @@ class OpdsParser { OpdsParser(const OpdsParser&) = delete; OpdsParser& operator=(const OpdsParser&) = delete; - void push(const char* xmlData, size_t length); - void finish(); + size_t write(uint8_t) override; + size_t write(const uint8_t*, size_t) override; + + void flush() override; + bool error() const; + operator bool() { + return !error(); + } + /** * Get the parsed entries (both navigation and book entries). * @return Vector of OpdsEntry entries diff --git a/lib/OpdsParser/OpdsStream.cpp b/lib/OpdsParser/OpdsStream.cpp index 68a2676..8fa9a0e 100644 --- a/lib/OpdsParser/OpdsStream.cpp +++ b/lib/OpdsParser/OpdsStream.cpp @@ -9,13 +9,11 @@ int OpdsParserStream::peek() { abort(); } int OpdsParserStream::read() { abort(); } size_t OpdsParserStream::write(uint8_t c) { - parser.push(reinterpret_cast(&c), 1); - return 1; + return parser.write(c); } size_t OpdsParserStream::write(const uint8_t* buffer, size_t size) { - parser.push(reinterpret_cast(buffer), size); - return size; + return parser.write(buffer, size); } -OpdsParserStream::~OpdsParserStream() { parser.finish(); } +OpdsParserStream::~OpdsParserStream() { parser.flush(); } diff --git a/src/activities/browser/OpdsBookBrowserActivity.cpp b/src/activities/browser/OpdsBookBrowserActivity.cpp index 104eaac..8eb83aa 100644 --- a/src/activities/browser/OpdsBookBrowserActivity.cpp +++ b/src/activities/browser/OpdsBookBrowserActivity.cpp @@ -17,7 +17,7 @@ namespace { constexpr int PAGE_ITEMS = 23; constexpr int SKIP_PAGE_MS = 700; -constexpr char OPDS_ROOT_PATH[] = "opds"; // No leading slash - relative to server URL +constexpr char OPDS_ROOT_PATH[] = "api/opds/c7f8522c-5539-4f60-b978-3626a33245b6"; // No leading slash - relative to server URL } // namespace void OpdsBookBrowserActivity::taskTrampoline(void* param) { @@ -277,7 +277,7 @@ void OpdsBookBrowserActivity::fetchFeed(const std::string& path) { } } - if (parser.error()) { + if (!parser) { state = BrowserState::ERROR; errorMessage = "Failed to parse feed"; updateRequired = true;