summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2010-10-17 12:13:36 (GMT)
committerRemko Tronçon <git@el-tramo.be>2010-10-21 18:25:00 (GMT)
commit1b58ef2af54456004390a0888c3edf104e3baa99 (patch)
treedbe4ae29de1b765a88ea704dfaa1c03af4b196b3 /Swiften/Parser/PayloadParsers
parent07402c4e3451f2084a1c3ddc5bacfb38a66899a7 (diff)
downloadswift-contrib-1b58ef2af54456004390a0888c3edf104e3baa99.zip
swift-contrib-1b58ef2af54456004390a0888c3edf104e3baa99.tar.bz2
Added beginnings of outgoing file transfer to Swiften.
Diffstat (limited to 'Swiften/Parser/PayloadParsers')
-rw-r--r--Swiften/Parser/PayloadParsers/BytestreamsParser.cpp48
-rw-r--r--Swiften/Parser/PayloadParsers/BytestreamsParser.h31
-rw-r--r--Swiften/Parser/PayloadParsers/BytestreamsParserFactory.h17
-rw-r--r--Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp6
-rw-r--r--Swiften/Parser/PayloadParsers/IBBParser.cpp77
-rw-r--r--Swiften/Parser/PayloadParsers/IBBParser.h31
-rw-r--r--Swiften/Parser/PayloadParsers/IBBParserFactory.h17
-rw-r--r--Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp117
-rw-r--r--Swiften/Parser/PayloadParsers/StreamInitiationParser.h42
-rw-r--r--Swiften/Parser/PayloadParsers/StreamInitiationParserFactory.h17
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp38
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp75
12 files changed, 516 insertions, 0 deletions
diff --git a/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp b/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp
new file mode 100644
index 0000000..154a925
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/BytestreamsParser.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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/BytestreamsParser.h"
+
+#include <boost/lexical_cast.hpp>
+
+#include "Swiften/Base/foreach.h"
+
+namespace Swift {
+
+BytestreamsParser::BytestreamsParser() : level(TopLevel) {
+}
+
+BytestreamsParser::~BytestreamsParser() {
+}
+
+void BytestreamsParser::handleStartElement(const String& element, const String&, const AttributeMap& attributes) {
+ if (level == TopLevel) {
+ getPayloadInternal()->setStreamID(attributes.getAttribute("sid"));
+ }
+ else if (level == PayloadLevel) {
+ if (element == "streamhost") {
+ try {
+ getPayloadInternal()->addStreamHost(Bytestreams::StreamHost(attributes.getAttribute("host"), JID(attributes.getAttribute("jid")), boost::lexical_cast<int>(attributes.getAttribute("port"))));
+ }
+ catch (boost::bad_lexical_cast& e) {
+ }
+ }
+ else if (element == "streamhost-used") {
+ getPayloadInternal()->setUsedStreamHost(JID(attributes.getAttribute("jid")));
+ }
+ }
+ ++level;
+}
+
+void BytestreamsParser::handleEndElement(const String&, const String&) {
+ --level;
+}
+
+void BytestreamsParser::handleCharacterData(const String&) {
+}
+
+
+}
diff --git a/Swiften/Parser/PayloadParsers/BytestreamsParser.h b/Swiften/Parser/PayloadParsers/BytestreamsParser.h
new file mode 100644
index 0000000..a45baa4
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/BytestreamsParser.h
@@ -0,0 +1,31 @@
+/*
+ * 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/Bytestreams.h"
+#include "Swiften/Parser/GenericPayloadParser.h"
+
+namespace Swift {
+ class BytestreamsParser : public GenericPayloadParser<Bytestreams> {
+ public:
+ BytestreamsParser();
+ ~BytestreamsParser();
+
+ 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,
+ };
+ int level;
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/BytestreamsParserFactory.h b/Swiften/Parser/PayloadParsers/BytestreamsParserFactory.h
new file mode 100644
index 0000000..8defd45
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/BytestreamsParserFactory.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/BytestreamsParser.h"
+
+namespace Swift {
+ class BytestreamsParserFactory : public GenericPayloadParserFactory<BytestreamsParser> {
+ public:
+ BytestreamsParserFactory() : GenericPayloadParserFactory<BytestreamsParser>("query", "http://jabber.org/protocol/bytestreams") {}
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
index de0e71c..90e9038 100644
--- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
+++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
@@ -27,6 +27,9 @@
#include "Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParserFactory.h"
#include "Swiften/Parser/PayloadParsers/FormParserFactory.h"
#include "Swiften/Parser/PayloadParsers/CommandParserFactory.h"
+#include "Swiften/Parser/PayloadParsers/StreamInitiationParserFactory.h"
+#include "Swiften/Parser/PayloadParsers/BytestreamsParserFactory.h"
+#include "Swiften/Parser/PayloadParsers/IBBParserFactory.h"
#include "Swiften/Parser/PayloadParsers/VCardUpdateParserFactory.h"
#include "Swiften/Parser/PayloadParsers/VCardParserFactory.h"
#include "Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h"
@@ -40,6 +43,7 @@ using namespace boost;
namespace Swift {
FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() {
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new IBBParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new StatusParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new StatusShowParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new BodyParserFactory()));
@@ -58,6 +62,8 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() {
factories_.push_back(shared_ptr<PayloadParserFactory>(new SecurityLabelsCatalogParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new FormParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new CommandParserFactory()));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new StreamInitiationParserFactory()));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new BytestreamsParserFactory()));
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)));
diff --git a/Swiften/Parser/PayloadParsers/IBBParser.cpp b/Swiften/Parser/PayloadParsers/IBBParser.cpp
new file mode 100644
index 0000000..b2b4929
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/IBBParser.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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/IBBParser.h"
+
+#include <boost/lexical_cast.hpp>
+
+#include "Swiften/Base/foreach.h"
+#include "Swiften/StringCodecs/Base64.h"
+
+namespace Swift {
+
+IBBParser::IBBParser() : level(TopLevel) {
+}
+
+IBBParser::~IBBParser() {
+}
+
+void IBBParser::handleStartElement(const String& element, const String&, const AttributeMap& attributes) {
+ if (level == TopLevel) {
+ if (element == "data") {
+ getPayloadInternal()->setAction(IBB::Data);
+ getPayloadInternal()->setStreamID(attributes.getAttribute("sid"));
+ try {
+ getPayloadInternal()->setSequenceNumber(boost::lexical_cast<int>(attributes.getAttribute("seq")));
+ }
+ catch (boost::bad_lexical_cast& e) {
+ }
+ }
+ else if (element == "open") {
+ getPayloadInternal()->setAction(IBB::Open);
+ getPayloadInternal()->setStreamID(attributes.getAttribute("sid"));
+ if (attributes.getAttribute("stanza") == "message") {
+ getPayloadInternal()->setStanzaType(IBB::MessageStanza);
+ }
+ else {
+ getPayloadInternal()->setStanzaType(IBB::IQStanza);
+ }
+ try {
+ getPayloadInternal()->setBlockSize(boost::lexical_cast<int>(attributes.getAttribute("block-size")));
+ }
+ catch (boost::bad_lexical_cast& e) {
+ }
+ }
+ else if (element == "close") {
+ getPayloadInternal()->setAction(IBB::Close);
+ getPayloadInternal()->setStreamID(attributes.getAttribute("sid"));
+ }
+ }
+ ++level;
+}
+
+void IBBParser::handleEndElement(const String& element, const String&) {
+ --level;
+ if (level == TopLevel) {
+ if (element == "data") {
+ std::vector<char> data;
+ for (size_t i = 0; i < currentText.getUTF8Size(); ++i) {
+ char c = currentText[i];
+ if (c >= 48 && c <= 122) {
+ data.push_back(c);
+ }
+ }
+ getPayloadInternal()->setData(Base64::decode(String(&data[0], data.size())));
+ }
+ }
+}
+
+void IBBParser::handleCharacterData(const String& data) {
+ currentText += data;
+}
+
+
+}
diff --git a/Swiften/Parser/PayloadParsers/IBBParser.h b/Swiften/Parser/PayloadParsers/IBBParser.h
new file mode 100644
index 0000000..1fc062f
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/IBBParser.h
@@ -0,0 +1,31 @@
+/*
+ * 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/IBB.h"
+#include "Swiften/Parser/GenericPayloadParser.h"
+
+namespace Swift {
+ class IBBParser : public GenericPayloadParser<IBB> {
+ public:
+ IBBParser();
+ ~IBBParser();
+
+ 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,
+ };
+ int level;
+ String currentText;
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/IBBParserFactory.h b/Swiften/Parser/PayloadParsers/IBBParserFactory.h
new file mode 100644
index 0000000..aa323f7
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/IBBParserFactory.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/IBBParser.h"
+
+namespace Swift {
+ class IBBParserFactory : public GenericPayloadParserFactory<IBBParser> {
+ public:
+ IBBParserFactory() : GenericPayloadParserFactory<IBBParser>("", "http://jabber.org/protocol/ibb") {}
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp b/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp
new file mode 100644
index 0000000..76925af
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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/StreamInitiationParser.h"
+
+#include <boost/lexical_cast.hpp>
+
+#include "Swiften/Parser/PayloadParsers/FormParserFactory.h"
+#include "Swiften/Parser/PayloadParsers/FormParser.h"
+#include "Swiften/Base/foreach.h"
+
+
+#define FILE_TRANSFER_NS "http://jabber.org/protocol/si/profile/file-transfer"
+#define FEATURE_NEG_NS "http://jabber.org/protocol/feature-neg"
+
+namespace Swift {
+
+StreamInitiationParser::StreamInitiationParser() : level(TopLevel), formParser(0), inFile(false), inFeature(false) {
+ formParserFactory = new FormParserFactory();
+}
+
+StreamInitiationParser::~StreamInitiationParser() {
+ delete formParserFactory;
+}
+
+void StreamInitiationParser::handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) {
+ if (level == TopLevel) {
+ getPayloadInternal()->setID(attributes.getAttribute("id"));
+ if (!attributes.getAttribute("profile").isEmpty()) {
+ getPayloadInternal()->setIsFileTransfer(attributes.getAttribute("profile") == FILE_TRANSFER_NS);
+ }
+ }
+ else if (level == PayloadLevel) {
+ if (element == "file") {
+ inFile = true;
+ currentFile = StreamInitiation::FileInfo();
+ currentFile.name = attributes.getAttribute("name");
+ try {
+ currentFile.size = boost::lexical_cast<int>(attributes.getAttribute("size"));
+ }
+ catch (boost::bad_lexical_cast& e) {
+ }
+ }
+ else if (element == "feature" && ns == FEATURE_NEG_NS) {
+ inFeature = true;
+ }
+ }
+ else if (level == FileOrFeatureLevel) {
+ if (inFile && element == "desc") {
+ currentText.clear();
+ }
+ else if (inFeature && formParserFactory->canParse(element, ns, attributes)) {
+ formParser = dynamic_cast<FormParser*>(formParserFactory->createPayloadParser());
+ }
+ }
+
+ if (formParser) {
+ formParser->handleStartElement(element, ns, attributes);
+ }
+ ++level;
+}
+
+void StreamInitiationParser::handleEndElement(const String& element, const String& ns) {
+ --level;
+ if (formParser) {
+ formParser->handleEndElement(element, ns);
+ }
+ if (level == TopLevel) {
+ }
+ else if (level == PayloadLevel) {
+ if (element == "file") {
+ getPayloadInternal()->setFileInfo(currentFile);
+ inFile = false;
+ }
+ else if (element == "feature" && ns == FEATURE_NEG_NS) {
+ inFeature = false;
+ }
+ }
+ else if (level == FileOrFeatureLevel) {
+ if (inFile && element == "desc") {
+ currentFile.description = currentText;
+ }
+ else if (formParser) {
+ Form::ref form = formParser->getPayloadInternal();
+ if (form) {
+ FormField::ref field = boost::dynamic_pointer_cast<FormField>(form->getField("stream-method"));
+ if (field) {
+ if (form->getType() == Form::FormType) {
+ foreach (const FormField::Option& option, field->getOptions()) {
+ getPayloadInternal()->addProvidedMethod(option.value);
+ }
+ }
+ else if (form->getType() == Form::SubmitType) {
+ if (field->getRawValues().size() > 0) {
+ getPayloadInternal()->setRequestedMethod(field->getRawValues()[0]);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void StreamInitiationParser::handleCharacterData(const String& data) {
+ if (formParser) {
+ formParser->handleCharacterData(data);
+ }
+ else {
+ currentText += data;
+ }
+}
+
+
+}
diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationParser.h b/Swiften/Parser/PayloadParsers/StreamInitiationParser.h
new file mode 100644
index 0000000..f01567e
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/StreamInitiationParser.h
@@ -0,0 +1,42 @@
+/*
+ * 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/StreamInitiation.h"
+#include "Swiften/Parser/GenericPayloadParser.h"
+
+namespace Swift {
+ class FormParserFactory;
+ class FormParser;
+
+ class StreamInitiationParser : public GenericPayloadParser<StreamInitiation> {
+ public:
+ StreamInitiationParser();
+ ~StreamInitiationParser();
+
+ 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,
+ FileOrFeatureLevel = 2,
+ FormOrDescriptionLevel = 3,
+ };
+ int level;
+ FormParserFactory* formParserFactory;
+ FormParser* formParser;
+ bool inFile;
+ bool inFeature;
+ StreamInitiation::FileInfo currentFile;
+ String currentText;
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationParserFactory.h b/Swiften/Parser/PayloadParsers/StreamInitiationParserFactory.h
new file mode 100644
index 0000000..ee5ed09
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/StreamInitiationParserFactory.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/StreamInitiationParser.h"
+
+namespace Swift {
+ class StreamInitiationParserFactory : public GenericPayloadParserFactory<StreamInitiationParser> {
+ public:
+ StreamInitiationParserFactory() : GenericPayloadParserFactory<StreamInitiationParser>("si", "http://jabber.org/protocol/si") {}
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp
new file mode 100644
index 0000000..f892deb
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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/IBB.h"
+
+using namespace Swift;
+
+class IBBParserTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(IBBParserTest);
+ CPPUNIT_TEST(testParse_Data);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void testParse_Data() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse(
+ "<data xmlns='http://jabber.org/protocol/ibb' seq='4'>\n"
+ "\t YWJjZGVmZ2loamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWjEyMzQ1\n"
+ "\t Njc4OTAK\n"
+ "</data>"
+ ));
+
+ IBB::ref ibb = parser.getPayload<IBB>();
+ CPPUNIT_ASSERT(ibb->getAction() == IBB::Data);
+ CPPUNIT_ASSERT_EQUAL(ByteArray("abcdefgihjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890\x0a"), ibb->getData());
+ CPPUNIT_ASSERT_EQUAL(4, ibb->getSequenceNumber());
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(IBBParserTest);
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp
new file mode 100644
index 0000000..ca8e353
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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/StreamInitiation.h"
+
+using namespace Swift;
+
+class StreamInitiationParserTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(StreamInitiationParserTest);
+ CPPUNIT_TEST(testParse_Request);
+ CPPUNIT_TEST(testParse_Response);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void testParse_Request() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse(
+ "<si xmlns='http://jabber.org/protocol/si' id='a0' mime-type='text/plain' profile='http://jabber.org/protocol/si/profile/file-transfer'>"
+ "<file xmlns='http://jabber.org/protocol/si/profile/file-transfer' name='test.txt' size='1022'>"
+ "<desc>This is info about the file.</desc>"
+ "</file>"
+ "<feature xmlns='http://jabber.org/protocol/feature-neg'>"
+ "<x xmlns='jabber:x:data' type='form'>"
+ "<field var='stream-method' type='list-single'>"
+ "<option><value>http://jabber.org/protocol/bytestreams</value></option>"
+ "<option><value>jabber:iq:oob</value></option>"
+ "<option><value>http://jabber.org/protocol/ibb</value></option>"
+ "</field>"
+ "</x>"
+ "</feature>"
+ "</si>"
+ ));
+
+ StreamInitiation::ref si = parser.getPayload<StreamInitiation>();
+ CPPUNIT_ASSERT(si->getIsFileTransfer());
+ CPPUNIT_ASSERT(si->getFileInfo());
+ CPPUNIT_ASSERT_EQUAL(String("test.txt"), si->getFileInfo()->name);
+ CPPUNIT_ASSERT_EQUAL(1022, si->getFileInfo()->size);
+ CPPUNIT_ASSERT_EQUAL(String("This is info about the file."), si->getFileInfo()->description);
+ CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(si->getProvidedMethods().size()));
+ CPPUNIT_ASSERT_EQUAL(String("http://jabber.org/protocol/bytestreams"), si->getProvidedMethods()[0]);
+ CPPUNIT_ASSERT_EQUAL(String("jabber:iq:oob"), si->getProvidedMethods()[1]);
+ CPPUNIT_ASSERT_EQUAL(String("http://jabber.org/protocol/ibb"), si->getProvidedMethods()[2]);
+ }
+
+ void testParse_Response() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse(
+ "<si xmlns='http://jabber.org/protocol/si'>"
+ "<feature xmlns='http://jabber.org/protocol/feature-neg'>"
+ "<x xmlns='jabber:x:data' type='submit'>"
+ "<field var='stream-method'>"
+ "<value>http://jabber.org/protocol/bytestreams</value>"
+ "</field>"
+ "</x>"
+ "</feature>"
+ "</si>"
+ ));
+
+ StreamInitiation::ref si = parser.getPayload<StreamInitiation>();
+ CPPUNIT_ASSERT(si->getIsFileTransfer());
+ CPPUNIT_ASSERT_EQUAL(String("http://jabber.org/protocol/bytestreams"), si->getRequestedMethod());
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(StreamInitiationParserTest);