A fork of https://github.com/crosspoint-reader/crosspoint-reader
1#pragma once
2#include <Print.h>
3#include <expat.h>
4
5#include <string>
6#include <vector>
7
8/**
9 * Type of OPDS entry.
10 */
11enum class OpdsEntryType {
12 NAVIGATION, // Link to another catalog
13 BOOK // Downloadable book
14};
15
16/**
17 * Represents an entry from an OPDS feed (either a navigation link or a book).
18 */
19struct OpdsEntry {
20 OpdsEntryType type = OpdsEntryType::NAVIGATION;
21 std::string title;
22 std::string author; // Only for books
23 std::string href; // Navigation URL or epub download URL
24 std::string id;
25};
26
27// Legacy alias for backward compatibility
28using OpdsBook = OpdsEntry;
29
30/**
31 * Parser for OPDS (Open Publication Distribution System) Atom feeds.
32 * Uses the Expat XML parser to parse OPDS catalog entries.
33 *
34 * Usage:
35 * OpdsParser parser;
36 * if (parser.parse(xmlData, xmlLength)) {
37 * for (const auto& entry : parser.getEntries()) {
38 * if (entry.type == OpdsEntryType::BOOK) {
39 * // Downloadable book
40 * } else {
41 * // Navigation link to another catalog
42 * }
43 * }
44 * }
45 */
46class OpdsParser final : public Print {
47 public:
48 OpdsParser();
49 ~OpdsParser();
50
51 // Disable copy
52 const std::string& getSearchTemplate() const { return searchTemplate; }
53 const std::string& getNextPageUrl() const { return nextPageUrl; }
54 const std::string& getPrevPageUrl() const { return prevPageUrl; }
55 OpdsParser(const OpdsParser&) = delete;
56 OpdsParser& operator=(const OpdsParser&) = delete;
57
58 size_t write(uint8_t) override;
59 size_t write(const uint8_t*, size_t) override;
60
61 void flush() override;
62
63 bool error() const;
64
65 operator bool() { return !error(); }
66
67 /**
68 * Get the parsed entries (both navigation and book entries).
69 * @return Vector of OpdsEntry entries
70 */
71 const std::vector<OpdsEntry>& getEntries() const& { return entries; }
72 std::vector<OpdsEntry> getEntries() && { return std::move(entries); }
73
74 /**
75 * Get only book entries (legacy compatibility).
76 * @return Vector of book entries
77 */
78 std::vector<OpdsEntry> getBooks() const;
79
80 /**
81 * Clear all parsed entries.
82 */
83 void clear();
84
85 private:
86 // Expat callbacks
87 static void XMLCALL startElement(void* userData, const XML_Char* name, const XML_Char** atts);
88 static void XMLCALL endElement(void* userData, const XML_Char* name);
89 static void XMLCALL characterData(void* userData, const XML_Char* s, int len);
90
91 std::string searchTemplate;
92 std::string nextPageUrl;
93 std::string prevPageUrl;
94 // Helper to find attribute value
95 static const char* findAttribute(const XML_Char** atts, const char* name);
96
97 XML_Parser parser = nullptr;
98 std::vector<OpdsEntry> entries;
99 OpdsEntry currentEntry;
100 std::string currentText;
101
102 // Parser state
103 bool inEntry = false;
104 bool inTitle = false;
105 bool inAuthor = false;
106 bool inAuthorName = false;
107 bool inId = false;
108
109 bool errorOccured = false;
110};