diff --git a/lib/xml/xmlparser.cpp b/lib/xml/xmlparser.cpp index bf77afa..b6a000e 100644 --- a/lib/xml/xmlparser.cpp +++ b/lib/xml/xmlparser.cpp @@ -5,9 +5,9 @@ #include #include -#include #include #include +#include #include #include @@ -69,13 +69,18 @@ std::string getElementText(DOMElement* Element) return trimCopy(Value); } -std::generator iterateElementChildren(DOMElement* Parent) +template +void iterateElementChildren(DOMElement* Parent, Callback&& Handler) { + static_assert( + std::is_void_v>, + "iterateElementChildren callback must return void" + ); DOMNodeList* Children = Parent->getChildNodes(); for (XMLSize_t Index = 0; Index < Children->getLength(); ++Index) { DOMNode* Child = Children->item(Index); if (Child->getNodeType() == DOMNode::ELEMENT_NODE) { - co_yield static_cast(Child); + Handler(static_cast(Child)); } } } @@ -85,7 +90,8 @@ struct MessageSlice std::string_view Slice; }; -std::generator splitMessages(std::string_view Input, bool& FramingError) +template +void splitMessages(std::string_view Input, bool& FramingError, Callback&& Handler) { std::size_t Cursor = 0; std::size_t LastEnd = std::string_view::npos; @@ -98,7 +104,7 @@ std::generator splitMessages(std::string_view Input, bool& Framing if (LastEnd != std::string_view::npos && Start != LastEnd) { FramingError = true; - co_return; + return; } const std::size_t End = Input.find(NLAP_XML_END_MARKER, Start); @@ -107,7 +113,10 @@ std::generator splitMessages(std::string_view Input, bool& Framing } const std::size_t MessageEnd = End + NLAP_XML_END_MARKER.size(); - co_yield MessageSlice{Input.substr(Start, MessageEnd - Start)}; + // Handler must return true to continue iterating and false to stop. + if (!Handler(MessageSlice{Input.substr(Start, MessageEnd - Start)})) { + return; + } Cursor = MessageEnd; LastEnd = MessageEnd; @@ -197,12 +206,12 @@ void populateTree(DOMElement* Element, XMLNode& Node, std::string_view RawMessag { bool HasElementChildren = false; - for (DOMElement* Child : iterateElementChildren(Element)) { + iterateElementChildren(Element, [&](DOMElement* Child) { HasElementChildren = true; const std::string ChildName = transcodeXMLCh(Child->getTagName()); XMLNode& ChildNode = Node[ChildName]; populateTree(Child, ChildNode, RawMessage, SearchOffset); - } + }); if (HasElementChildren) { return; @@ -297,11 +306,11 @@ uint16_t parseMessage( XMLNode& RootNode = OutputTree[RootName]; std::size_t SearchOffset = 0; - for (DOMElement* Child : iterateElementChildren(Root)) { + iterateElementChildren(Root, [&](DOMElement* Child) { const std::string ChildName = transcodeXMLCh(Child->getTagName()); XMLNode& ChildNode = RootNode[ChildName]; populateTree(Child, ChildNode, RawMessage, SearchOffset); - } + }); return 0; } @@ -372,17 +381,24 @@ ParseResult_t XMLParser::parse(char* InputBuffer) const } bool FramingError = false; - for (const MessageSlice& Slice : splitMessages(InputBufferSV, FramingError)) { + bool HasMessageError = false; + splitMessages(InputBufferSV, FramingError, [&](const MessageSlice& Slice) { ResultTree_t Tree; const uint16_t MessageError = parseMessage(_GrammarPool, Slice.Slice, Tree); if (MessageError != 0) { Result.ErrorCode = MessageError; Result.Results.clear(); - return Result; + HasMessageError = true; + return false; } Result.Results.push_back(std::move(Tree)); + return true; + }); + + if (HasMessageError) { + return Result; } if (FramingError) {