diff options
author | crupest <crupest@outlook.com> | 2022-01-01 01:28:21 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-01-01 01:28:21 +0800 |
commit | 96a93e17baaff2c2050eba2afada639e93001232 (patch) | |
tree | 4e1625c0004b711c0bcf5c774ad37b54e3975de1 /src/xml/XmlParser.cpp | |
parent | 4e92e8709b30c385e1a88d7d4f76c50ee4a3d736 (diff) | |
download | cru-96a93e17baaff2c2050eba2afada639e93001232.tar.gz cru-96a93e17baaff2c2050eba2afada639e93001232.tar.bz2 cru-96a93e17baaff2c2050eba2afada639e93001232.zip |
...
Diffstat (limited to 'src/xml/XmlParser.cpp')
-rw-r--r-- | src/xml/XmlParser.cpp | 114 |
1 files changed, 102 insertions, 12 deletions
diff --git a/src/xml/XmlParser.cpp b/src/xml/XmlParser.cpp index 23407d11..f24a7f68 100644 --- a/src/xml/XmlParser.cpp +++ b/src/xml/XmlParser.cpp @@ -1,27 +1,117 @@ #include "cru/xml/XmlParser.hpp" +#include "cru/xml/XmlNode.hpp" namespace cru::xml { -XmlNode XmlParser::Parse() { - if (!root_node_) { - root_node_ = DoParse(); +XmlElementNode* XmlParser::Parse() { + if (!cache_) { + cache_ = DoParse(); } - return *root_node_; + return static_cast<XmlElementNode*>(cache_->Clone()); } -XmlNode XmlParser::DoParse() { - XmlNode root(XmlNode::Type::Element); - XmlNode* current = &root; - int current_position = 0; +char16_t XmlParser::Read1() { + if (current_position_ >= xml_.size()) { + throw XmlParsingException(u"Unexpected end of xml"); + } + return xml_[current_position_++]; +} + +void XmlParser::ReadSpacesAndDiscard() { + while (current_position_ < xml_.size() && + (xml_[current_position_] == ' ' || xml_[current_position_] == '\t' || + xml_[current_position_] == '\n' || xml_[current_position_] == '\r')) { + ++current_position_; + } +} + +String XmlParser::ReadSpaces() { + String spaces; + while (current_position_ < xml_.size() && + (xml_[current_position_] == ' ' || xml_[current_position_] == '\t' || + xml_[current_position_] == '\n' || xml_[current_position_] == '\r')) { + spaces += xml_[current_position_]; + ++current_position_; + } + return spaces; +} + +String XmlParser::ReadIdenitifier() { + String identifier; + while (current_position_ < xml_.size() && + (xml_[current_position_] >= 'a' && xml_[current_position_] <= 'z' || + xml_[current_position_] >= 'A' && xml_[current_position_] <= 'Z' || + xml_[current_position_] >= '0' && xml_[current_position_] <= '9' || + xml_[current_position_] == '_')) { + identifier += xml_[current_position_]; + ++current_position_; + } + return identifier; +} + +String XmlParser::ReadAttributeString() { + if (Read1() != '"') { + throw XmlParsingException(u"Expected \"."); + } + + String string; + + while (true) { + char16_t c = Read1(); + + if (c == '"') { + break; + } + + string += c; + } + + return string; +} - // TODO: Implement this. - while (current_position < xml_.size()) { - switch (xml_[current_position]) { +XmlElementNode* XmlParser::DoParse() { + while (current_position_ < xml_.size()) { + switch (xml_[current_position_]) { case '<': { + ++current_position_; + + if (Read1() == '/') { + } else { + ReadSpacesAndDiscard(); + + String tag = ReadIdenitifier(); + + XmlElementNode* node = new XmlElementNode(tag); + + while (true) { + ReadSpacesAndDiscard(); + if (Read1() == '>') { + break; + } else { + String attribute_name = ReadIdenitifier(); + + ReadSpacesAndDiscard(); + + if (Read1() != '=') { + throw XmlParsingException(u"Expected '='"); + } + + ReadSpacesAndDiscard(); + + String attribute_value = ReadAttributeString(); + + node->AddAttribute(attribute_name, attribute_value); + } + } + + current_->AddChild(node); + current_ = node; + } + break; } } } - return root; + return pseudo_root_node_; } } // namespace cru::xml |