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/SearchPayloadParser.cpp110
-rw-r--r--Swiften/Parser/PayloadParsers/SearchPayloadParser.h39
-rw-r--r--Swiften/Parser/PayloadParsers/SearchPayloadParserFactory.h17
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/SearchPayloadParserTest.cpp71
5 files changed, 239 insertions, 0 deletions
diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
index 41bba11..70dd81e 100644
--- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
+++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
@@ -28,6 +28,7 @@
#include "Swiften/Parser/PayloadParsers/FormParserFactory.h"
#include "Swiften/Parser/PayloadParsers/CommandParserFactory.h"
#include "Swiften/Parser/PayloadParsers/InBandRegistrationPayloadParserFactory.h"
+#include "Swiften/Parser/PayloadParsers/SearchPayloadParserFactory.h"
#include "Swiften/Parser/PayloadParsers/StreamInitiationParserFactory.h"
#include "Swiften/Parser/PayloadParsers/BytestreamsParserFactory.h"
#include "Swiften/Parser/PayloadParsers/IBBParserFactory.h"
@@ -64,6 +65,7 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() {
factories_.push_back(shared_ptr<PayloadParserFactory>(new FormParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new CommandParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new InBandRegistrationPayloadParserFactory()));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new SearchPayloadParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new StreamInitiationParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new BytestreamsParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new VCardUpdateParserFactory()));
diff --git a/Swiften/Parser/PayloadParsers/SearchPayloadParser.cpp b/Swiften/Parser/PayloadParsers/SearchPayloadParser.cpp
new file mode 100644
index 0000000..f2cf1dd
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/SearchPayloadParser.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swiften/Parser/PayloadParsers/SearchPayloadParser.h"
+#include "Swiften/Parser/PayloadParsers/FormParserFactory.h"
+#include "Swiften/Parser/PayloadParsers/FormParser.h"
+
+namespace Swift {
+
+SearchPayloadParser::SearchPayloadParser() : level(TopLevel), formParser(NULL) {
+ formParserFactory = new FormParserFactory();
+}
+
+SearchPayloadParser::~SearchPayloadParser() {
+ delete formParserFactory;
+}
+
+void SearchPayloadParser::handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) {
+ if (level == TopLevel) {
+ }
+ else if (level == PayloadLevel) {
+ if (element == "x" && ns == "jabber:x:data") {
+ assert(!formParser);
+ formParser = dynamic_cast<FormParser*>(formParserFactory->createPayloadParser());
+ }
+ else if (element == "item") {
+ assert(!currentItem);
+ currentItem.reset(SearchPayload::Item());
+ currentItem->jid = JID(attributes.getAttribute("jid"));
+ }
+ else {
+ currentText.clear();
+ }
+ }
+ else if (level == ItemLevel && currentItem) {
+ currentText.clear();
+ }
+
+ if (formParser) {
+ formParser->handleStartElement(element, ns, attributes);
+ }
+
+ ++level;
+}
+
+void SearchPayloadParser::handleEndElement(const String& element, const String& ns) {
+ --level;
+
+ if (formParser) {
+ formParser->handleEndElement(element, ns);
+ }
+
+ if (level == TopLevel) {
+ }
+ else if (level == PayloadLevel) {
+ if (formParser) {
+ getPayloadInternal()->setForm(formParser->getPayloadInternal());
+ delete formParser;
+ formParser = NULL;
+ }
+ else if (element == "item") {
+ assert(currentItem);
+ getPayloadInternal()->addItem(*currentItem);
+ currentItem.reset();
+ }
+ else if (element == "instructions") {
+ getPayloadInternal()->setInstructions(currentText);
+ }
+ else if (element == "nick") {
+ getPayloadInternal()->setNick(currentText);
+ }
+ else if (element == "first") {
+ getPayloadInternal()->setFirst(currentText);
+ }
+ else if (element == "last") {
+ getPayloadInternal()->setLast(currentText);
+ }
+ else if (element == "email") {
+ getPayloadInternal()->setEMail(currentText);
+ }
+ }
+ else if (level == ItemLevel && currentItem) {
+ if (element == "nick") {
+ currentItem->nick = currentText;
+ }
+ else if (element == "first") {
+ currentItem->first = currentText;
+ }
+ else if (element == "last") {
+ currentItem->last = currentText;
+ }
+ else if (element == "email") {
+ currentItem->email = currentText;
+ }
+ }
+}
+
+void SearchPayloadParser::handleCharacterData(const String& data) {
+ if (formParser) {
+ formParser->handleCharacterData(data);
+ }
+ else {
+ currentText += data;
+ }
+}
+
+}
diff --git a/Swiften/Parser/PayloadParsers/SearchPayloadParser.h b/Swiften/Parser/PayloadParsers/SearchPayloadParser.h
new file mode 100644
index 0000000..55177b0
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/SearchPayloadParser.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/optional.hpp>
+
+#include "Swiften/Elements/SearchPayload.h"
+#include "Swiften/Parser/GenericPayloadParser.h"
+
+namespace Swift {
+ class FormParserFactory;
+ class FormParser;
+
+ class SearchPayloadParser : public GenericPayloadParser<SearchPayload> {
+ public:
+ SearchPayloadParser();
+ ~SearchPayloadParser();
+
+ 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:
+ enum Level {
+ TopLevel = 0,
+ PayloadLevel = 1,
+ ItemLevel = 2,
+ };
+ int level;
+ FormParserFactory* formParserFactory;
+ FormParser* formParser;
+ String currentText;
+ boost::optional<SearchPayload::Item> currentItem;
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/SearchPayloadParserFactory.h b/Swiften/Parser/PayloadParsers/SearchPayloadParserFactory.h
new file mode 100644
index 0000000..0f8a6c7
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/SearchPayloadParserFactory.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include "Swiften/Parser/GenericPayloadParserFactory.h"
+#include "Swiften/Parser/PayloadParsers/SearchPayloadParser.h"
+
+namespace Swift {
+ class SearchPayloadParserFactory : public GenericPayloadParserFactory<SearchPayloadParser> {
+ public:
+ SearchPayloadParserFactory() : GenericPayloadParserFactory<SearchPayloadParser>("query", "jabber:iq:search") {}
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/SearchPayloadParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/SearchPayloadParserTest.cpp
new file mode 100644
index 0000000..1d94c15
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/UnitTest/SearchPayloadParserTest.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h"
+#include "Swiften/Elements/SearchPayload.h"
+
+using namespace Swift;
+
+class SearchPayloadParserTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(SearchPayloadParserTest);
+ CPPUNIT_TEST(testParse_FormRequestResponse);
+ CPPUNIT_TEST(testParse_Results);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void testParse_FormRequestResponse() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse(
+ "<query xmlns=\"jabber:iq:search\">"
+ "<instructions>Foo</instructions>"
+ "<first/>"
+ "<last/>"
+ "</query>"
+ ));
+
+ SearchPayload::ref payload = parser.getPayload<SearchPayload>();
+ CPPUNIT_ASSERT_EQUAL(String("Foo"), *payload->getInstructions());
+ CPPUNIT_ASSERT(payload->getFirst());
+ CPPUNIT_ASSERT(payload->getLast());
+ CPPUNIT_ASSERT(!payload->getNick());
+ }
+
+ void testParse_Results() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse(
+ "<query xmlns=\"jabber:iq:search\">"
+ "<item jid=\"juliet@capulet.com\">"
+ "<first>Juliet</first>"
+ "<last>Capulet</last>"
+ "<nick>JuliC</nick>"
+ "<email>juliet@shakespeare.lit</email>"
+ "</item>"
+ "<item jid=\"tybalt@shakespeare.lit\">"
+ "<first>Tybalt</first>"
+ "<last>Capulet</last>"
+ "<nick>ty</nick>"
+ "<email>tybalt@shakespeare.lit</email>"
+ "</item>"
+ "</query>"
+ ));
+
+ SearchPayload::ref payload = parser.getPayload<SearchPayload>();
+ CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(payload->getItems().size()));
+ CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.com"), payload->getItems()[0].jid);
+ CPPUNIT_ASSERT_EQUAL(String("Juliet"), payload->getItems()[0].first);
+ CPPUNIT_ASSERT_EQUAL(String("Capulet"), payload->getItems()[0].last);
+ CPPUNIT_ASSERT_EQUAL(String("JuliC"), payload->getItems()[0].nick);
+ CPPUNIT_ASSERT_EQUAL(String("juliet@shakespeare.lit"), payload->getItems()[0].email);
+ CPPUNIT_ASSERT_EQUAL(JID("tybalt@shakespeare.lit"), payload->getItems()[1].jid);
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SearchPayloadParserTest);