summaryrefslogtreecommitdiffstats
path: root/server/src/xml.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/xml.cpp')
-rw-r--r--server/src/xml.cpp94
1 files changed, 53 insertions, 41 deletions
diff --git a/server/src/xml.cpp b/server/src/xml.cpp
index cad42d1..c1b4358 100644
--- a/server/src/xml.cpp
+++ b/server/src/xml.cpp
@@ -9,53 +9,65 @@ import :xml;
9 9
10namespace routemon::xml { 10namespace routemon::xml {
11 11
12 auto qname_view::operator==(qname_view const& rhs) const -> bool { 12auto qname_view::operator==(qname_view const& rhs) const -> bool
13 return ns_uri == rhs.ns_uri && local == rhs.local; 13{
14 } 14 return ns_uri == rhs.ns_uri && local == rhs.local;
15}
15 16
16 executor::executor() : 17executor::executor() : p_{XML_ParserCreateNS("UTF-8", detail::qname_sep)}
17 p_{XML_ParserCreateNS("UTF-8", detail::qname_sep)} 18{
18 { 19 XML_SetUserData(p_, this);
19 XML_SetUserData(p_, this); 20 XML_SetElementHandler(p_, handle_start_element, handle_end_element);
20 XML_SetElementHandler(p_, handle_start_element, handle_end_element); 21 XML_SetCharacterDataHandler(p_, handle_character_data);
21 XML_SetCharacterDataHandler(p_, handle_character_data); 22 XML_SetProcessingInstructionHandler(p_, handle_processing_instructions);
22 XML_SetProcessingInstructionHandler(p_, handle_processing_instructions); 23 XML_SetExternalEntityRefHandler(p_, handle_external_entity_ref);
23 XML_SetExternalEntityRefHandler(p_, handle_external_entity_ref); 24 XML_SetNamespaceDeclHandler(
24 XML_SetNamespaceDeclHandler(p_, handle_start_namespace_decl, handle_end_namespace_decl); 25 p_, handle_start_namespace_decl, handle_end_namespace_decl);
25 XML_SetXmlDeclHandler(p_, handle_xml_decl); 26 XML_SetXmlDeclHandler(p_, handle_xml_decl);
26 } 27}
27 28
28 executor::~executor() { 29executor::~executor() { XML_ParserFree(p_); }
29 XML_ParserFree(p_);
30 }
31 30
32 auto executor::start() -> void { 31auto executor::start() -> void
33 continuation_.resume(); 32{
34 if (ex_) std::rethrow_exception(ex_); 33 continuation_.resume();
35 } 34 if (ex_)
35 std::rethrow_exception(ex_);
36}
36 37
37 auto executor::read(std::string_view xml, bool is_final) -> void { 38auto executor::read(std::string_view xml, bool is_final) -> void
38 if (ex_) 39{
39 throw std::runtime_error{"refusing to restart parser that was thrown in"}; 40 if (ex_)
40 // TODO: narrow_cast 41 throw std::runtime_error{"refusing to restart parser that was thrown in"};
41 if (auto s = XML_Parse(p_, xml.data(), static_cast<int>(xml.size()), is_final); s != XML_STATUS_OK) { 42 // TODO: narrow_cast
42 auto errc = XML_GetErrorCode(p_); 43 if (auto s =
43 if (errc == XML_ERROR_ABORTED) { 44 XML_Parse(p_, xml.data(), static_cast<int>(xml.size()), is_final);
44 assert(ex_); 45 s != XML_STATUS_OK)
45 std::rethrow_exception(ex_); 46 {
46 } else { 47 auto errc = XML_GetErrorCode(p_);
47 throw std::runtime_error{std::format("failed to parse XML: {}", XML_ErrorString(errc))}; 48 if (errc == XML_ERROR_ABORTED)
48 } 49 {
50 assert(ex_);
51 std::rethrow_exception(ex_);
52 }
53 else
54 {
55 throw std::runtime_error{std::format(
56 "failed to parse XML: {}", XML_ErrorString(errc))};
49 } 57 }
50 } 58 }
59}
51 60
52 auto executor::end() -> void { 61auto executor::end() -> void
53 if (ex_) 62{
54 throw std::runtime_error{"refusing to restart parser that was thrown in"}; 63 if (ex_)
55 ev_ = eof_event{}; 64 throw std::runtime_error{"refusing to restart parser that was thrown in"};
56 advance_ = false; 65 ev_ = eof_event{};
57 while (continuation_) continuation_.resume(); 66 advance_ = false;
58 if (ex_) std::rethrow_exception(ex_); 67 while (continuation_)
59 } 68 continuation_.resume();
69 if (ex_)
70 std::rethrow_exception(ex_);
71}
60 72
61} // namespace routemon::xml 73} // namespace routemon::xml