MCPcopy Create free account
hub / github.com/crosspoint-reader/crosspoint-reader / startElement

Method startElement

lib/OpdsParser/OpdsParser.cpp:90–153  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

88}
89
90void XMLCALL OpdsParser::startElement(void* userData, const XML_Char* name, const XML_Char** atts) {
91 auto* self = static_cast<OpdsParser*>(userData);
92
93 if (strcmp(name, "link") == 0 || strstr(name, ":link") != nullptr) {
94 const char* href = findAttribute(atts, "href");
95 if (href) {
96 const char* rel = findAttribute(atts, "rel");
97 const char* type = findAttribute(atts, "type");
98
99 if (rel && strcmp(rel, "search") == 0) {
100 std::string sHref(href);
101 if (sHref.find("{searchTerms}") != std::string::npos) {
102 self->searchTemplate = sHref;
103 }
104 } else if (rel && strcmp(rel, "next") == 0 && !self->inEntry) {
105 self->nextPageUrl = href;
106 } else if (rel && strcmp(rel, "previous") == 0 && !self->inEntry) {
107 self->prevPageUrl = href;
108 }
109
110 if (self->inEntry) {
111 if (rel && type && strstr(rel, "opds-spec.org/acquisition") != nullptr &&
112 strcmp(type, "application/epub+zip") == 0) {
113 // Prefer plain EPUB links over derived formats when multiple
114 // acquisition links are present for one entry.
115 const bool isPlainEpub = strstr(href, ".epub") != nullptr || strstr(href, "/epub/") != nullptr;
116 const bool alreadyHasPlainEpub = self->currentEntry.type == OpdsEntryType::BOOK &&
117 (self->currentEntry.href.find(".epub") != std::string::npos ||
118 self->currentEntry.href.find("/epub/") != std::string::npos);
119 if (self->currentEntry.type != OpdsEntryType::BOOK || (isPlainEpub && !alreadyHasPlainEpub)) {
120 self->currentEntry.type = OpdsEntryType::BOOK;
121 self->currentEntry.href = href;
122 }
123 } else if (type && strstr(type, "application/atom+xml") != nullptr) {
124 if (self->currentEntry.type != OpdsEntryType::BOOK) {
125 self->currentEntry.type = OpdsEntryType::NAVIGATION;
126 self->currentEntry.href = href;
127 }
128 }
129 }
130 }
131 }
132
133 if (strcmp(name, "entry") == 0 || strstr(name, ":entry") != nullptr) {
134 self->inEntry = true;
135 self->currentEntry = OpdsEntry{};
136 return;
137 }
138
139 if (!self->inEntry) return;
140
141 if (strcmp(name, "title") == 0 || strstr(name, ":title") != nullptr) {
142 self->inTitle = true;
143 self->currentText.clear();
144 } else if (strcmp(name, "author") == 0 || strstr(name, ":author") != nullptr) {
145 self->inAuthor = true;
146 } else if (self->inAuthor && (strcmp(name, "name") == 0 || strstr(name, ":name") != nullptr)) {
147 self->inAuthorName = true;

Callers

nothing calls this directly

Calls 1

clearMethod · 0.45

Tested by

no test coverage detected