summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Serializer/XML')
-rw-r--r--Swiften/Serializer/XML/Makefile.inc5
-rw-r--r--Swiften/Serializer/XML/UnitTest/Makefile.inc2
-rw-r--r--Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp62
-rw-r--r--Swiften/Serializer/XML/XMLElement.cpp49
-rw-r--r--Swiften/Serializer/XML/XMLElement.h27
-rw-r--r--Swiften/Serializer/XML/XMLNode.cpp8
-rw-r--r--Swiften/Serializer/XML/XMLNode.h15
-rw-r--r--Swiften/Serializer/XML/XMLRawTextNode.h21
-rw-r--r--Swiften/Serializer/XML/XMLTextNode.h23
9 files changed, 212 insertions, 0 deletions
diff --git a/Swiften/Serializer/XML/Makefile.inc b/Swiften/Serializer/XML/Makefile.inc
new file mode 100644
index 0000000..6daca82
--- /dev/null
+++ b/Swiften/Serializer/XML/Makefile.inc
@@ -0,0 +1,5 @@
+SWIFTEN_SOURCES += \
+ Swiften/Serializer/XML/XMLNode.cpp \
+ Swiften/Serializer/XML/XMLElement.cpp
+
+include Swiften/Serializer/XML/UnitTest/Makefile.inc
diff --git a/Swiften/Serializer/XML/UnitTest/Makefile.inc b/Swiften/Serializer/XML/UnitTest/Makefile.inc
new file mode 100644
index 0000000..fa00b76
--- /dev/null
+++ b/Swiften/Serializer/XML/UnitTest/Makefile.inc
@@ -0,0 +1,2 @@
+UNITTEST_SOURCES += \
+ Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp
diff --git a/Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp b/Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp
new file mode 100644
index 0000000..49eb109
--- /dev/null
+++ b/Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp
@@ -0,0 +1,62 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/XML/XMLElement.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+
+using namespace Swift;
+
+class XMLElementTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(XMLElementTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST(testSerialize_NoChildren);
+ CPPUNIT_TEST(testSerialize_SpecialAttributeCharacters);
+ CPPUNIT_TEST(testSerialize_EmptyAttributeValue);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ XMLElementTest() {}
+
+ void testSerialize() {
+ XMLElement testling("foo", "http://example.com");
+ testling.setAttribute("myatt", "myval");
+ boost::shared_ptr<XMLElement> barElement(new XMLElement("bar"));
+ barElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode("Blo")));
+ testling.addNode(barElement);
+ boost::shared_ptr<XMLElement> bazElement(new XMLElement("baz"));
+ bazElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode("Bli")));
+ testling.addNode(bazElement);
+
+ String result = testling.serialize();
+ String expectedResult =
+ "<foo myatt=\"myval\" xmlns=\"http://example.com\">"
+ "<bar>Blo</bar>"
+ "<baz>Bli</baz>"
+ "</foo>";
+
+ CPPUNIT_ASSERT_EQUAL(expectedResult, result);
+ }
+
+ void testSerialize_NoChildren() {
+ XMLElement testling("foo", "http://example.com");
+
+ CPPUNIT_ASSERT_EQUAL(String("<foo xmlns=\"http://example.com\"/>"), testling.serialize());
+ }
+
+ void testSerialize_SpecialAttributeCharacters() {
+ XMLElement testling("foo");
+ testling.setAttribute("myatt", "<\"'&>");
+
+ CPPUNIT_ASSERT_EQUAL(String("<foo myatt=\"&lt;&quot;&apos;&amp;&gt;\"/>"), testling.serialize());
+ }
+
+ void testSerialize_EmptyAttributeValue() {
+ XMLElement testling("foo");
+ testling.setAttribute("myatt", "");
+
+ CPPUNIT_ASSERT_EQUAL(String("<foo myatt=\"\"/>"), testling.serialize());
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(XMLElementTest);
diff --git a/Swiften/Serializer/XML/XMLElement.cpp b/Swiften/Serializer/XML/XMLElement.cpp
new file mode 100644
index 0000000..af2cb34
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLElement.cpp
@@ -0,0 +1,49 @@
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+#include "Swiften/Base/foreach.h"
+
+namespace Swift {
+
+XMLElement::XMLElement(const String& tag, const String& xmlns) :
+ tag_(tag) {
+ if (!xmlns.isEmpty()) {
+ setAttribute("xmlns", xmlns);
+ }
+}
+
+String XMLElement::serialize() {
+ String result;
+ result += "<" + tag_;
+ typedef std::pair<String,String> Pair;
+ foreach(const Pair& p, attributes_) {
+ result += " " + p.first + "=\"" + p.second + "\"";
+ }
+
+ if (childNodes_.size() > 0) {
+ result += ">";
+ foreach (boost::shared_ptr<XMLNode> node, childNodes_) {
+ result += node->serialize();
+ }
+ result += "</" + tag_ + ">";
+ }
+ else {
+ result += "/>";
+ }
+ return result;
+}
+
+void XMLElement::setAttribute(const String& attribute, const String& value) {
+ String escapedValue(value);
+ escapedValue.replaceAll('&', "&amp;");
+ escapedValue.replaceAll('<', "&lt;");
+ escapedValue.replaceAll('>', "&gt;");
+ escapedValue.replaceAll('\'', "&apos;");
+ escapedValue.replaceAll('"', "&quot;");
+ attributes_[attribute] = escapedValue;
+}
+
+void XMLElement::addNode(boost::shared_ptr<XMLNode> node) {
+ childNodes_.push_back(node);
+}
+
+}
diff --git a/Swiften/Serializer/XML/XMLElement.h b/Swiften/Serializer/XML/XMLElement.h
new file mode 100644
index 0000000..f2eb8bf
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLElement.h
@@ -0,0 +1,27 @@
+#ifndef SWIFTEN_XMLElement_H
+#define SWIFTEN_XMLElement_H
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <map>
+
+#include "Swiften/Base/String.h"
+#include "Swiften/Serializer/XML/XMLNode.h"
+
+namespace Swift {
+ class XMLElement : public XMLNode {
+ public:
+ XMLElement(const String& tag, const String& xmlns = "");
+
+ void setAttribute(const String& attribute, const String& value);
+ void addNode(boost::shared_ptr<XMLNode> node);
+
+ virtual String serialize();
+
+ private:
+ String tag_;
+ std::map<String, String> attributes_;
+ std::vector< boost::shared_ptr<XMLNode> > childNodes_;
+ };
+}
+#endif
diff --git a/Swiften/Serializer/XML/XMLNode.cpp b/Swiften/Serializer/XML/XMLNode.cpp
new file mode 100644
index 0000000..1bef64a
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLNode.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/Serializer/XML/XMLNode.h"
+
+namespace Swift {
+
+XMLNode::~XMLNode() {
+}
+
+}
diff --git a/Swiften/Serializer/XML/XMLNode.h b/Swiften/Serializer/XML/XMLNode.h
new file mode 100644
index 0000000..b31c0d6
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLNode.h
@@ -0,0 +1,15 @@
+#ifndef SWIFTEN_XMLNode_H
+#define SWIFTEN_XMLNode_H
+
+#include "Swiften/Base/String.h"
+
+namespace Swift {
+ class XMLNode {
+ public:
+ virtual ~XMLNode();
+
+ virtual String serialize() = 0;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/XML/XMLRawTextNode.h b/Swiften/Serializer/XML/XMLRawTextNode.h
new file mode 100644
index 0000000..e5800c3
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLRawTextNode.h
@@ -0,0 +1,21 @@
+#ifndef SWIFTEN_XMLRawTextNode_H
+#define SWIFTEN_XMLRawTextNode_H
+
+#include "Swiften/Serializer/XML/XMLNode.h"
+
+namespace Swift {
+ class XMLRawTextNode : public XMLNode {
+ public:
+ XMLRawTextNode(const String& text) : text_(text) {
+ }
+
+ String serialize() {
+ return text_;
+ }
+
+ private:
+ String text_;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/XML/XMLTextNode.h b/Swiften/Serializer/XML/XMLTextNode.h
new file mode 100644
index 0000000..a142325
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLTextNode.h
@@ -0,0 +1,23 @@
+#ifndef SWIFTEN_XMLTextNode_H
+#define SWIFTEN_XMLTextNode_H
+
+#include "Swiften/Serializer/XML/XMLNode.h"
+
+namespace Swift {
+ class XMLTextNode : public XMLNode {
+ public:
+ XMLTextNode(const String& text) : text_(text) {
+ text_.replaceAll('&', "&amp;"); // Should come first
+ text_.replaceAll('<', "&lt;");
+ }
+
+ String serialize() {
+ return text_;
+ }
+
+ private:
+ String text_;
+ };
+}
+
+#endif