#include "TocNavParser.h" #include #include #include "../BookMetadataCache.h" bool TocNavParser::setup() { parser = XML_ParserCreate(nullptr); if (!parser) { Serial.printf("[%lu] [NAV] Couldn't allocate memory for parser\n", millis()); return false; } XML_SetUserData(parser, this); XML_SetElementHandler(parser, startElement, endElement); XML_SetCharacterDataHandler(parser, characterData); return true; } TocNavParser::~TocNavParser() { if (parser) { XML_StopParser(parser, XML_FALSE); XML_SetElementHandler(parser, nullptr, nullptr); XML_SetCharacterDataHandler(parser, nullptr); XML_ParserFree(parser); parser = nullptr; } } size_t TocNavParser::write(const uint8_t data) { return write(&data, 1); } size_t TocNavParser::write(const uint8_t* buffer, const size_t size) { if (!parser) return 0; const uint8_t* currentBufferPos = buffer; auto remainingInBuffer = size; while (remainingInBuffer > 0) { void* const buf = XML_GetBuffer(parser, 1024); if (!buf) { Serial.printf("[%lu] [NAV] Couldn't allocate memory for buffer\n", millis()); XML_StopParser(parser, XML_FALSE); XML_SetElementHandler(parser, nullptr, nullptr); XML_SetCharacterDataHandler(parser, nullptr); XML_ParserFree(parser); parser = nullptr; return 0; } const auto toRead = remainingInBuffer < 1024 ? remainingInBuffer : 1024; memcpy(buf, currentBufferPos, toRead); if (XML_ParseBuffer(parser, static_cast(toRead), remainingSize == toRead) == XML_STATUS_ERROR) { Serial.printf("[%lu] [NAV] Parse error at line %lu: %s\n", millis(), XML_GetCurrentLineNumber(parser), XML_ErrorString(XML_GetErrorCode(parser))); XML_StopParser(parser, XML_FALSE); XML_SetElementHandler(parser, nullptr, nullptr); XML_SetCharacterDataHandler(parser, nullptr); XML_ParserFree(parser); parser = nullptr; return 0; } currentBufferPos += toRead; remainingInBuffer -= toRead; remainingSize -= toRead; } return size; } void XMLCALL TocNavParser::startElement(void* userData, const XML_Char* name, const XML_Char** atts) { auto* self = static_cast(userData); // Track HTML structure loosely - we mainly care about finding