diff options
Diffstat (limited to 'Swiften/Serializer/XML')
-rw-r--r-- | Swiften/Serializer/XML/Makefile.inc | 5 | ||||
-rw-r--r-- | Swiften/Serializer/XML/UnitTest/Makefile.inc | 2 | ||||
-rw-r--r-- | Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp | 62 | ||||
-rw-r--r-- | Swiften/Serializer/XML/XMLElement.cpp | 49 | ||||
-rw-r--r-- | Swiften/Serializer/XML/XMLElement.h | 27 | ||||
-rw-r--r-- | Swiften/Serializer/XML/XMLNode.cpp | 8 | ||||
-rw-r--r-- | Swiften/Serializer/XML/XMLNode.h | 15 | ||||
-rw-r--r-- | Swiften/Serializer/XML/XMLRawTextNode.h | 21 | ||||
-rw-r--r-- | Swiften/Serializer/XML/XMLTextNode.h | 23 |
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=\"<"'&>\"/>"), 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('&', "&"); + escapedValue.replaceAll('<', "<"); + escapedValue.replaceAll('>', ">"); + escapedValue.replaceAll('\'', "'"); + escapedValue.replaceAll('"', """); + 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('&', "&"); // Should come first + text_.replaceAll('<', "<"); + } + + String serialize() { + return text_; + } + + private: + String text_; + }; +} + +#endif |