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/Serializer
parent07402c4e3451f2084a1c3ddc5bacfb38a66899a7 (diff)
downloadswift-1b58ef2af54456004390a0888c3edf104e3baa99.zip
swift-1b58ef2af54456004390a0888c3edf104e3baa99.tar.bz2
Added beginnings of outgoing file transfer to Swiften.
Diffstat (limited to 'Swiften/Serializer')
-rw-r--r--Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.cpp41
-rw-r--r--Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h21
-rw-r--r--Swiften/Serializer/PayloadSerializers/FormSerializer.cpp4
-rw-r--r--Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp6
-rw-r--r--Swiften/Serializer/PayloadSerializers/IBBSerializer.cpp54
-rw-r--r--Swiften/Serializer/PayloadSerializers/IBBSerializer.h21
-rw-r--r--Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp74
-rw-r--r--Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h21
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp4
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp69
10 files changed, 312 insertions, 3 deletions
diff --git a/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.cpp b/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.cpp
new file mode 100644
index 0000000..9acabee
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+#include "Swiften/Serializer/PayloadSerializerCollection.h"
+
+
+namespace Swift {
+
+BytestreamsSerializer::BytestreamsSerializer() {
+}
+
+String BytestreamsSerializer::serializePayload(boost::shared_ptr<Bytestreams> bytestreams) const {
+ XMLElement queryElement("query", "http://jabber.org/protocol/bytestreams");
+ queryElement.setAttribute("sid", bytestreams->getStreamID());
+ foreach(const Bytestreams::StreamHost& streamHost, bytestreams->getStreamHosts()) {
+ boost::shared_ptr<XMLElement> streamHostElement(new XMLElement("streamhost"));
+ streamHostElement->setAttribute("host", streamHost.host);
+ streamHostElement->setAttribute("jid", streamHost.jid.toString());
+ streamHostElement->setAttribute("port", boost::lexical_cast<std::string>(streamHost.port));
+ queryElement.addNode(streamHostElement);
+ }
+
+ if (bytestreams->getUsedStreamHost()) {
+ boost::shared_ptr<XMLElement> streamHostElement(new XMLElement("streamhost-used"));
+ streamHostElement->setAttribute("jid", *bytestreams->getUsedStreamHost());
+ queryElement.addNode(streamHostElement);
+ }
+ return queryElement.serialize();
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h b/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h
new file mode 100644
index 0000000..50d58c2
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/BytestreamsSerializer.h
@@ -0,0 +1,21 @@
+/*
+ * 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/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/Bytestreams.h"
+
+namespace Swift {
+ class PayloadSerializerCollection;
+
+ class BytestreamsSerializer : public GenericPayloadSerializer<Bytestreams> {
+ public:
+ BytestreamsSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<Bytestreams>) const;
+ };
+}
diff --git a/Swiften/Serializer/PayloadSerializers/FormSerializer.cpp b/Swiften/Serializer/PayloadSerializers/FormSerializer.cpp
index ece8fd8..77c2fd4 100644
--- a/Swiften/Serializer/PayloadSerializers/FormSerializer.cpp
+++ b/Swiften/Serializer/PayloadSerializers/FormSerializer.cpp
@@ -145,7 +145,9 @@ boost::shared_ptr<XMLElement> FormSerializer::fieldToXML(boost::shared_ptr<FormF
foreach (const FormField::Option& option, field->getOptions()) {
boost::shared_ptr<XMLElement> optionElement(new XMLElement("option"));
- optionElement->setAttribute("label", option.label);
+ if (!option.label.isEmpty()) {
+ optionElement->setAttribute("label", option.label);
+ }
boost::shared_ptr<XMLElement> valueElement(new XMLElement("value"));
valueElement->addNode(XMLTextNode::create(option.value));
diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
index 8598f17..1d04456 100644
--- a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
+++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
@@ -7,6 +7,7 @@
#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"
#include "Swiften/Base/foreach.h"
#include "Swiften/Serializer/PayloadSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/IBBSerializer.h"
#include "Swiften/Serializer/PayloadSerializers/BodySerializer.h"
#include "Swiften/Serializer/PayloadSerializers/SubjectSerializer.h"
#include "Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h"
@@ -26,6 +27,8 @@
#include "Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h"
#include "Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h"
#include "Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/ByteStreamsSerializer.h"
#include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h"
#include "Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h"
#include "Swiften/Serializer/PayloadSerializers/RawXMLPayloadSerializer.h"
@@ -39,6 +42,7 @@
namespace Swift {
FullPayloadSerializerCollection::FullPayloadSerializerCollection() {
+ serializers_.push_back(new IBBSerializer());
serializers_.push_back(new BodySerializer());
serializers_.push_back(new SubjectSerializer());
serializers_.push_back(new ChatStateSerializer());
@@ -58,6 +62,8 @@ FullPayloadSerializerCollection::FullPayloadSerializerCollection() {
serializers_.push_back(new StartSessionSerializer());
serializers_.push_back(new SecurityLabelSerializer());
serializers_.push_back(new SecurityLabelsCatalogSerializer());
+ serializers_.push_back(new StreamInitiationSerializer());
+ serializers_.push_back(new BytestreamsSerializer());
serializers_.push_back(new VCardSerializer());
serializers_.push_back(new VCardUpdateSerializer());
serializers_.push_back(new RawXMLPayloadSerializer());
diff --git a/Swiften/Serializer/PayloadSerializers/IBBSerializer.cpp b/Swiften/Serializer/PayloadSerializers/IBBSerializer.cpp
new file mode 100644
index 0000000..5e52145
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/IBBSerializer.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swiften/Serializer/PayloadSerializers/IBBSerializer.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+#include "Swiften/Serializer/PayloadSerializerCollection.h"
+#include "Swiften/StringCodecs/Base64.h"
+
+namespace Swift {
+
+IBBSerializer::IBBSerializer() {
+}
+
+String IBBSerializer::serializePayload(boost::shared_ptr<IBB> ibb) const {
+ switch(ibb->getAction()) {
+ case IBB::Data: {
+ XMLElement ibbElement("data", "http://jabber.org/protocol/ibb");
+ ibbElement.setAttribute("sid", ibb->getStreamID());
+ if (ibb->getSequenceNumber() >= 0) {
+ ibbElement.setAttribute("seq", boost::lexical_cast<std::string>(ibb->getSequenceNumber()));
+ }
+ ibbElement.addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(Base64::encode(ibb->getData()))));
+ return ibbElement.serialize();
+ }
+ case IBB::Open: {
+ XMLElement ibbElement("open", "http://jabber.org/protocol/ibb");
+ ibbElement.setAttribute("sid", ibb->getStreamID());
+ switch (ibb->getStanzaType()) {
+ case IBB::IQStanza: ibbElement.setAttribute("stanza", "iq"); break;
+ case IBB::MessageStanza: ibbElement.setAttribute("stanza", "message"); break;
+ }
+ assert(ibb->getBlockSize() > 0);
+ ibbElement.setAttribute("block-size", boost::lexical_cast<std::string>(ibb->getBlockSize()));
+ return ibbElement.serialize();
+ }
+ case IBB::Close: {
+ XMLElement ibbElement("close", "http://jabber.org/protocol/ibb");
+ ibbElement.setAttribute("sid", ibb->getStreamID());
+ return ibbElement.serialize();
+ }
+ }
+ return "";
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/IBBSerializer.h b/Swiften/Serializer/PayloadSerializers/IBBSerializer.h
new file mode 100644
index 0000000..71b1c80
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/IBBSerializer.h
@@ -0,0 +1,21 @@
+/*
+ * 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/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/IBB.h"
+
+namespace Swift {
+ class PayloadSerializerCollection;
+
+ class IBBSerializer : public GenericPayloadSerializer<IBB> {
+ public:
+ IBBSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<IBB>) const;
+ };
+}
diff --git a/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp b/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp
new file mode 100644
index 0000000..71702d0
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h"
+
+#include <boost/shared_ptr.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+#include "Swiften/Serializer/XML/XMLRawTextNode.h"
+#include "Swiften/Serializer/PayloadSerializerCollection.h"
+#include "Swiften/Serializer/PayloadSerializers/FormSerializer.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 {
+
+StreamInitiationSerializer::StreamInitiationSerializer() {
+}
+
+String StreamInitiationSerializer::serializePayload(boost::shared_ptr<StreamInitiation> streamInitiation) const {
+ assert(streamInitiation->getIsFileTransfer());
+
+ XMLElement siElement("si", "http://jabber.org/protocol/si");
+ if (!streamInitiation->getID().isEmpty()) {
+ siElement.setAttribute("id", streamInitiation->getID());
+ }
+ siElement.setAttribute("profile", FILE_TRANSFER_NS);
+
+ if (streamInitiation->getFileInfo()) {
+ StreamInitiation::FileInfo file = *streamInitiation->getFileInfo();
+ boost::shared_ptr<XMLElement> fileElement(new XMLElement("file", "http://jabber.org/protocol/si/profile/file-transfer"));
+ fileElement->setAttribute("name", file.name);
+ if (file.size != -1) {
+ fileElement->setAttribute("size", boost::lexical_cast<std::string>(file.size));
+ }
+ if (!file.description.isEmpty()) {
+ boost::shared_ptr<XMLElement> descElement(new XMLElement("desc"));
+ descElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(file.description)));
+ fileElement->addNode(descElement);
+ }
+ siElement.addNode(fileElement);
+ }
+
+ boost::shared_ptr<XMLElement> featureElement(new XMLElement("feature", "http://jabber.org/protocol/feature-neg"));
+ if (streamInitiation->getProvidedMethods().size() > 0) {
+ Form::ref form(new Form(Form::FormType));
+ ListSingleFormField::ref field = ListSingleFormField::create();
+ field->setName("stream-method");
+ foreach(const String& method, streamInitiation->getProvidedMethods()) {
+ field->addOption(FormField::Option("", method));
+ }
+ form->addField(field);
+ featureElement->addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(FormSerializer().serialize(form))));
+ }
+ else if (!streamInitiation->getRequestedMethod().isEmpty()) {
+ Form::ref form(new Form(Form::SubmitType));
+ ListSingleFormField::ref field = ListSingleFormField::create(streamInitiation->getRequestedMethod());
+ field->setName("stream-method");
+ form->addField(field);
+ featureElement->addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(FormSerializer().serialize(form))));
+ }
+ siElement.addNode(featureElement);
+ return siElement.serialize();
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h b/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h
new file mode 100644
index 0000000..35c71b9
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.h
@@ -0,0 +1,21 @@
+/*
+ * 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/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/StreamInitiation.h"
+
+namespace Swift {
+ class PayloadSerializerCollection;
+
+ class StreamInitiationSerializer : public GenericPayloadSerializer<StreamInitiation> {
+ public:
+ StreamInitiationSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<StreamInitiation>) const;
+ };
+}
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp
index ebc8664..4ed3ba9 100644
--- a/Swiften/Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp
@@ -84,7 +84,7 @@ class FormSerializerTest : public CppUnit::TestFixture {
field->addOption(FormField::Option("30", "30"));
field->addOption(FormField::Option("50", "50"));
field->addOption(FormField::Option("100", "100"));
- field->addOption(FormField::Option("None", "none"));
+ field->addOption(FormField::Option("", "none"));
form->addField(field);
std::vector<JID> jids;
@@ -132,7 +132,7 @@ class FormSerializerTest : public CppUnit::TestFixture {
"<option label=\"30\"><value>30</value></option>"
"<option label=\"50\"><value>50</value></option>"
"<option label=\"100\"><value>100</value></option>"
- "<option label=\"None\"><value>none</value></option>"
+ "<option><value>none</value></option>"
"</field>"
"<field label=\"People to invite\" type=\"jid-multi\" var=\"invitelist\">"
"<desc>Tell all your friends about your new bot!</desc>"
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp
new file mode 100644
index 0000000..12c8485
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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/Serializer/PayloadSerializers/StreamInitiationSerializer.h"
+
+using namespace Swift;
+
+class StreamInitiationSerializerTest : public CppUnit::TestFixture{
+ CPPUNIT_TEST_SUITE(StreamInitiationSerializerTest);
+ CPPUNIT_TEST(testSerialize_Request);
+ CPPUNIT_TEST(testSerialize_Response);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void testSerialize_Request() {
+ StreamInitiationSerializer testling;
+ boost::shared_ptr<StreamInitiation> streamInitiation(new StreamInitiation());
+ StreamInitiation::FileInfo fileInfo("test.txt", "This is info about the file.", 1022);
+ streamInitiation->setID("a0");
+ streamInitiation->setFileInfo(fileInfo);
+ streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams");
+ streamInitiation->addProvidedMethod("jabber:iq:oob");
+ streamInitiation->addProvidedMethod("http://jabber.org/protocol/ibb");
+
+ CPPUNIT_ASSERT_EQUAL(String(
+ "<si id=\"a0\" profile=\"http://jabber.org/protocol/si/profile/file-transfer\" xmlns=\"http://jabber.org/protocol/si\">"
+ "<file name=\"test.txt\" size=\"1022\" xmlns=\"http://jabber.org/protocol/si/profile/file-transfer\">"
+ "<desc>This is info about the file.</desc>"
+ "</file>"
+ "<feature xmlns=\"http://jabber.org/protocol/feature-neg\">"
+ "<x type=\"form\" xmlns=\"jabber:x:data\">"
+ "<field type=\"list-single\" var=\"stream-method\">"
+ "<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>"
+ ), testling.serialize(streamInitiation));
+ }
+
+ void testSerialize_Response() {
+ StreamInitiationSerializer testling;
+ boost::shared_ptr<StreamInitiation> streamInitiation(new StreamInitiation());
+ streamInitiation->setRequestedMethod("http://jabber.org/protocol/bytestreams");
+
+ CPPUNIT_ASSERT_EQUAL(String(
+ "<si profile=\"http://jabber.org/protocol/si/profile/file-transfer\" xmlns=\"http://jabber.org/protocol/si\">"
+ "<feature xmlns=\"http://jabber.org/protocol/feature-neg\">"
+ "<x type=\"submit\" xmlns=\"jabber:x:data\">"
+ "<field type=\"list-single\" var=\"stream-method\">"
+ "<value>http://jabber.org/protocol/bytestreams</value>"
+ "</field>"
+ "</x>"
+ "</feature>"
+ "</si>"
+ ), testling.serialize(streamInitiation));
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(StreamInitiationSerializerTest);