summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Parser/PayloadParsers')
-rw-r--r--Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp2
-rw-r--r--Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp43
-rw-r--r--Swiften/Parser/PayloadParsers/PrivateStorageParser.h25
-rw-r--r--Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h26
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp89
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp3
6 files changed, 186 insertions, 2 deletions
diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
index f4a7b9d..eb4cda0 100644
--- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
+++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
@@ -18,6 +18,7 @@
#include "Swiften/Parser/PayloadParsers/VCardUpdateParserFactory.h"
#include "Swiften/Parser/PayloadParsers/VCardParserFactory.h"
#include "Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h"
+#include "Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h"
using namespace boost;
@@ -39,6 +40,7 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() {
factories_.push_back(shared_ptr<PayloadParserFactory>(new SecurityLabelsCatalogParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new VCardUpdateParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new VCardParserFactory()));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new PrivateStorageParserFactory(this)));
foreach(shared_ptr<PayloadParserFactory> factory, factories_) {
addFactory(factory.get());
}
diff --git a/Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp b/Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp
new file mode 100644
index 0000000..5c3af26
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp
@@ -0,0 +1,43 @@
+#include "Swiften/Parser/PayloadParsers/PrivateStorageParser.h"
+#include "Swiften/Parser/PayloadParserFactoryCollection.h"
+#include "Swiften/Parser/PayloadParserFactory.h"
+
+namespace Swift {
+
+PrivateStorageParser::PrivateStorageParser(PayloadParserFactoryCollection* factories) : factories(factories), level(0) {
+}
+
+void PrivateStorageParser::handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) {
+ if (level == 1) {
+ PayloadParserFactory* payloadParserFactory = factories->getPayloadParserFactory(element, ns, attributes);
+ if (payloadParserFactory) {
+ currentPayloadParser.reset(payloadParserFactory->createPayloadParser());
+ }
+ }
+
+ if (level >= 1 && currentPayloadParser.get()) {
+ currentPayloadParser->handleStartElement(element, ns, attributes);
+ }
+ ++level;
+}
+
+void PrivateStorageParser::handleEndElement(const String& element, const String& ns) {
+ --level;
+ if (currentPayloadParser.get()) {
+ if (level >= 1) {
+ currentPayloadParser->handleEndElement(element, ns);
+ }
+
+ if (level == 1) {
+ getPayloadInternal()->setPayload(currentPayloadParser->getPayload());
+ }
+ }
+}
+
+void PrivateStorageParser::handleCharacterData(const String& data) {
+ if (level > 1 && currentPayloadParser.get()) {
+ currentPayloadParser->handleCharacterData(data);
+ }
+}
+
+}
diff --git a/Swiften/Parser/PayloadParsers/PrivateStorageParser.h b/Swiften/Parser/PayloadParsers/PrivateStorageParser.h
new file mode 100644
index 0000000..fae0f10
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/PrivateStorageParser.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <boost/optional.hpp>
+
+#include "Swiften/Elements/PrivateStorage.h"
+#include "Swiften/Parser/GenericPayloadParser.h"
+
+namespace Swift {
+ class PayloadParserFactoryCollection;
+
+ class PrivateStorageParser : public GenericPayloadParser<PrivateStorage> {
+ public:
+ PrivateStorageParser(PayloadParserFactoryCollection* factories);
+
+ private:
+ virtual void handleStartElement(const String& element, const String&, const AttributeMap& attributes);
+ virtual void handleEndElement(const String& element, const String&);
+ virtual void handleCharacterData(const String& data);
+
+ private:
+ PayloadParserFactoryCollection* factories;
+ int level;
+ std::auto_ptr<PayloadParser> currentPayloadParser;
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h b/Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h
new file mode 100644
index 0000000..4d9c02b
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "Swiften/Parser/PayloadParserFactory.h"
+#include "Swiften/Parser/PayloadParsers/PrivateStorageParser.h"
+
+namespace Swift {
+ class PayloadParserFactoryCollection;
+
+ class PrivateStorageParserFactory : public PayloadParserFactory {
+ public:
+ PrivateStorageParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) {
+ }
+
+ virtual bool canParse(const String& element, const String& ns, const AttributeMap&) const {
+ return element == "query" && ns == "jabber:iq:private";
+ }
+
+ virtual PayloadParser* createPayloadParser() {
+ return new PrivateStorageParser(factories);
+ }
+
+ private:
+ PayloadParserFactoryCollection* factories;
+
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp
new file mode 100644
index 0000000..e820083
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp
@@ -0,0 +1,89 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Elements/Storage.h"
+#include "Swiften/Parser/PayloadParsers/PrivateStorageParser.h"
+#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h"
+#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h"
+
+using namespace Swift;
+
+class PrivateStorageParserTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(PrivateStorageParserTest);
+ CPPUNIT_TEST(testParse);
+ CPPUNIT_TEST(testParse_NoPayload);
+ CPPUNIT_TEST(testParse_MultiplePayloads);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ PrivateStorageParserTest() {}
+
+ void testParse() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse(
+ "<query xmlns='jabber:iq:private'>"
+ "<storage xmlns='storage:bookmarks'>"
+ "<conference name='Swift' jid='swift@rooms.swift.im'>"
+ "<nick>Alice</nick>"
+ "</conference>"
+ "</storage>"
+ "</query>"));
+
+ boost::shared_ptr<PrivateStorage> payload = boost::dynamic_pointer_cast<PrivateStorage>(parser.getPayload());
+ CPPUNIT_ASSERT(payload);
+ boost::shared_ptr<Storage> storage = boost::dynamic_pointer_cast<Storage>(payload->getPayload());
+ CPPUNIT_ASSERT(storage);
+ CPPUNIT_ASSERT_EQUAL(String("Alice"), storage->getConferences()[0].nick);
+ CPPUNIT_ASSERT_EQUAL(JID("swift@rooms.swift.im"), storage->getConferences()[0].jid);
+ }
+
+ void testParse_NoPayload() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse("<query xmlns='jabber:iq:private'/>"));
+
+ boost::shared_ptr<PrivateStorage> payload = boost::dynamic_pointer_cast<PrivateStorage>(parser.getPayload());
+ CPPUNIT_ASSERT(payload);
+ CPPUNIT_ASSERT(!payload->getPayload());
+ }
+
+ void testParse_MultiplePayloads() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse(
+ "<query xmlns='jabber:iq:private'>"
+ "<storage xmlns='storage:bookmarks'>"
+ "<conference name='Swift' jid='swift@rooms.swift.im'>"
+ "<nick>Alice</nick>"
+ "</conference>"
+ "</storage>"
+ "<storage xmlns='storage:bookmarks'>"
+ "<conference name='Swift' jid='swift@rooms.swift.im'>"
+ "<nick>Rabbit</nick>"
+ "</conference>"
+ "</storage>"
+ "</query>"));
+
+ boost::shared_ptr<PrivateStorage> payload = boost::dynamic_pointer_cast<PrivateStorage>(parser.getPayload());
+ CPPUNIT_ASSERT(payload);
+ boost::shared_ptr<Storage> storage = boost::dynamic_pointer_cast<Storage>(payload->getPayload());
+ CPPUNIT_ASSERT(storage);
+ CPPUNIT_ASSERT_EQUAL(String("Rabbit"), storage->getConferences()[0].nick);
+ }
+
+ void testParse_UnsupportedPayload() {
+ PayloadParserFactoryCollection factories;
+ PrivateStorageParser testling(&factories);
+ PayloadParserTester parser(&testling);
+
+ CPPUNIT_ASSERT(parser.parse(
+ "<query xmlns='jabber:iq:private'>"
+ "<foo>Bar</foo>"
+ "</query>"));
+
+ CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<PrivateStorage>(testling.getPayload())->getPayload());
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(PrivateStorageParserTest);
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp
index 0cd0100..3fbf27a 100644
--- a/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp
+++ b/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp
@@ -6,8 +6,7 @@
using namespace Swift;
-class StorageParserTest : public CppUnit::TestFixture
-{
+class StorageParserTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StorageParserTest);
CPPUNIT_TEST(testParse_Conference);
CPPUNIT_TEST(testParse_MultipleConferences);