summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Parser/PayloadParsers')
-rw-r--r--Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp23
-rw-r--r--Swiften/Parser/PayloadParsers/IBBParser.cpp2
-rw-r--r--Swiften/Parser/PayloadParsers/JingleContentPayloadParser.cpp74
-rw-r--r--Swiften/Parser/PayloadParsers/JingleContentPayloadParser.h30
-rw-r--r--Swiften/Parser/PayloadParsers/JingleContentPayloadParserFactory.h35
-rw-r--r--Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp75
-rw-r--r--Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.h38
-rw-r--r--Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParserFactory.h35
-rw-r--r--Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.cpp43
-rw-r--r--Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.h27
-rw-r--r--Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp49
-rw-r--r--Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h27
-rw-r--r--Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.cpp38
-rw-r--r--Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h26
-rw-r--r--Swiften/Parser/PayloadParsers/JingleParser.cpp119
-rw-r--r--Swiften/Parser/PayloadParsers/JingleParser.h32
-rw-r--r--Swiften/Parser/PayloadParsers/JingleParserFactory.h35
-rw-r--r--Swiften/Parser/PayloadParsers/JingleReasonParser.cpp81
-rw-r--r--Swiften/Parser/PayloadParsers/JingleReasonParser.h30
-rw-r--r--Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp88
-rw-r--r--Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h29
-rw-r--r--Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp64
-rw-r--r--Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h30
-rw-r--r--Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.cpp69
-rw-r--r--Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h28
-rw-r--r--Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp6
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp709
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp6
28 files changed, 1841 insertions, 7 deletions
diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
index 1b59f6f..9eafcba 100644
--- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
+++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
@@ -48,6 +48,19 @@
#include <Swiften/Parser/PayloadParsers/NicknameParserFactory.h>
#include <Swiften/Parser/PayloadParsers/ReplaceParser.h>
#include <Swiften/Parser/PayloadParsers/LastParser.h>
+#include <Swiften/Parser/PayloadParsers/JingleParserFactory.h>
+#include <Swiften/Parser/PayloadParsers/JingleReasonParser.h>
+#include <Swiften/Parser/PayloadParsers/JingleContentPayloadParserFactory.h>
+#include <Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h>
+#include <Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h>
+#include <Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParserFactory.h>
+#include <Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h>
+#include <Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h>
+#include <Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.h>
+#include <Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h>
+
+#include "JingleIBBTransportMethodPayloadParser.h"
+#include "JingleFileTransferDescriptionParser.h"
using namespace boost;
@@ -91,6 +104,16 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() {
factories_.push_back(shared_ptr<PayloadParserFactory>(new MUCUserPayloadParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<MUCAdminPayloadParser>("query", "http://jabber.org/protocol/muc#admin")));
factories_.push_back(shared_ptr<PayloadParserFactory>(new NicknameParserFactory()));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new JingleParserFactory(this)));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<JingleReasonParser>("reason", "urn:xmpp:jingle:1")));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new JingleContentPayloadParserFactory(this)));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<JingleIBBTransportMethodPayloadParser>("transport", "urn:xmpp:jingle:transports:ibb:1")));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<JingleS5BTransportMethodPayloadParser>("transport", "urn:xmpp:jingle:transports:s5b:1")));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new JingleFileTransferDescriptionParserFactory(this)));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<StreamInitiationFileInfoParser>("file", "http://jabber.org/protocol/si/profile/file-transfer")));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<JingleFileTransferReceivedParser>("received", "urn:xmpp:jingle:apps:file-transfer:3")));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<JingleFileTransferHashParser>("checksum")));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<S5BProxyRequestParser>("query", "http://jabber.org/protocol/bytestreams")));
foreach(shared_ptr<PayloadParserFactory> factory, factories_) {
addFactory(factory.get());
}
diff --git a/Swiften/Parser/PayloadParsers/IBBParser.cpp b/Swiften/Parser/PayloadParsers/IBBParser.cpp
index 2705c75..20a1ce9 100644
--- a/Swiften/Parser/PayloadParsers/IBBParser.cpp
+++ b/Swiften/Parser/PayloadParsers/IBBParser.cpp
@@ -60,7 +60,7 @@ void IBBParser::handleEndElement(const std::string& element, const std::string&)
std::vector<char> data;
for (size_t i = 0; i < currentText.size(); ++i) {
char c = currentText[i];
- if (c >= 48 && c <= 122) {
+ if ((c >= 48 && c <= 122) || c == 47 || c == 43) {
data.push_back(c);
}
}
diff --git a/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.cpp b/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.cpp
new file mode 100644
index 0000000..1431b9e
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "JingleContentPayloadParser.h"
+#include <Swiften/Parser/PayloadParserFactoryCollection.h>
+#include <Swiften/Parser/PayloadParserFactory.h>
+#include <Swiften/Elements/JinglePayload.h>
+
+#include <Swiften/Base/Log.h>
+
+namespace Swift {
+ JingleContentPayloadParser::JingleContentPayloadParser(PayloadParserFactoryCollection* factories) : factories(factories), level(0) {
+
+ }
+
+ void JingleContentPayloadParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) {
+ if (level == 0) {
+ std::string creator = attributes.getAttributeValue("creator").get_value_or("");
+ if (creator == "initiator") {
+ getPayloadInternal()->setCreator(JingleContentPayload::InitiatorCreator);
+ } else if (creator == "responder") {
+ getPayloadInternal()->setCreator(JingleContentPayload::ResponderCreator);
+ } else {
+ getPayloadInternal()->setCreator(JingleContentPayload::UnknownCreator);
+ }
+
+ getPayloadInternal()->setName(attributes.getAttributeValue("name").get_value_or(""));
+ }
+
+ if (level == 1) {
+ PayloadParserFactory* payloadParserFactory = factories->getPayloadParserFactory(element, ns, attributes);
+ if (payloadParserFactory) {
+ currentPayloadParser.reset(payloadParserFactory->createPayloadParser());
+ }
+ }
+
+ if (level >= 1 && currentPayloadParser) {
+ currentPayloadParser->handleStartElement(element, ns, attributes);
+ }
+
+ ++level;
+ }
+
+ void JingleContentPayloadParser::handleEndElement(const std::string& element, const std::string& ns) {
+ --level;
+
+ if (currentPayloadParser) {
+ if (level >= 1) {
+ currentPayloadParser->handleEndElement(element, ns);
+ }
+
+ if (level == 1) {
+ boost::shared_ptr<JingleTransportPayload> transport = boost::dynamic_pointer_cast<JingleTransportPayload>(currentPayloadParser->getPayload());
+ if (transport) {
+ getPayloadInternal()->addTransport(transport);
+ }
+
+ boost::shared_ptr<JingleDescription> description = boost::dynamic_pointer_cast<JingleDescription>(currentPayloadParser->getPayload());
+ if (description) {
+ getPayloadInternal()->addDescription(description);
+ }
+ }
+ }
+ }
+
+ void JingleContentPayloadParser::handleCharacterData(const std::string& data) {
+ if (level > 1 && currentPayloadParser) {
+ currentPayloadParser->handleCharacterData(data);
+ }
+ }
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.h b/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.h
new file mode 100644
index 0000000..a871cc4
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleContentPayloadParser.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/JingleContentPayload.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+
+namespace Swift {
+
+class PayloadParserFactoryCollection;
+
+class JingleContentPayloadParser : public GenericPayloadParser<JingleContentPayload> {
+ public:
+ JingleContentPayloadParser(PayloadParserFactoryCollection* factories);
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+
+ private:
+ PayloadParserFactoryCollection* factories;
+ int level;
+ boost::shared_ptr<PayloadParser> currentPayloadParser;
+};
+
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleContentPayloadParserFactory.h b/Swiften/Parser/PayloadParsers/JingleContentPayloadParserFactory.h
new file mode 100644
index 0000000..6d66e74
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleContentPayloadParserFactory.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Parser/GenericPayloadParserFactory.h>
+#include <Swiften/Parser/PayloadParsers/JingleContentPayloadParser.h>
+
+namespace Swift {
+
+ class PayloadParserFactoryCollection;
+
+ class JingleContentPayloadParserFactory : public PayloadParserFactory {
+ public:
+ JingleContentPayloadParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) {
+ }
+
+ virtual bool canParse(const std::string& element, const std::string& ns, const AttributeMap&) const {
+ return element == "content" && ns == "urn:xmpp:jingle:1";
+ }
+
+ virtual PayloadParser* createPayloadParser() {
+ return new JingleContentPayloadParser(factories);
+ }
+
+ private:
+ PayloadParserFactoryCollection* factories;
+
+ };
+}
+
+
diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp
new file mode 100644
index 0000000..b394115
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "JingleFileTransferDescriptionParser.h"
+
+#include <Swiften/Parser/PayloadParserFactoryCollection.h>
+#include <Swiften/Parser/PayloadParserFactory.h>
+#include <Swiften/Base/Log.h>
+
+namespace Swift {
+
+JingleFileTransferDescriptionParser::JingleFileTransferDescriptionParser(PayloadParserFactoryCollection* factories) : factories(factories), level(0),
+ currentElement(UnknownElement) {
+
+}
+
+void JingleFileTransferDescriptionParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) {
+ if (level == 0) {
+
+ }
+
+ if (level == 1) {
+ if (element == "offer") {
+ currentElement = OfferElement;
+ } else if (element == "request") {
+ currentElement = RequestElement;
+ } else {
+ currentElement = UnknownElement;
+ }
+ }
+
+ if (level == 2) {
+ PayloadParserFactory* payloadParserFactory = factories->getPayloadParserFactory(element, ns, attributes);
+ if (payloadParserFactory) {
+ currentPayloadParser.reset(payloadParserFactory->createPayloadParser());
+ }
+ }
+
+ if (level >= 2 && currentPayloadParser) {
+ currentPayloadParser->handleStartElement(element, ns, attributes);
+ }
+
+ ++level;
+}
+
+void JingleFileTransferDescriptionParser::handleEndElement(const std::string& element, const std::string& ns) {
+ --level;
+ if (currentPayloadParser) {
+ if (level >= 2) {
+ currentPayloadParser->handleEndElement(element, ns);
+ }
+
+ if (level == 2) {
+ boost::shared_ptr<StreamInitiationFileInfo> info = boost::dynamic_pointer_cast<StreamInitiationFileInfo>(currentPayloadParser->getPayload());
+ if (info) {
+ if (currentElement == OfferElement) {
+ getPayloadInternal()->addOffer(*info);
+ } else if (currentElement == RequestElement) {
+ getPayloadInternal()->addRequest(*info);
+ }
+ }
+ }
+ }
+}
+
+void JingleFileTransferDescriptionParser::handleCharacterData(const std::string& data) {
+ if (level >= 2 && currentPayloadParser) {
+ currentPayloadParser->handleCharacterData(data);
+ }
+}
+
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.h b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.h
new file mode 100644
index 0000000..93560c6
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/JingleFileTransferDescription.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+#include <Swiften/Parser/PayloadParser.h>
+
+namespace Swift {
+
+class PayloadParserFactoryCollection;
+
+class JingleFileTransferDescriptionParser : public GenericPayloadParser<JingleFileTransferDescription> {
+ public:
+ JingleFileTransferDescriptionParser(PayloadParserFactoryCollection* factories);
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+
+ private:
+ enum CurrentParseElement {
+ UnknownElement,
+ RequestElement,
+ OfferElement,
+ };
+
+ PayloadParserFactoryCollection* factories;
+ int level;
+ CurrentParseElement currentElement;
+ boost::shared_ptr<PayloadParser> currentPayloadParser;
+};
+
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParserFactory.h b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParserFactory.h
new file mode 100644
index 0000000..b997c1d
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParserFactory.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Parser/GenericPayloadParserFactory.h>
+#include <Swiften/Parser/PayloadParsers/JingleFileTransferDescriptionParser.h>
+
+namespace Swift {
+
+ class PayloadParserFactoryCollection;
+
+ class JingleFileTransferDescriptionParserFactory : public PayloadParserFactory {
+ public:
+ JingleFileTransferDescriptionParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) {
+ }
+
+ virtual bool canParse(const std::string& element, const std::string& ns, const AttributeMap&) const {
+ return element == "description" && ns == "urn:xmpp:jingle:apps:file-transfer:3";
+ }
+
+ virtual PayloadParser* createPayloadParser() {
+ return new JingleFileTransferDescriptionParser(factories);
+ }
+
+ private:
+ PayloadParserFactoryCollection* factories;
+
+ };
+}
+
+
diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.cpp b/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.cpp
new file mode 100644
index 0000000..87f8317
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "JingleFileTransferHashParser.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include <Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h>
+#include <Swiften/Parser/GenericPayloadParserFactory.h>
+#include <Swiften/Parser/PayloadParserFactory.h>
+
+namespace Swift {
+
+JingleFileTransferHashParser::JingleFileTransferHashParser() {
+}
+
+void JingleFileTransferHashParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) {
+ if (element == "hash") {
+ algo = attributes.getAttribute("algo");
+ }
+}
+
+void JingleFileTransferHashParser::handleEndElement(const std::string& element, const std::string& ) {
+ if (element == "hash" && !algo.empty() && !hash.empty()) {
+ getPayloadInternal()->setHash(algo, hash);
+ algo.clear();
+ hash.clear();
+ }
+}
+
+void JingleFileTransferHashParser::handleCharacterData(const std::string& data) {
+ if (!algo.empty()) {
+ std::string new_data(data);
+ boost::trim(new_data);
+ hash += new_data;
+ }
+}
+
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.h b/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.h
new file mode 100644
index 0000000..35e4a05
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleFileTransferHashParser.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/JingleFileTransferHash.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+
+namespace Swift {
+
+class JingleFileTransferHashParser : public GenericPayloadParser<JingleFileTransferHash> {
+public:
+ JingleFileTransferHashParser();
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+
+private:
+ std::string algo;
+ std::string hash;
+};
+
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp
new file mode 100644
index 0000000..20ad73e
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "JingleFileTransferReceivedParser.h"
+#include "StreamInitiationFileInfoParser.h"
+
+#include <boost/shared_ptr.hpp>
+#include <Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h>
+#include <Swiften/Parser/GenericPayloadParserFactory.h>
+#include <Swiften/Parser/PayloadParserFactory.h>
+
+namespace Swift {
+
+JingleFileTransferReceivedParser::JingleFileTransferReceivedParser() : level(0) {
+}
+
+void JingleFileTransferReceivedParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) {
+ if (level == 1 && element == "file") {
+ PayloadParserFactory* payloadParserFactory = new GenericPayloadParserFactory<StreamInitiationFileInfoParser>("file", "http://jabber.org/protocol/si/profile/file-transfer");
+ if (payloadParserFactory) {
+ currentPayloadParser.reset(payloadParserFactory->createPayloadParser());
+ }
+ }
+
+ if (currentPayloadParser && level >= 1) {
+ currentPayloadParser->handleStartElement(element, ns, attributes);
+ }
+
+ ++level;
+}
+
+void JingleFileTransferReceivedParser::handleEndElement(const std::string& element, const std::string& ) {
+ --level;
+ if (element == "file") {
+ boost::shared_ptr<StreamInitiationFileInfo> fileInfo = boost::dynamic_pointer_cast<StreamInitiationFileInfo>(currentPayloadParser->getPayload());
+ if (fileInfo) {
+ getPayloadInternal()->setFileInfo(*fileInfo);
+ }
+ }
+}
+
+void JingleFileTransferReceivedParser::handleCharacterData(const std::string& ) {
+
+}
+
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h
new file mode 100644
index 0000000..824b06d
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleFileTransferReceivedParser.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/JingleFileTransferReceived.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+
+namespace Swift {
+
+class JingleFileTransferReceivedParser : public GenericPayloadParser<JingleFileTransferReceived> {
+public:
+ JingleFileTransferReceivedParser();
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+
+private:
+ boost::shared_ptr<PayloadParser> currentPayloadParser;
+ int level;
+};
+
+} \ No newline at end of file
diff --git a/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.cpp b/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.cpp
new file mode 100644
index 0000000..a3dfd12
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <boost/lexical_cast.hpp>
+#include <boost/optional.hpp>
+
+#include "JingleIBBTransportMethodPayloadParser.h"
+
+#include <Swiften/Base/Log.h>
+
+namespace Swift {
+ JingleIBBTransportMethodPayloadParser::JingleIBBTransportMethodPayloadParser() : level(0) {
+
+ }
+
+ void JingleIBBTransportMethodPayloadParser::handleStartElement(const std::string&, const std::string&, const AttributeMap& attributes) {
+ try {
+ getPayloadInternal()->setBlockSize(boost::lexical_cast<int>(attributes.getAttributeValue("block-size").get_value_or("0")));
+ } catch (boost::bad_lexical_cast &) {
+ getPayloadInternal()->setBlockSize(0);
+ }
+ getPayloadInternal()->setSessionID(attributes.getAttributeValue("sid").get_value_or(""));
+ ++level;
+ }
+
+ void JingleIBBTransportMethodPayloadParser::handleEndElement(const std::string&, const std::string&) {
+ --level;
+
+
+ }
+
+ void JingleIBBTransportMethodPayloadParser::handleCharacterData(const std::string&) {
+
+ }
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h b/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h
new file mode 100644
index 0000000..311cc5b
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/JingleIBBTransportPayload.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+
+namespace Swift {
+
+class JingleIBBTransportMethodPayloadParser : public GenericPayloadParser<JingleIBBTransportPayload> {
+ public:
+ JingleIBBTransportMethodPayloadParser();
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+
+ private:
+ int level;
+};
+
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleParser.cpp b/Swiften/Parser/PayloadParsers/JingleParser.cpp
new file mode 100644
index 0000000..dd34458
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleParser.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/Parser/PayloadParsers/JingleParser.h>
+#include <Swiften/Parser/PayloadParserFactory.h>
+#include <Swiften/Elements/JingleContentPayload.h>
+#include <Swiften/Elements/JingleFileTransferReceived.h>
+#include <Swiften/Elements/JingleFileTransferHash.h>
+#include <Swiften/Base/Log.h>
+
+#include <boost/intrusive_ptr.hpp>
+
+namespace Swift {
+
+ JingleParser::JingleParser(PayloadParserFactoryCollection* factories) : factories(factories), level(0) {
+
+ }
+
+ void JingleParser::handleStartElement(const std::string& element, const std::string &ns, const AttributeMap& attributes) {
+ if (level == 0) {
+ // <jingle > tag
+ JinglePayload::ref payload = getPayloadInternal();
+ payload->setAction(stringToAction(attributes.getAttributeValue("action").get_value_or("")));
+ payload->setInitiator(JID(attributes.getAttributeValue("initiator").get_value_or("")));
+ payload->setResponder(JID(attributes.getAttributeValue("responder").get_value_or("")));
+ payload->setSessionID(attributes.getAttributeValue("sid").get_value_or(""));
+ }
+
+ if (level == 1) {
+ PayloadParserFactory* payloadParserFactory = factories->getPayloadParserFactory(element, ns, attributes);
+ if (payloadParserFactory) {
+ currentPayloadParser.reset(payloadParserFactory->createPayloadParser());
+ }
+ }
+
+ if (level >= 1 && currentPayloadParser) {
+ currentPayloadParser->handleStartElement(element, ns, attributes);
+ }
+
+ ++level;
+ }
+
+ void JingleParser::handleEndElement(const std::string& element, const std::string &ns) {
+ --level;
+ if (currentPayloadParser) {
+ if (level >= 1) {
+ currentPayloadParser->handleEndElement(element, ns);
+ }
+
+ if (level == 1) {
+ boost::shared_ptr<JinglePayload::Reason> reason = boost::dynamic_pointer_cast<JinglePayload::Reason>(currentPayloadParser->getPayload());
+ if (reason) {
+ getPayloadInternal()->setReason(*reason);
+ }
+
+ boost::shared_ptr<JingleContentPayload> payload = boost::dynamic_pointer_cast<JingleContentPayload>(currentPayloadParser->getPayload());
+ if (payload) {
+ getPayloadInternal()->addContent(payload);
+ }
+
+ boost::shared_ptr<JingleFileTransferReceived> received = boost::dynamic_pointer_cast<JingleFileTransferReceived>(currentPayloadParser->getPayload());
+ if (received) {
+ getPayloadInternal()->addPayload(received);
+ }
+
+ boost::shared_ptr<JingleFileTransferHash> hash = boost::dynamic_pointer_cast<JingleFileTransferHash>(currentPayloadParser->getPayload());
+ if (hash) {
+ getPayloadInternal()->addPayload(hash);
+ }
+ }
+ }
+ }
+
+ void JingleParser::handleCharacterData(const std::string& data) {
+ if (level > 1 && currentPayloadParser) {
+ currentPayloadParser->handleCharacterData(data);
+ }
+ }
+
+ JinglePayload::Action JingleParser::stringToAction(const std::string &str) const {
+ if (str == "content-accept") {
+ return JinglePayload::ContentAccept;
+ } else if (str == "content-add") {
+ return JinglePayload::ContentAdd;
+ } else if (str == "content-modify") {
+ return JinglePayload::ContentModify;
+ } else if (str == "content-reject") {
+ return JinglePayload::ContentReject;
+ } else if (str == "content-remove") {
+ return JinglePayload::ContentRemove;
+ } else if (str == "description-info") {
+ return JinglePayload::DescriptionInfo;
+ } else if (str == "security-info") {
+ return JinglePayload::SecurityInfo;
+ } else if (str == "session-accept") {
+ return JinglePayload::SessionAccept;
+ } else if (str == "session-info") {
+ return JinglePayload::SessionInfo;
+ } else if (str == "session-initiate") {
+ return JinglePayload::SessionInitiate;
+ } else if (str == "session-terminate") {
+ return JinglePayload::SessionTerminate;
+ } else if (str == "transport-accept") {
+ return JinglePayload::TransportAccept;
+ } else if (str == "transport-info") {
+ return JinglePayload::TransportInfo;
+ } else if (str == "transport-reject") {
+ return JinglePayload::TransportReject;
+ } else if (str == "transport-replace") {
+ return JinglePayload::TransportReplace;
+ } else {
+ return JinglePayload::UnknownAction;
+ }
+
+ }
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleParser.h b/Swiften/Parser/PayloadParsers/JingleParser.h
new file mode 100644
index 0000000..ecaca3c
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleParser.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/JinglePayload.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+#include <Swiften/Parser/PayloadParserFactoryCollection.h>
+
+namespace Swift {
+
+class JingleParser : public GenericPayloadParser<JinglePayload> {
+ public:
+ JingleParser(PayloadParserFactoryCollection* factories);
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+
+ private:
+ JinglePayload::Action stringToAction(const std::string &str) const;
+
+ private:
+ PayloadParserFactoryCollection* factories;
+ int level;
+ boost::shared_ptr<PayloadParser> currentPayloadParser;
+};
+
+}; \ No newline at end of file
diff --git a/Swiften/Parser/PayloadParsers/JingleParserFactory.h b/Swiften/Parser/PayloadParsers/JingleParserFactory.h
new file mode 100644
index 0000000..fa25aeb
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleParserFactory.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Parser/GenericPayloadParserFactory.h>
+#include <Swiften/Parser/PayloadParsers/JingleParser.h>
+
+namespace Swift {
+
+ class PayloadParserFactoryCollection;
+
+ class JingleParserFactory : public PayloadParserFactory {
+ public:
+ JingleParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) {
+ }
+
+ virtual bool canParse(const std::string& element, const std::string& ns, const AttributeMap&) const {
+ return element == "jingle" && ns == "urn:xmpp:jingle:1";
+ }
+
+ virtual PayloadParser* createPayloadParser() {
+ return new JingleParser(factories);
+ }
+
+ private:
+ PayloadParserFactoryCollection* factories;
+
+ };
+}
+
+
diff --git a/Swiften/Parser/PayloadParsers/JingleReasonParser.cpp b/Swiften/Parser/PayloadParsers/JingleReasonParser.cpp
new file mode 100644
index 0000000..3df82ae
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleReasonParser.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "JingleReasonParser.h"
+
+#include <Swiften/Base/Log.h>
+
+namespace Swift {
+ JingleReasonParser::JingleReasonParser() : level(0), parseText(false) {
+
+ }
+
+ void JingleReasonParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap&) {
+ if (level == 1) {
+ if (element == "text") {
+ parseText = true;
+ } else {
+ // reason type
+ getPayloadInternal()->type = stringToReasonType(element);
+ }
+ }
+ ++level;
+ }
+
+ void JingleReasonParser::handleEndElement(const std::string& element, const std::string&) {
+ --level;
+ if (element == "text") {
+ parseText = false;
+ getPayloadInternal()->text = text;
+ }
+ }
+
+ void JingleReasonParser::handleCharacterData(const std::string& data) {
+ if (parseText) {
+ text += data;
+ }
+ }
+
+ JinglePayload::Reason::Type JingleReasonParser::stringToReasonType(const std::string& type) const {
+ if (type == "alternative-session") {
+ return JinglePayload::Reason::AlternativeSession;
+ } else if (type == "busy") {
+ return JinglePayload::Reason::Busy;
+ } else if (type == "cancel") {
+ return JinglePayload::Reason::Cancel;
+ } else if (type == "connectivity-error") {
+ return JinglePayload::Reason::ConnectivityError;
+ } else if (type == "decline") {
+ return JinglePayload::Reason::Decline;
+ } else if (type == "expired") {
+ return JinglePayload::Reason::Expired;
+ } else if (type == "failed-application") {
+ return JinglePayload::Reason::FailedApplication;
+ } else if (type == "failed-transport") {
+ return JinglePayload::Reason::FailedTransport;
+ } else if (type == "general-error") {
+ return JinglePayload::Reason::GeneralError;
+ } else if (type == "gone") {
+ return JinglePayload::Reason::Gone;
+ } else if (type == "incompatible-parameters") {
+ return JinglePayload::Reason::IncompatibleParameters;
+ } else if (type == "media-error") {
+ return JinglePayload::Reason::MediaError;
+ } else if (type == "security-error") {
+ return JinglePayload::Reason::SecurityError;
+ } else if (type == "success") {
+ return JinglePayload::Reason::Success;
+ } else if (type == "timeout") {
+ return JinglePayload::Reason::Timeout;
+ } else if (type == "unsupported-applications") {
+ return JinglePayload::Reason::UnsupportedApplications;
+ } else if (type == "unsupported-transports") {
+ return JinglePayload::Reason::UnsupportedTransports;
+ } else {
+ return JinglePayload::Reason::UnknownType;
+ }
+ }
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleReasonParser.h b/Swiften/Parser/PayloadParsers/JingleReasonParser.h
new file mode 100644
index 0000000..08af31a
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleReasonParser.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/JinglePayload.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+
+namespace Swift {
+
+class JingleReasonParser : public GenericPayloadParser<JinglePayload::Reason> {
+ public:
+ JingleReasonParser();
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+ private:
+ JinglePayload::Reason::Type stringToReasonType(const std::string& type) const;
+
+ private:
+ int level;
+ bool parseText;
+ std::string text;
+};
+
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp
new file mode 100644
index 0000000..14a80e6
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <boost/lexical_cast.hpp>
+#include <boost/optional.hpp>
+
+#include "JingleS5BTransportMethodPayloadParser.h"
+
+#include <Swiften/Base/Log.h>
+
+namespace Swift {
+ JingleS5BTransportMethodPayloadParser::JingleS5BTransportMethodPayloadParser() : level(0) {
+
+ }
+
+ void JingleS5BTransportMethodPayloadParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) {
+ if (level == 0) {
+ getPayloadInternal()->setSessionID(attributes.getAttributeValue("sid").get_value_or(""));
+ std::string mode = attributes.getAttributeValue("mode").get_value_or("tcp");
+ if (mode == "tcp") {
+ getPayloadInternal()->setMode(JingleS5BTransportPayload::TCPMode);
+ } else if(mode == "udp") {
+ getPayloadInternal()->setMode(JingleS5BTransportPayload::UDPMode);
+ } else {
+ std::cerr << "Unknown S5B mode; falling back to defaul!" << std::endl;
+ getPayloadInternal()->setMode(JingleS5BTransportPayload::TCPMode);
+ }
+ } else if (level == 1) {
+ if (element == "candidate") {
+ JingleS5BTransportPayload::Candidate candidate;
+ candidate.cid = attributes.getAttributeValue("cid").get_value_or("");
+
+ int port = -1;
+ try {
+ port = boost::lexical_cast<int>(attributes.getAttributeValue("port").get_value_or("-1"));
+ } catch(boost::bad_lexical_cast &) { }
+ candidate.hostPort = HostAddressPort(HostAddress(attributes.getAttributeValue("host").get_value_or("")), port);
+ candidate.jid = JID(attributes.getAttributeValue("jid").get_value_or(""));
+ int priority = -1;
+ try {
+ priority = boost::lexical_cast<int>(attributes.getAttributeValue("priority").get_value_or("-1"));
+ } catch(boost::bad_lexical_cast &) { }
+ candidate.priority = priority;
+ candidate.type = stringToType(attributes.getAttributeValue("type").get_value_or("direct"));
+
+ getPayloadInternal()->addCandidate(candidate);
+ } else if (element == "candidate-used") {
+ getPayloadInternal()->setCandidateUsed(attributes.getAttributeValue("cid").get_value_or(""));
+ } else if (element == "candidate-error") {
+ getPayloadInternal()->setCandidateError(true);
+ } else if (element == "activated") {
+ getPayloadInternal()->setActivated(attributes.getAttributeValue("cid").get_value_or(""));
+ } else if (element == "proxy-error") {
+ getPayloadInternal()->setProxyError(true);
+ }
+ }
+
+ ++level;
+ }
+
+ void JingleS5BTransportMethodPayloadParser::handleEndElement(const std::string&, const std::string&) {
+ --level;
+
+
+ }
+
+ void JingleS5BTransportMethodPayloadParser::handleCharacterData(const std::string&) {
+
+ }
+
+ JingleS5BTransportPayload::Candidate::Type JingleS5BTransportMethodPayloadParser::stringToType(const std::string &str) const {
+ if (str == "direct") {
+ return JingleS5BTransportPayload::Candidate::DirectType;
+ } else if (str == "assisted") {
+ return JingleS5BTransportPayload::Candidate::AssistedType;
+ } else if (str == "tunnel") {
+ return JingleS5BTransportPayload::Candidate::TunnelType;
+ } else if (str == "proxy") {
+ return JingleS5BTransportPayload::Candidate::ProxyType;
+ } else {
+ std::cerr << "Unknown candidate type; falling back to default!" << std::endl;
+ return JingleS5BTransportPayload::Candidate::DirectType;
+ }
+ }
+}
diff --git a/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h
new file mode 100644
index 0000000..1987d3f
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/JingleS5BTransportPayload.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+
+namespace Swift {
+
+class JingleS5BTransportMethodPayloadParser : public GenericPayloadParser<JingleS5BTransportPayload> {
+ public:
+ JingleS5BTransportMethodPayloadParser();
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+
+ private:
+ JingleS5BTransportPayload::Candidate::Type stringToType(const std::string &str) const;
+
+ private:
+ int level;
+};
+
+}
diff --git a/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp
new file mode 100644
index 0000000..6e33f16
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "S5BProxyRequestParser.h"
+
+#include <boost/lexical_cast.hpp>
+#include <boost/optional.hpp>
+
+namespace Swift {
+
+S5BProxyRequestParser::S5BProxyRequestParser() : parseActivate(false) {
+}
+
+S5BProxyRequestParser::~S5BProxyRequestParser() {
+}
+
+void S5BProxyRequestParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) {
+ if (element == "streamhost") {
+ if (attributes.getAttributeValue("host") && attributes.getAttributeValue("jid") && attributes.getAttributeValue("port")) {
+ HostAddress address = attributes.getAttributeValue("host").get_value_or("");
+ int port = -1;
+ JID jid = attributes.getAttributeValue("jid").get_value_or("");
+
+ try {
+ port = boost::lexical_cast<int>(attributes.getAttributeValue("port").get());
+ } catch (boost::bad_lexical_cast &) {
+ port = -1;
+ }
+ if (address.isValid() && port != -1 && jid.isValid()) {
+ S5BProxyRequest::StreamHost streamHost;
+ streamHost.addressPort = HostAddressPort(address, port);
+ streamHost.jid = jid;
+ getPayloadInternal()->setStreamHost(streamHost);
+ }
+ }
+ } else if (element == "activate") {
+ parseActivate = true;
+ } else if (element == "query") {
+ if (attributes.getAttributeValue("sid")) {
+ getPayloadInternal()->setSID(attributes.getAttributeValue("sid").get());
+ }
+ }
+}
+
+void S5BProxyRequestParser::handleEndElement(const std::string& element, const std::string&) {
+ if (element == "activate") {
+ JID activate = JID(activateJID);
+ if (activate.isValid()) {
+ getPayloadInternal()->setActivate(activate);
+ }
+ parseActivate = false;
+ }
+}
+
+void S5BProxyRequestParser::handleCharacterData(const std::string& data) {
+ if (parseActivate) {
+ activateJID = activateJID + data;
+ }
+}
+
+}
diff --git a/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h
new file mode 100644
index 0000000..0bf1a26
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/S5BProxyRequestParser.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <Swiften/Elements/S5BProxyRequest.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+
+namespace Swift {
+
+class S5BProxyRequestParser : public GenericPayloadParser<S5BProxyRequest> {
+public:
+ S5BProxyRequestParser();
+ virtual ~S5BProxyRequestParser();
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+
+private:
+ bool parseActivate;
+ std::string activateJID;
+};
+
+}
diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.cpp b/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.cpp
new file mode 100644
index 0000000..0a13844
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "StreamInitiationFileInfoParser.h"
+
+#include <boost/optional.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <Swiften/Base/DateTime.h>
+#include <Swiften/Base/Log.h>
+
+namespace Swift {
+
+StreamInitiationFileInfoParser::StreamInitiationFileInfoParser() : level(0), parseDescription(false) {
+
+}
+
+void StreamInitiationFileInfoParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) {
+ if (level == 0) {
+ getPayloadInternal()->setName(attributes.getAttributeValue("name").get_value_or(""));
+ getPayloadInternal()->setHash(attributes.getAttributeValue("hash").get_value_or(""));
+ getPayloadInternal()->setAlgo(attributes.getAttributeValue("algo").get_value_or("md5"));
+ try {
+ getPayloadInternal()->setSize(boost::lexical_cast<boost::uintmax_t>(attributes.getAttributeValue("size").get_value_or("0")));
+ } catch (boost::bad_lexical_cast &) {
+ getPayloadInternal()->setSize(0);
+ }
+ getPayloadInternal()->setDate(stringToDateTime(attributes.getAttributeValue("date").get_value_or("")));
+ } else if (level == 1) {
+ if (element == "desc") {
+ parseDescription = true;
+ } else {
+ parseDescription = false;
+ if (element == "range") {
+ int offset = 0;
+ try {
+ offset = boost::lexical_cast<boost::uintmax_t>(attributes.getAttributeValue("offset").get_value_or("0"));
+ } catch (boost::bad_lexical_cast &) {
+ offset = 0;
+ }
+ if (offset == 0) {
+ getPayloadInternal()->setSupportsRangeRequests(true);
+ } else {
+ getPayloadInternal()->setRangeOffset(offset);
+ }
+ }
+ }
+ }
+ ++level;
+}
+
+void StreamInitiationFileInfoParser::handleEndElement(const std::string& element, const std::string&) {
+ --level;
+ if (parseDescription && element == "desc") {
+ parseDescription = false;
+ getPayloadInternal()->setDescription(desc);
+ }
+}
+
+void StreamInitiationFileInfoParser::handleCharacterData(const std::string& data) {
+ if (parseDescription) {
+ desc += data;
+ }
+}
+
+}
diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h b/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h
new file mode 100644
index 0000000..6d3591d
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/StreamInitiationFileInfoParser.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/StreamInitiationFileInfo.h>
+#include <Swiften/Parser/GenericPayloadParser.h>
+
+namespace Swift {
+
+class StreamInitiationFileInfoParser : public GenericPayloadParser<StreamInitiationFileInfo> {
+ public:
+ StreamInitiationFileInfoParser();
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+
+ private:
+ int level;
+ bool parseDescription;
+ std::string desc;
+};
+
+}
diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp b/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp
index 9ea8089..fd3d019 100644
--- a/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp
+++ b/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp
@@ -38,9 +38,9 @@ void StreamInitiationParser::handleStartElement(const std::string& element, cons
if (element == "file") {
inFile = true;
currentFile = StreamInitiationFileInfo();
- currentFile.name = attributes.getAttribute("name");
+ currentFile.setName(attributes.getAttribute("name"));
try {
- currentFile.size = boost::lexical_cast<int>(attributes.getAttribute("size"));
+ currentFile.setSize(boost::lexical_cast<int>(attributes.getAttribute("size")));
}
catch (boost::bad_lexical_cast&) {
}
@@ -83,7 +83,7 @@ void StreamInitiationParser::handleEndElement(const std::string& element, const
}
else if (level == FileOrFeatureLevel) {
if (inFile && element == "desc") {
- currentFile.description = currentText;
+ currentFile.setDescription(currentText);
}
else if (formParser) {
Form::ref form = formParser->getPayloadInternal();
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp
new file mode 100644
index 0000000..d03ba8b
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp
@@ -0,0 +1,709 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h>
+#include <Swiften/Elements/JinglePayload.h>
+#include <Swiften/Elements/JingleIBBTransportPayload.h>
+#include <Swiften/Elements/JingleS5BTransportPayload.h>
+#include <Swiften/Elements/JingleFileTransferDescription.h>
+#include <Swiften/Elements/StreamInitiationFileInfo.h>
+#include <Swiften/Elements/JingleFileTransferReceived.h>
+#include <Swiften/Elements/JingleFileTransferHash.h>
+#include <Swiften/Base/DateTime.h>
+
+#include <Swiften/Base/Log.h>
+
+using namespace Swift;
+
+class JingleParserTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(JingleParserTest);
+ CPPUNIT_TEST(testParse_Xep0166_Example3);
+ CPPUNIT_TEST(testParse_Xep0166_Example8);
+
+ CPPUNIT_TEST(testParse_Xep0261_Example1);
+ CPPUNIT_TEST(testParse_Xep0261_Example3);
+ CPPUNIT_TEST(testParse_Xep0261_Example9);
+ CPPUNIT_TEST(testParse_Xep0261_Example13);
+
+ CPPUNIT_TEST(testParse_Xep0234_Example1);
+ CPPUNIT_TEST(testParse_Xep0234_Example3);
+ CPPUNIT_TEST(testParse_Xep0234_Example5);
+ CPPUNIT_TEST(testParse_Xep0234_Example8);
+ CPPUNIT_TEST(testParse_Xep0234_Example10);
+ CPPUNIT_TEST(testParse_Xep0234_Example11);
+ CPPUNIT_TEST(testParse_Xep0234_Example12);
+
+ CPPUNIT_TEST(testParse_Xep0260_Example1);
+ CPPUNIT_TEST(testParse_Xep0260_Example3);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ //http://xmpp.org/extensions/xep-0166.html#example-3
+ void testParse_Xep0166_Example3() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-terminate'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <reason>\n"
+ " <success/>\n"
+ " </reason>\n"
+ "</jingle>\n"
+ ));
+
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionTerminate, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::Reason::Success,
+ jingle->getReason().get_value_or(JinglePayload::Reason(JinglePayload::Reason::UnknownType, "")).type);
+ }
+
+ //http://xmpp.org/extensions/xep-0166.html#example-8
+ void testParse_Xep0166_Example8() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-terminate'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <reason>\n"
+ " <success/>\n"
+ " <text>Sorry, gotta go!</text>\n"
+ " </reason>\n"
+ "</jingle>\n"
+ ));
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionTerminate, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::Reason::Success,
+ jingle->getReason().get_value_or(JinglePayload::Reason(JinglePayload::Reason::UnknownType, "")).type);
+ CPPUNIT_ASSERT_EQUAL(std::string("Sorry, gotta go!"),
+ jingle->getReason().get_value_or(JinglePayload::Reason(JinglePayload::Reason::UnknownType, "")).text);
+ }
+
+ // IBB Transport Method Examples
+
+ // http://xmpp.org/extensions/xep-0261.html#example-1
+ void testParse_Xep0261_Example1() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-initiate'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <content creator='initiator' name='ex'>\n"
+ " <description xmlns='urn:xmpp:example'/>\n"
+ " <transport xmlns='urn:xmpp:jingle:transports:ibb:1'\n"
+ " block-size='4096'\n"
+ " sid='ch3d9s71'/>\n"
+ " </content>\n"
+ "</jingle>\n"
+ ));
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+
+ std::vector<JingleContentPayload::ref> payloads = jingle->getContents();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payloads.size());
+ JingleContentPayload::ref payload = payloads[0];
+ CPPUNIT_ASSERT_EQUAL(JingleContentPayload::InitiatorCreator, payload->getCreator());
+ CPPUNIT_ASSERT_EQUAL(std::string("ex"), payload->getName());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payload->getTransports().size());
+
+ JingleIBBTransportPayload::ref transportPaylod = payload->getTransport<JingleIBBTransportPayload>();
+ CPPUNIT_ASSERT(transportPaylod);
+ CPPUNIT_ASSERT_EQUAL(4096, transportPaylod->getBlockSize());
+ CPPUNIT_ASSERT_EQUAL(std::string("ch3d9s71"), transportPaylod->getSessionID());
+ }
+
+ // http://xmpp.org/extensions/xep-0261.html#example-1
+ void testParse_Xep0261_Example3() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-accept'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " responder='juliet@capulet.lit/balcony'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <content creator='initiator' name='ex'>\n"
+ " <description xmlns='urn:xmpp:example'/>\n"
+ " <transport xmlns='urn:xmpp:jingle:transports:ibb:1'\n"
+ " block-size='2048'\n"
+ " sid='ch3d9s71'/>\n"
+ " </content>\n"
+ " </jingle>\n"
+ ));
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionAccept, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), jingle->getResponder());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+
+ std::vector<JingleContentPayload::ref> payloads = jingle->getContents();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payloads.size());
+ JingleContentPayload::ref payload = payloads[0];
+ CPPUNIT_ASSERT_EQUAL(JingleContentPayload::InitiatorCreator, payload->getCreator());
+ CPPUNIT_ASSERT_EQUAL(std::string("ex"), payload->getName());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payload->getTransports().size());
+
+ JingleIBBTransportPayload::ref transportPaylod = payload->getTransport<JingleIBBTransportPayload>();
+ CPPUNIT_ASSERT(transportPaylod);
+ CPPUNIT_ASSERT_EQUAL(2048, transportPaylod->getBlockSize());
+ CPPUNIT_ASSERT_EQUAL(std::string("ch3d9s71"), transportPaylod->getSessionID());
+ }
+
+ // http://xmpp.org/extensions/xep-0261.html#example-9
+ void testParse_Xep0261_Example9() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='transport-info'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <content creator='initiator' name='ex'>\n"
+ " <transport xmlns='urn:xmpp:jingle:transports:ibb:1'\n"
+ " block-size='2048'\n"
+ " sid='bt8a71h6'/>\n"
+ " </content>\n"
+ "</jingle>\n"
+ ));
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::TransportInfo, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+
+ std::vector<JingleContentPayload::ref> payloads = jingle->getContents();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payloads.size());
+ JingleContentPayload::ref payload = payloads[0];
+ CPPUNIT_ASSERT_EQUAL(JingleContentPayload::InitiatorCreator, payload->getCreator());
+ CPPUNIT_ASSERT_EQUAL(std::string("ex"), payload->getName());
+
+ JingleIBBTransportPayload::ref transportPaylod = payload->getTransport<JingleIBBTransportPayload>();
+ CPPUNIT_ASSERT(transportPaylod);
+ CPPUNIT_ASSERT_EQUAL(2048, transportPaylod->getBlockSize());
+ CPPUNIT_ASSERT_EQUAL(std::string("bt8a71h6"), transportPaylod->getSessionID());
+ }
+
+ // http://xmpp.org/extensions/xep-0261.html#example-13
+ void testParse_Xep0261_Example13() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-terminate'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <reason><success/></reason>\n"
+ " </jingle>\n"
+ ));
+
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionTerminate, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::Reason::Success, jingle->getReason().get_value_or(JinglePayload::Reason()).type);
+
+ }
+
+ // Jingle File Transfer Examples
+
+ // http://xmpp.org/extensions/xep-0234.html#example-1
+ void testParse_Xep0234_Example1() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-initiate'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='851ba2'>\n"
+ " <content creator='initiator' name='a-file-offer'>\n"
+ " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n"
+ " <offer>\n"
+ " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n"
+ " date='1969-07-21T02:56:15Z'\n"
+ " hash='552da749930852c69ae5d2141d3766b1'\n"
+ " name='test.txt'\n"
+ " size='1022'>\n"
+ " <desc>This is a test. If this were a real file...</desc>\n"
+ " <range/>\n"
+ " </file>\n"
+ " </offer>\n"
+ " </description>\n"
+ " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n"
+ " mode='tcp'\n"
+ " sid='vj3hs98y'>\n"
+ " <candidate cid='hft54dqy'\n"
+ " host='192.168.4.1'\n"
+ " jid='romeo@montague.lit/orchard'\n"
+ " port='5086'\n"
+ " priority='8257636'\n"
+ " type='direct'/>\n"
+ " <candidate cid='hutr46fe'\n"
+ " host='24.24.24.1'\n"
+ " jid='romeo@montague.lit/orchard'\n"
+ " port='5087'\n"
+ " priority='8258636'\n"
+ " type='direct'/>\n"
+ " </transport>\n"
+ " </content>\n"
+ " </jingle>\n"
+ ));
+
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("851ba2"), jingle->getSessionID());
+
+ std::vector<JingleContentPayload::ref> contents = jingle->getContents();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), contents.size());
+
+ JingleFileTransferDescription::ref description = contents[0]->getDescription<JingleFileTransferDescription>();
+
+
+ std::vector<StreamInitiationFileInfo> offers = description->getOffers();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), offers.size());
+ CPPUNIT_ASSERT_EQUAL(std::string("test.txt"), offers[0].getName());
+ CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), offers[0].getHash());
+ CPPUNIT_ASSERT(1022 == offers[0].getSize());
+ CPPUNIT_ASSERT_EQUAL(std::string("This is a test. If this were a real file..."), offers[0].getDescription());
+ CPPUNIT_ASSERT_EQUAL(true, offers[0].getSupportsRangeRequests());
+ CPPUNIT_ASSERT(stringToDateTime("1969-07-21T02:56:15Z") == offers[0].getDate());
+ CPPUNIT_ASSERT_EQUAL(std::string("md5"), offers[0].getAlgo());
+ }
+
+ // http://xmpp.org/extensions/xep-0234.html#example-3
+ void testParse_Xep0234_Example3() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-accept'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='851ba2'>\n"
+ " <content creator='initiator' name='a-file-offer'>\n"
+ " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n"
+ " <offer>\n"
+ " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n"
+ " name='test.txt'\n"
+ " size='1022'\n"
+ " hash='552da749930852c69ae5d2141d3766b1'\n"
+ " date='1969-07-21T02:56:15Z'>\n"
+ " <desc>This is a test. If this were a real file...</desc>\n"
+ " <range/>\n"
+ " </file>\n"
+ " </offer>\n"
+ " </description>\n"
+ " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n"
+ " mode='tcp'\n"
+ " sid='vj3hs98y'>\n"
+ " <candidate cid='ht567dq'\n"
+ " host='192.169.1.10'\n"
+ " jid='juliet@capulet.lit/balcony'\n"
+ " port='6539'\n"
+ " priority='8257636'\n"
+ " type='direct'/>\n"
+ " <candidate cid='hr65dqyd'\n"
+ " host='134.102.201.180'\n"
+ " jid='juliet@capulet.lit/balcony'\n"
+ " port='16453'\n"
+ " priority='7929856'\n"
+ " type='assisted'/>\n"
+ " <candidate cid='grt654q2'\n"
+ " host='2001:638:708:30c9:219:d1ff:fea4:a17d'\n"
+ " jid='juliet@capulet.lit/balcony'\n"
+ " port='6539'\n"
+ " priority='8257606'\n"
+ " type='direct'/>\n"
+ " </transport>\n"
+ " </content>\n"
+ "</jingle>\n"
+ ));
+
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionAccept, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("851ba2"), jingle->getSessionID());
+
+ std::vector<JingleContentPayload::ref> contents = jingle->getContents();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), contents.size());
+
+ JingleFileTransferDescription::ref description = contents[0]->getDescription<JingleFileTransferDescription>();
+
+
+ std::vector<StreamInitiationFileInfo> offers = description->getOffers();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), offers.size());
+ CPPUNIT_ASSERT_EQUAL(std::string("test.txt"), offers[0].getName());
+ CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), offers[0].getHash());
+ CPPUNIT_ASSERT(1022 == offers[0].getSize());
+ CPPUNIT_ASSERT_EQUAL(std::string("This is a test. If this were a real file..."), offers[0].getDescription());
+ CPPUNIT_ASSERT_EQUAL(true, offers[0].getSupportsRangeRequests());
+ CPPUNIT_ASSERT(stringToDateTime("1969-07-21T02:56:15Z") == offers[0].getDate());
+ CPPUNIT_ASSERT_EQUAL(std::string("md5"), offers[0].getAlgo());
+ }
+
+ // http://xmpp.org/extensions/xep-0234.html#example-5
+ void testParse_Xep0234_Example5() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='transport-info'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <content creator='initiator' name='ex'>\n"
+ " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n"
+ " sid='vj3hs98y'>\n"
+ " <candidate-used cid='hr65dqyd'/>\n"
+ " </transport>\n"
+ " </content>\n"
+ "</jingle>\n"
+ ));
+
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::TransportInfo, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+
+ std::vector<JingleContentPayload::ref> contents = jingle->getContents();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), contents.size());
+
+ JingleS5BTransportPayload::ref transport = contents[0]->getTransport<JingleS5BTransportPayload>();
+ CPPUNIT_ASSERT(transport);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("vj3hs98y"), transport->getSessionID());
+ CPPUNIT_ASSERT_EQUAL(std::string("hr65dqyd"), transport->getCandidateUsed());
+ }
+
+ // http://xmpp.org/extensions/xep-0234.html#example-8
+ void testParse_Xep0234_Example8() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-info'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <checksum xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n"
+ " <file>\n"
+ " <hashes xmlns='urn:xmpp:hashes:0'>\n"
+ " <hash algo='sha-1'>552da749930852c69ae5d2141d3766b1</hash>\n"
+ " </hashes>\n"
+ " </file>\n"
+ " </checksum>\n"
+ "</jingle>\n"
+ ));
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInfo, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+
+ JingleFileTransferHash::ref hash = jingle->getPayload<JingleFileTransferHash>();
+ CPPUNIT_ASSERT(hash);
+ CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), hash->getHashes().at("sha-1"));
+
+ }
+
+ // http://xmpp.org/extensions/xep-0234.html#example-10
+ void testParse_Xep0234_Example10() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-initiate'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='uj3b2'>\n"
+ " <content creator='initiator' name='a-file-request'>\n"
+ " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n"
+ " <request>\n"
+ " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n"
+ " hash='552da749930852c69ae5d2141d3766b1'>\n"
+ " <range offset='270336'/>\n"
+ " </file>\n"
+ " </request>\n"
+ " </description>\n"
+ " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n"
+ " mode='tcp'\n"
+ " sid='xig361fj'>\n"
+ " <candidate cid='ht567dq'\n"
+ " host='192.169.1.10'\n"
+ " jid='juliet@capulet.lit/balcony'\n"
+ " port='6539'\n"
+ " priority='8257636'\n"
+ " type='direct'/>\n"
+ " <candidate cid='hr65dqyd'\n"
+ " host='134.102.201.180'\n"
+ " jid='juliet@capulet.lit/balcony'\n"
+ " port='16453'\n"
+ " priority='7929856'\n"
+ " type='assisted'/>\n"
+ " <candidate cid='grt654q2'\n"
+ " host='2001:638:708:30c9:219:d1ff:fea4:a17d'\n"
+ " jid='juliet@capulet.lit/balcony'\n"
+ " port='6539'\n"
+ " priority='8257606'\n"
+ " type='direct'/>\n"
+ " </transport>\n"
+ " </content>\n"
+ "</jingle>\n"
+ ));
+
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("uj3b2"), jingle->getSessionID());
+
+ JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>();
+ CPPUNIT_ASSERT(content);
+
+ StreamInitiationFileInfo file = content->getDescription<JingleFileTransferDescription>()->getRequests()[0];
+ CPPUNIT_ASSERT_EQUAL(std::string("552da749930852c69ae5d2141d3766b1"), file.getHash());
+ CPPUNIT_ASSERT_EQUAL(270336, file.getRangeOffset());
+ CPPUNIT_ASSERT_EQUAL(true, file.getSupportsRangeRequests());
+ }
+
+ // http://xmpp.org/extensions/xep-0234.html#example-11
+ void testParse_Xep0234_Example11() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-initiate'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='h2va419i'>\n"
+ " <content creator='initiator' name='a-file-offer'>\n"
+ " <description xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n"
+ " <offer>\n"
+ " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n"
+ " date='2011-06-01T15:58:15Z'\n"
+ " hash='a749930852c69ae5d2141d3766b1552d'\n"
+ " name='somefile.txt'\n"
+ " size='1234'/>\n"
+ " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n"
+ " date='2011-06-01T15:58:15Z'\n"
+ " hash='930852c69ae5d2141d3766b1552da749'\n"
+ " name='anotherfile.txt'\n"
+ " size='2345'/>\n"
+ " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n"
+ " date='2011-06-01T15:58:15Z'\n"
+ " hash='52c69ae5d2141d3766b1552da7499308'\n"
+ " name='yetanotherfile.txt'\n"
+ " size='3456'/>\n"
+ " </offer>\n"
+ " </description>\n"
+ " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n"
+ " mode='tcp'\n"
+ " sid='vj3hs98y'>\n"
+ " <candidate cid='hft54dqy'\n"
+ " host='192.168.4.1'\n"
+ " jid='romeo@montague.lit/orchard'\n"
+ " port='5086'\n"
+ " priority='8257636'\n"
+ " type='direct'/>\n"
+ " <candidate cid='hutr46fe'\n"
+ " host='24.24.24.1'\n"
+ " jid='romeo@montague.lit/orchard'\n"
+ " port='5087'\n"
+ " priority='8258636'\n"
+ " type='direct'/>\n"
+ " </transport>\n"
+ " </content>\n"
+ "</jingle>\n"
+ ));
+
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("h2va419i"), jingle->getSessionID());
+
+ JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>();
+ CPPUNIT_ASSERT(content);
+ CPPUNIT_ASSERT_EQUAL(JingleContentPayload::InitiatorCreator, content->getCreator());
+ CPPUNIT_ASSERT_EQUAL(std::string("a-file-offer"), content->getName());
+
+ std::vector<StreamInitiationFileInfo> offers = content->getDescription<JingleFileTransferDescription>()->getOffers();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), offers.size());
+ }
+
+ // http://xmpp.org/extensions/xep-0234.html#example-12
+ void testParse_Xep0234_Example12() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-info'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <received xmlns='urn:xmpp:jingle:apps:file-transfer:3'>\n"
+ " <file xmlns='http://jabber.org/protocol/si/profile/file-transfer'\n"
+ " hash='a749930852c69ae5d2141d3766b1552d'/>\n"
+ " </received>\n"
+ "</jingle>\n"
+ ));
+
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInfo, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+
+ boost::shared_ptr<JingleFileTransferReceived> received = jingle->getPayload<JingleFileTransferReceived>();
+ CPPUNIT_ASSERT(received);
+ CPPUNIT_ASSERT_EQUAL(std::string("a749930852c69ae5d2141d3766b1552d"), received->getFileInfo().getHash());
+ }
+
+ // http://xmpp.org/extensions/xep-0260.html#example-1
+ void testParse_Xep0260_Example1() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-initiate'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <content creator='initiator' name='ex'>\n"
+ " <description xmlns='urn:xmpp:example'/>\n"
+ " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n"
+ " mode='tcp'\n"
+ " sid='vj3hs98y'>\n"
+ " <candidate cid='hft54dqy'\n"
+ " host='192.168.4.1'\n"
+ " jid='romeo@montague.lit/orchard'\n"
+ " port='5086'\n"
+ " priority='8257636'\n"
+ " type='direct'/>\n"
+ " <candidate cid='hutr46fe'\n"
+ " host='24.24.24.1'\n"
+ " jid='romeo@montague.lit/orchard'\n"
+ " port='5087'\n"
+ " priority='8258636'\n"
+ " type='direct'/>\n"
+ " </transport>\n"
+ " </content>\n"
+ "</jingle>\n"
+ ));
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionInitiate, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+
+ JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>();
+ CPPUNIT_ASSERT(content);
+
+ JingleS5BTransportPayload::ref s5bPayload = content->getTransport<JingleS5BTransportPayload>();
+ CPPUNIT_ASSERT(s5bPayload);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("vj3hs98y"), s5bPayload->getSessionID());
+ CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::TCPMode, s5bPayload->getMode());
+ CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasCandidateError());
+ CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasProxyError());
+ CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getActivated());
+ CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getCandidateUsed());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), s5bPayload->getCandidates().size());
+
+ JingleS5BTransportPayload::Candidate candidate;
+ candidate = s5bPayload->getCandidates()[0];
+ CPPUNIT_ASSERT_EQUAL(std::string("hft54dqy"), candidate.cid);
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), candidate.jid);
+ CPPUNIT_ASSERT(HostAddressPort(HostAddress("192.168.4.1"), 5086) == candidate.hostPort);
+ CPPUNIT_ASSERT_EQUAL(8257636, candidate.priority);
+ CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type);
+
+ candidate = s5bPayload->getCandidates()[1];
+ CPPUNIT_ASSERT_EQUAL(std::string("hutr46fe"), candidate.cid);
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), candidate.jid);
+ CPPUNIT_ASSERT(HostAddressPort(HostAddress("24.24.24.1"), 5087) == candidate.hostPort);
+ CPPUNIT_ASSERT_EQUAL(8258636, candidate.priority);
+ CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type);
+ }
+
+ // http://xmpp.org/extensions/xep-0260.html#example-3
+ void testParse_Xep0260_Example3() {
+ PayloadsParserTester parser;
+ CPPUNIT_ASSERT(parser.parse(
+ "<jingle xmlns='urn:xmpp:jingle:1'\n"
+ " action='session-accept'\n"
+ " initiator='romeo@montague.lit/orchard'\n"
+ " sid='a73sjjvkla37jfea'>\n"
+ " <content creator='initiator' name='ex'>\n"
+ " <description xmlns='urn:xmpp:example'/>\n"
+ " <transport xmlns='urn:xmpp:jingle:transports:s5b:1'\n"
+ " mode='tcp'\n"
+ " sid='vj3hs98y'>\n"
+ " <candidate cid='ht567dq'\n"
+ " host='192.169.1.10'\n"
+ " jid='juliet@capulet.lit/balcony'\n"
+ " port='6539'\n"
+ " priority='8257636'\n"
+ " type='direct'/>\n"
+ " <candidate cid='hr65dqyd'\n"
+ " host='134.102.201.180'\n"
+ " jid='juliet@capulet.lit/balcony'\n"
+ " port='16453'\n"
+ " priority='7929856'\n"
+ " type='assisted'/>\n"
+ " <candidate cid='grt654q2'\n"
+ " host='2001:638:708:30c9:219:d1ff:fea4:a17d'\n"
+ " jid='juliet@capulet.lit/balcony'\n"
+ " port='6539'\n"
+ " priority='8257606'\n"
+ " type='direct'/>\n"
+ " </transport>\n"
+ " </content>\n"
+ "</jingle>\n"
+ ));
+
+ JinglePayload::ref jingle = parser.getPayload<JinglePayload>();
+ CPPUNIT_ASSERT(jingle);
+ CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionAccept, jingle->getAction());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator());
+ CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID());
+
+ JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>();
+ CPPUNIT_ASSERT(content);
+
+ JingleS5BTransportPayload::ref s5bPayload = content->getTransport<JingleS5BTransportPayload>();
+ CPPUNIT_ASSERT(s5bPayload);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("vj3hs98y"), s5bPayload->getSessionID());
+ CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::TCPMode, s5bPayload->getMode());
+ CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasCandidateError());
+ CPPUNIT_ASSERT_EQUAL(false, s5bPayload->hasProxyError());
+ CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getActivated());
+ CPPUNIT_ASSERT_EQUAL(std::string(), s5bPayload->getCandidateUsed());
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), s5bPayload->getCandidates().size());
+
+ JingleS5BTransportPayload::Candidate candidate;
+ candidate = s5bPayload->getCandidates()[0];
+ CPPUNIT_ASSERT_EQUAL(std::string("ht567dq"), candidate.cid);
+ CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), candidate.jid);
+ CPPUNIT_ASSERT(HostAddressPort(HostAddress("192.169.1.10"), 6539) == candidate.hostPort);
+ CPPUNIT_ASSERT_EQUAL(8257636, candidate.priority);
+ CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type);
+
+ candidate = s5bPayload->getCandidates()[1];
+ CPPUNIT_ASSERT_EQUAL(std::string("hr65dqyd"), candidate.cid);
+ CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), candidate.jid);
+ CPPUNIT_ASSERT(HostAddressPort(HostAddress("134.102.201.180"), 16453) == candidate.hostPort);
+ CPPUNIT_ASSERT_EQUAL(7929856, candidate.priority);
+ CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::AssistedType, candidate.type);
+
+ candidate = s5bPayload->getCandidates()[2];
+ CPPUNIT_ASSERT_EQUAL(std::string("grt654q2"), candidate.cid);
+ CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), candidate.jid);
+ CPPUNIT_ASSERT(HostAddressPort(HostAddress("2001:638:708:30c9:219:d1ff:fea4:a17d"), 6539) == candidate.hostPort);
+ CPPUNIT_ASSERT_EQUAL(8257606, candidate.priority);
+ CPPUNIT_ASSERT_EQUAL(JingleS5BTransportPayload::Candidate::DirectType, candidate.type);
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(JingleParserTest);
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp
index 47b2816..63a6c9b 100644
--- a/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp
+++ b/Swiften/Parser/PayloadParsers/UnitTest/StreamInitiationParserTest.cpp
@@ -42,9 +42,9 @@ class StreamInitiationParserTest : public CppUnit::TestFixture {
StreamInitiation::ref si = parser.getPayload<StreamInitiation>();
CPPUNIT_ASSERT(si->getIsFileTransfer());
CPPUNIT_ASSERT(si->getFileInfo());
- CPPUNIT_ASSERT_EQUAL(std::string("test.txt"), si->getFileInfo()->name);
- CPPUNIT_ASSERT_EQUAL(1022, si->getFileInfo()->size);
- CPPUNIT_ASSERT_EQUAL(std::string("This is info about the file."), si->getFileInfo()->description);
+ CPPUNIT_ASSERT_EQUAL(std::string("test.txt"), si->getFileInfo()->getName());
+ CPPUNIT_ASSERT(1022 == si->getFileInfo()->getSize());
+ CPPUNIT_ASSERT_EQUAL(std::string("This is info about the file."), si->getFileInfo()->getDescription());
CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(si->getProvidedMethods().size()));
CPPUNIT_ASSERT_EQUAL(std::string("http://jabber.org/protocol/bytestreams"), si->getProvidedMethods()[0]);
CPPUNIT_ASSERT_EQUAL(std::string("jabber:iq:oob"), si->getProvidedMethods()[1]);