aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-01-02 18:59:43 +0800
committercrupest <crupest@outlook.com>2022-01-02 18:59:43 +0800
commitda3098abe8377a4b7e1d5b00e41af48cccc5696e (patch)
tree4caf637eb71ea4f4e98d96e6abb8127ffde6ac3d
parent18099ad8f5c24b1c2b1c92238dbc54912eab0406 (diff)
downloadcru-da3098abe8377a4b7e1d5b00e41af48cccc5696e.tar.gz
cru-da3098abe8377a4b7e1d5b00e41af48cccc5696e.tar.bz2
cru-da3098abe8377a4b7e1d5b00e41af48cccc5696e.zip
...
-rw-r--r--include/cru/xml/XmlNode.hpp10
-rw-r--r--src/xml/XmlNode.cpp15
-rw-r--r--test/xml/ParserTest.cpp92
3 files changed, 56 insertions, 61 deletions
diff --git a/include/cru/xml/XmlNode.hpp b/include/cru/xml/XmlNode.hpp
index 186f395c..cf2543c9 100644
--- a/include/cru/xml/XmlNode.hpp
+++ b/include/cru/xml/XmlNode.hpp
@@ -8,6 +8,7 @@
namespace cru::xml {
class XmlElementNode;
+class XmlTextNode;
class XmlNode {
friend XmlElementNode;
@@ -29,6 +30,11 @@ class XmlNode {
virtual XmlNode* Clone() const = 0;
+ XmlElementNode* AsElement();
+ XmlTextNode* AsText();
+ const XmlElementNode* AsElement() const;
+ const XmlTextNode* AsText() const;
+
private:
const Type type_;
XmlElementNode* parent_ = nullptr;
@@ -80,6 +86,10 @@ class XmlElementNode : public XmlNode {
}
const std::vector<XmlNode*> GetChildren() const { return children_; }
+ int GetChildCount() const { return children_.size(); }
+ String GetAttribute(const String& key) const { return attributes_.at(key); }
+ XmlNode* GetChildAt(int index) const { return children_[index]; }
+
void AddAttribute(String key, String value);
void AddChild(XmlNode* child);
diff --git a/src/xml/XmlNode.cpp b/src/xml/XmlNode.cpp
index d6203973..51a861fa 100644
--- a/src/xml/XmlNode.cpp
+++ b/src/xml/XmlNode.cpp
@@ -1,6 +1,21 @@
#include "cru/xml/XmlNode.hpp"
namespace cru::xml {
+
+XmlElementNode* XmlNode::AsElement() {
+ return static_cast<XmlElementNode*>(this);
+}
+
+XmlTextNode* XmlNode::AsText() { return static_cast<XmlTextNode*>(this); }
+
+const XmlElementNode* XmlNode::AsElement() const {
+ return static_cast<const XmlElementNode*>(this);
+}
+
+const XmlTextNode* XmlNode::AsText() const {
+ return static_cast<const XmlTextNode*>(this);
+}
+
XmlElementNode::~XmlElementNode() {
for (auto child : children_) {
delete child;
diff --git a/test/xml/ParserTest.cpp b/test/xml/ParserTest.cpp
index 01098b7c..238ea507 100644
--- a/test/xml/ParserTest.cpp
+++ b/test/xml/ParserTest.cpp
@@ -10,7 +10,7 @@ TEST(CruXmlParserTest, Simple) {
auto n = parser.Parse();
ASSERT_EQ(n->GetTag(), u"root");
ASSERT_EQ(n->GetAttributes().empty(), true);
- ASSERT_EQ(n->GetChildren().size(), 0);
+ ASSERT_EQ(n->GetChildCount(), 0);
delete n;
}
@@ -18,9 +18,9 @@ TEST(CruXmlParserTest, SimpleWithAttribute) {
XmlParser parser(u"<root a1=\"v1\" a2=\"v2\"></root>");
auto n = parser.Parse();
ASSERT_EQ(n->GetTag(), u"root");
- ASSERT_EQ(n->GetAttributes().at(u"a1"), u"v1");
- ASSERT_EQ(n->GetAttributes().at(u"a2"), u"v2");
- ASSERT_EQ(n->GetChildren().size(), 0);
+ ASSERT_EQ(n->GetAttribute(u"a1"), u"v1");
+ ASSERT_EQ(n->GetAttribute(u"a2"), u"v2");
+ ASSERT_EQ(n->GetChildCount(), 0);
delete n;
}
@@ -28,9 +28,9 @@ TEST(CruXmlParserTest, SimpleSelfClosing) {
XmlParser parser(u"<root a1=\"v1\" a2=\"v2\"/>");
auto n = parser.Parse();
ASSERT_EQ(n->GetTag(), u"root");
- ASSERT_EQ(n->GetAttributes().at(u"a1"), u"v1");
- ASSERT_EQ(n->GetAttributes().at(u"a2"), u"v2");
- ASSERT_EQ(n->GetChildren().size(), 0);
+ ASSERT_EQ(n->GetAttribute(u"a1"), u"v1");
+ ASSERT_EQ(n->GetAttribute(u"a2"), u"v2");
+ ASSERT_EQ(n->GetChildCount(), 0);
delete n;
}
@@ -39,35 +39,15 @@ TEST(CruXmlParserTest, NestedElement) {
u"<root><c1><d1></d1></c1><c2><d2></d2><d3></d3></c2></root>");
auto n = parser.Parse();
ASSERT_EQ(n->GetChildren().size(), 2);
- ASSERT_EQ(static_cast<XmlElementNode*>(n->GetChildren().at(0))->GetTag(),
- u"c1");
- ASSERT_EQ(static_cast<XmlElementNode*>(n->GetChildren().at(1))->GetTag(),
- u"c2");
- ASSERT_EQ(static_cast<XmlElementNode*>(n->GetChildren().at(0))
- ->GetChildren()
- .size(),
- 1);
- ASSERT_EQ(static_cast<XmlElementNode*>(
- static_cast<XmlElementNode*>(n->GetChildren().at(0))
- ->GetChildren()
- .at(0))
- ->GetTag(),
+ ASSERT_EQ(n->GetChildAt(0)->AsElement()->GetTag(), u"c1");
+ ASSERT_EQ(n->GetChildAt(1)->AsElement()->GetTag(), u"c2");
+ ASSERT_EQ(n->GetChildAt(0)->AsElement()->GetChildCount(), 1);
+ ASSERT_EQ(n->GetChildAt(0)->AsElement()->GetChildAt(0)->AsElement()->GetTag(),
u"d1");
- ASSERT_EQ(static_cast<XmlElementNode*>(n->GetChildren().at(1))
- ->GetChildren()
- .size(),
- 2);
- ASSERT_EQ(static_cast<XmlElementNode*>(
- static_cast<XmlElementNode*>(n->GetChildren().at(1))
- ->GetChildren()
- .at(0))
- ->GetTag(),
+ ASSERT_EQ(n->GetChildAt(1)->AsElement()->GetChildCount(), 2);
+ ASSERT_EQ(n->GetChildAt(1)->AsElement()->GetChildAt(0)->AsElement()->GetTag(),
u"d2");
- ASSERT_EQ(static_cast<XmlElementNode*>(
- static_cast<XmlElementNode*>(n->GetChildren().at(1))
- ->GetChildren()
- .at(1))
- ->GetTag(),
+ ASSERT_EQ(n->GetChildAt(1)->AsElement()->GetChildAt(1)->AsElement()->GetTag(),
u"d3");
delete n;
}
@@ -75,18 +55,16 @@ TEST(CruXmlParserTest, NestedElement) {
TEST(CruXmlParserTest, SimpleText) {
XmlParser parser(u"<root>text</root>");
auto n = parser.Parse();
- ASSERT_EQ(n->GetChildren().size(), 1);
- ASSERT_EQ(static_cast<XmlTextNode*>(n->GetChildren().at(0))->GetText(),
- u"text");
+ ASSERT_EQ(n->GetChildCount(), 1);
+ ASSERT_EQ(n->GetChildAt(0)->AsText()->GetText(), u"text");
delete n;
}
TEST(CruXmlParserTest, Whitespace) {
XmlParser parser(u"\t\t<root>\n\t\t\ttext test\n\t\t</root>\t\t");
auto n = parser.Parse();
- ASSERT_EQ(n->GetChildren().size(), 1);
- ASSERT_EQ(static_cast<XmlTextNode*>(n->GetChildren().at(0))->GetText(),
- u"text test");
+ ASSERT_EQ(n->GetChildCount(), 1);
+ ASSERT_EQ(n->GetChildAt(0)->AsText()->GetText(), u"text test");
delete n;
}
@@ -108,28 +86,20 @@ TEST(CruXmlParserTest, Complex) {
</root>
)");
auto n = parser.Parse();
- ASSERT_EQ(n->GetAttributes().at(u"a1"), u"v1");
- ASSERT_EQ(n->GetChildren().size(), 2);
- ASSERT_EQ(static_cast<XmlElementNode*>(n->GetChildren().at(0))->GetTag(),
- u"c1");
- ASSERT_EQ(static_cast<XmlElementNode*>(n->GetChildren().at(0))
- ->GetChildren()
- .size(),
- 1);
- auto c2 = static_cast<XmlElementNode*>(n->GetChildren().at(1));
+ ASSERT_EQ(n->GetAttribute(u"a1"), u"v1");
+ ASSERT_EQ(n->GetChildCount(), 2);
+ ASSERT_EQ(n->GetChildAt(0)->AsElement()->GetTag(), u"c1");
+ ASSERT_EQ(n->GetChildAt(0)->AsElement()->GetChildCount(), 1);
+ auto c2 = n->GetChildAt(1)->AsElement();
ASSERT_EQ(c2->GetTag(), u"c2");
- ASSERT_EQ(c2->GetAttributes().at(u"a2"), u"v2");
- ASSERT_EQ(c2->GetAttributes().at(u"a3"), u"v3");
- ASSERT_EQ(static_cast<XmlTextNode*>(c2->GetChildren().at(0))->GetText(),
- u"t1");
- auto d2 = static_cast<XmlElementNode*>(c2->GetChildren().at(1));
+ ASSERT_EQ(c2->GetAttribute(u"a2"), u"v2");
+ ASSERT_EQ(c2->GetAttribute(u"a3"), u"v3");
+ ASSERT_EQ(c2->GetChildAt(0)->AsText()->GetText(), u"t1");
+ auto d2 = c2->GetChildAt(1)->AsElement();
ASSERT_EQ(d2->GetTag(), u"d2");
- ASSERT_EQ(d2->GetAttributes().at(u"a4"), u"v4");
- ASSERT_EQ(static_cast<XmlTextNode*>(c2->GetChildren().at(2))->GetText(),
- u"text test");
- ASSERT_EQ(static_cast<XmlElementNode*>(c2->GetChildren().at(3))->GetTag(),
- u"d3");
- ASSERT_EQ(static_cast<XmlTextNode*>(c2->GetChildren().at(4))->GetText(),
- u"t2");
+ ASSERT_EQ(d2->GetAttribute(u"a4"), u"v4");
+ ASSERT_EQ(c2->GetChildAt(2)->AsText()->GetText(), u"text test");
+ ASSERT_EQ(c2->GetChildAt(3)->AsElement()->GetTag(), u"d3");
+ ASSERT_EQ(c2->GetChildAt(4)->AsText()->GetText(), u"t2");
delete n;
}