summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Serializer')
-rw-r--r--Swiften/Serializer/AuthFailureSerializer.h22
-rw-r--r--Swiften/Serializer/AuthRequestSerializer.cpp17
-rw-r--r--Swiften/Serializer/AuthRequestSerializer.h18
-rw-r--r--Swiften/Serializer/AuthSuccessSerializer.h22
-rw-r--r--Swiften/Serializer/CompressFailureSerializer.h22
-rw-r--r--Swiften/Serializer/CompressRequestSerializer.cpp19
-rw-r--r--Swiften/Serializer/CompressRequestSerializer.h18
-rw-r--r--Swiften/Serializer/ElementSerializer.cpp8
-rw-r--r--Swiften/Serializer/ElementSerializer.h19
-rw-r--r--Swiften/Serializer/GenericElementSerializer.h18
-rw-r--r--Swiften/Serializer/GenericPayloadSerializer.h25
-rw-r--r--Swiften/Serializer/GenericStanzaSerializer.h29
-rw-r--r--Swiften/Serializer/IQSerializer.h30
-rw-r--r--Swiften/Serializer/Makefile.inc15
-rw-r--r--Swiften/Serializer/MessageSerializer.cpp27
-rw-r--r--Swiften/Serializer/MessageSerializer.h21
-rw-r--r--Swiften/Serializer/PayloadSerializer.cpp8
-rw-r--r--Swiften/Serializer/PayloadSerializer.h19
-rw-r--r--Swiften/Serializer/PayloadSerializerCollection.cpp27
-rw-r--r--Swiften/Serializer/PayloadSerializerCollection.h26
-rw-r--r--Swiften/Serializer/PayloadSerializers/BodySerializer.h20
-rw-r--r--Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.cpp20
-rw-r--r--Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h16
-rw-r--r--Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.cpp36
-rw-r--r--Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h16
-rw-r--r--Swiften/Serializer/PayloadSerializers/ErrorSerializer.cpp56
-rw-r--r--Swiften/Serializer/PayloadSerializers/ErrorSerializer.h16
-rw-r--r--Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp49
-rw-r--r--Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h19
-rw-r--r--Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.cpp13
-rw-r--r--Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h16
-rw-r--r--Swiften/Serializer/PayloadSerializers/Makefile.inc13
-rw-r--r--Swiften/Serializer/PayloadSerializers/PrioritySerializer.h20
-rw-r--r--Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.cpp28
-rw-r--r--Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h16
-rw-r--r--Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp45
-rw-r--r--Swiften/Serializer/PayloadSerializers/RosterSerializer.h16
-rw-r--r--Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.cpp38
-rw-r--r--Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h16
-rw-r--r--Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp30
-rw-r--r--Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h16
-rw-r--r--Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp23
-rw-r--r--Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h16
-rw-r--r--Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h20
-rw-r--r--Swiften/Serializer/PayloadSerializers/StatusSerializer.h22
-rw-r--r--Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h33
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp25
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/DiscoInfoSerializerTest.cpp38
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/ErrorSerializerTest.cpp25
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/Makefile.inc12
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/PrioritySerializerTest.cpp25
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/ResourceBindSerializerTest.cpp49
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp48
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelSerializerTest.cpp43
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp52
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp25
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp25
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp58
-rw-r--r--Swiften/Serializer/PresenceSerializer.cpp27
-rw-r--r--Swiften/Serializer/PresenceSerializer.h21
-rw-r--r--Swiften/Serializer/StanzaSerializer.cpp50
-rw-r--r--Swiften/Serializer/StanzaSerializer.h25
-rw-r--r--Swiften/Serializer/StartTLSFailureSerializer.h22
-rw-r--r--Swiften/Serializer/StartTLSRequestSerializer.h22
-rw-r--r--Swiften/Serializer/StreamFeaturesSerializer.cpp46
-rw-r--r--Swiften/Serializer/StreamFeaturesSerializer.h18
-rw-r--r--Swiften/Serializer/TLSProceedSerializer.h22
-rw-r--r--Swiften/Serializer/UnitTest/Makefile.inc2
-rw-r--r--Swiften/Serializer/UnitTest/StreamFeaturesSerializerTest.cpp46
-rw-r--r--Swiften/Serializer/XML/Makefile.inc5
-rw-r--r--Swiften/Serializer/XML/UnitTest/Makefile.inc2
-rw-r--r--Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp62
-rw-r--r--Swiften/Serializer/XML/XMLElement.cpp49
-rw-r--r--Swiften/Serializer/XML/XMLElement.h27
-rw-r--r--Swiften/Serializer/XML/XMLNode.cpp8
-rw-r--r--Swiften/Serializer/XML/XMLNode.h15
-rw-r--r--Swiften/Serializer/XML/XMLRawTextNode.h21
-rw-r--r--Swiften/Serializer/XML/XMLTextNode.h23
-rw-r--r--Swiften/Serializer/XMPPSerializer.cpp58
-rw-r--r--Swiften/Serializer/XMPPSerializer.h28
80 files changed, 2063 insertions, 0 deletions
diff --git a/Swiften/Serializer/AuthFailureSerializer.h b/Swiften/Serializer/AuthFailureSerializer.h
new file mode 100644
index 0000000..e7e2ced
--- /dev/null
+++ b/Swiften/Serializer/AuthFailureSerializer.h
@@ -0,0 +1,22 @@
+#ifndef SWIFTEN_AuthFailureSerializer_H
+#define SWIFTEN_AuthFailureSerializer_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/AuthFailure.h"
+#include "Swiften/Serializer/GenericElementSerializer.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+ class AuthFailureSerializer : public GenericElementSerializer<AuthFailure> {
+ public:
+ AuthFailureSerializer() : GenericElementSerializer<AuthFailure>() {
+ }
+
+ virtual String serialize(boost::shared_ptr<Element>) const {
+ return XMLElement("failure", "urn:ietf:params:xml:ns:xmpp-sasl").serialize();
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/AuthRequestSerializer.cpp b/Swiften/Serializer/AuthRequestSerializer.cpp
new file mode 100644
index 0000000..7122485
--- /dev/null
+++ b/Swiften/Serializer/AuthRequestSerializer.cpp
@@ -0,0 +1,17 @@
+#include "Swiften/Serializer/AuthRequestSerializer.h"
+
+#include "Swiften/Elements/AuthRequest.h"
+#include "Swiften/StringCodecs/Base64.h"
+
+namespace Swift {
+
+AuthRequestSerializer::AuthRequestSerializer() {
+}
+
+String AuthRequestSerializer::serialize(boost::shared_ptr<Element> element) const {
+ boost::shared_ptr<AuthRequest> authRequest(boost::dynamic_pointer_cast<AuthRequest>(element));
+ String value = (authRequest->getMessage().isEmpty() ? "=" : Base64::encode(authRequest->getMessage()));
+ return "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"" + authRequest->getMechanism() + "\">" + value + "</auth>";
+}
+
+}
diff --git a/Swiften/Serializer/AuthRequestSerializer.h b/Swiften/Serializer/AuthRequestSerializer.h
new file mode 100644
index 0000000..b5131a3
--- /dev/null
+++ b/Swiften/Serializer/AuthRequestSerializer.h
@@ -0,0 +1,18 @@
+#ifndef SWIFTEN_AuthRequestSerializer_H
+#define SWIFTEN_AuthRequestSerializer_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/AuthRequest.h"
+#include "Swiften/Serializer/GenericElementSerializer.h"
+
+namespace Swift {
+ class AuthRequestSerializer : public GenericElementSerializer<AuthRequest> {
+ public:
+ AuthRequestSerializer();
+
+ virtual String serialize(boost::shared_ptr<Element> element) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/AuthSuccessSerializer.h b/Swiften/Serializer/AuthSuccessSerializer.h
new file mode 100644
index 0000000..1fdc3ab
--- /dev/null
+++ b/Swiften/Serializer/AuthSuccessSerializer.h
@@ -0,0 +1,22 @@
+#ifndef SWIFTEN_AuthSuccessSerializer_H
+#define SWIFTEN_AuthSuccessSerializer_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/AuthSuccess.h"
+#include "Swiften/Serializer/GenericElementSerializer.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+ class AuthSuccessSerializer : public GenericElementSerializer<AuthSuccess> {
+ public:
+ AuthSuccessSerializer() : GenericElementSerializer<AuthSuccess>() {
+ }
+
+ virtual String serialize(boost::shared_ptr<Element>) const {
+ return XMLElement("success", "urn:ietf:params:xml:ns:xmpp-sasl").serialize();
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/CompressFailureSerializer.h b/Swiften/Serializer/CompressFailureSerializer.h
new file mode 100644
index 0000000..c3e7953
--- /dev/null
+++ b/Swiften/Serializer/CompressFailureSerializer.h
@@ -0,0 +1,22 @@
+#ifndef SWIFTEN_CompressFailureSerializer_H
+#define SWIFTEN_CompressFailureSerializer_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/CompressFailure.h"
+#include "Swiften/Serializer/GenericElementSerializer.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+ class CompressFailureSerializer : public GenericElementSerializer<CompressFailure> {
+ public:
+ CompressFailureSerializer() : GenericElementSerializer<CompressFailure>() {
+ }
+
+ virtual String serialize(boost::shared_ptr<Element>) const {
+ return XMLElement("failure", "http://jabber.org/protocol/compress").serialize();
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/CompressRequestSerializer.cpp b/Swiften/Serializer/CompressRequestSerializer.cpp
new file mode 100644
index 0000000..4d3310b
--- /dev/null
+++ b/Swiften/Serializer/CompressRequestSerializer.cpp
@@ -0,0 +1,19 @@
+#include "Swiften/Serializer/CompressRequestSerializer.h"
+
+#include "Swiften/Elements/CompressRequest.h"
+
+namespace Swift {
+
+CompressRequestSerializer::CompressRequestSerializer() {
+}
+
+String CompressRequestSerializer::serialize(boost::shared_ptr<Element> element) const {
+ boost::shared_ptr<CompressRequest> compressRequest(boost::dynamic_pointer_cast<CompressRequest>(element));
+ return "<compress xmlns='http://jabber.org/protocol/compress'><method>" + compressRequest->getMethod() + "</method></compress>";
+}
+
+bool CompressRequestSerializer::canSerialize(boost::shared_ptr<Element> element) const {
+ return dynamic_cast<CompressRequest*>(element.get()) != 0;
+}
+
+}
diff --git a/Swiften/Serializer/CompressRequestSerializer.h b/Swiften/Serializer/CompressRequestSerializer.h
new file mode 100644
index 0000000..b6a493c
--- /dev/null
+++ b/Swiften/Serializer/CompressRequestSerializer.h
@@ -0,0 +1,18 @@
+#ifndef SWIFTEN_COMPRESSREQUESTSERIALIZER_H
+#define SWIFTEN_COMPRESSREQUESTSERIALIZER_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Serializer/ElementSerializer.h"
+
+namespace Swift {
+ class CompressRequestSerializer : public ElementSerializer {
+ public:
+ CompressRequestSerializer();
+
+ virtual String serialize(boost::shared_ptr<Element> element) const;
+ virtual bool canSerialize(boost::shared_ptr<Element> element) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/ElementSerializer.cpp b/Swiften/Serializer/ElementSerializer.cpp
new file mode 100644
index 0000000..22c64a6
--- /dev/null
+++ b/Swiften/Serializer/ElementSerializer.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/Serializer/ElementSerializer.h"
+
+namespace Swift {
+
+ElementSerializer::~ElementSerializer() {
+}
+
+}
diff --git a/Swiften/Serializer/ElementSerializer.h b/Swiften/Serializer/ElementSerializer.h
new file mode 100644
index 0000000..d2f5611
--- /dev/null
+++ b/Swiften/Serializer/ElementSerializer.h
@@ -0,0 +1,19 @@
+#ifndef SWIFTEN_ELEMENTSERIALIZER_H
+#define SWIFTEN_ELEMENTSERIALIZER_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Base/String.h"
+#include "Swiften/Elements/Element.h"
+
+namespace Swift {
+ class ElementSerializer {
+ public:
+ virtual ~ElementSerializer();
+
+ virtual String serialize(boost::shared_ptr<Element> element) const = 0;
+ virtual bool canSerialize(boost::shared_ptr<Element> element) const = 0;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/GenericElementSerializer.h b/Swiften/Serializer/GenericElementSerializer.h
new file mode 100644
index 0000000..7ccecb2
--- /dev/null
+++ b/Swiften/Serializer/GenericElementSerializer.h
@@ -0,0 +1,18 @@
+#ifndef SWIFTEN_GenericElementSerializer_H
+#define SWIFTEN_GenericElementSerializer_H
+
+#include "Swiften/Serializer/ElementSerializer.h"
+
+namespace Swift {
+ template<typename T>
+ class GenericElementSerializer : public ElementSerializer {
+ public:
+ virtual String serialize(boost::shared_ptr<Element> element) const = 0;
+
+ virtual bool canSerialize(boost::shared_ptr<Element> element) const {
+ return dynamic_cast<T*>(element.get()) != 0;
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/GenericPayloadSerializer.h b/Swiften/Serializer/GenericPayloadSerializer.h
new file mode 100644
index 0000000..c4a45c3
--- /dev/null
+++ b/Swiften/Serializer/GenericPayloadSerializer.h
@@ -0,0 +1,25 @@
+#ifndef SWIFTEN_GenericPayloadSerializer_H
+#define SWIFTEN_GenericPayloadSerializer_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Serializer/PayloadSerializer.h"
+#include "Swiften/Elements/Body.h"
+
+namespace Swift {
+ template<typename PAYLOAD_TYPE>
+ class GenericPayloadSerializer : public PayloadSerializer {
+ public:
+ virtual String serialize(boost::shared_ptr<Payload> element) const {
+ return serializePayload(boost::dynamic_pointer_cast<PAYLOAD_TYPE>(element));
+ }
+
+ virtual bool canSerialize(boost::shared_ptr<Payload> element) const {
+ return dynamic_cast<PAYLOAD_TYPE*>(element.get());
+ }
+
+ virtual String serializePayload(boost::shared_ptr<PAYLOAD_TYPE>) const = 0;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/GenericStanzaSerializer.h b/Swiften/Serializer/GenericStanzaSerializer.h
new file mode 100644
index 0000000..c59f735
--- /dev/null
+++ b/Swiften/Serializer/GenericStanzaSerializer.h
@@ -0,0 +1,29 @@
+#ifndef SWIFTEN_GENERICSTANZASERIALIZER_H
+#define SWIFTEN_GENERICSTANZASERIALIZER_H
+
+#include "Swiften/Serializer/StanzaSerializer.h"
+
+namespace Swift {
+ template<typename STANZA_TYPE>
+ class GenericStanzaSerializer : public StanzaSerializer {
+ public:
+ GenericStanzaSerializer(const String& tag, PayloadSerializerCollection* payloadSerializers) : StanzaSerializer(tag, payloadSerializers) {}
+
+ virtual bool canSerialize(boost::shared_ptr<Element> element) const {
+ return dynamic_cast<STANZA_TYPE*>(element.get()) != 0;
+ }
+
+ virtual void setStanzaSpecificAttributes(
+ boost::shared_ptr<Element> stanza,
+ XMLElement& element) const {
+ setStanzaSpecificAttributesGeneric(
+ boost::dynamic_pointer_cast<STANZA_TYPE>(stanza), element);
+ }
+
+ virtual void setStanzaSpecificAttributesGeneric(
+ boost::shared_ptr<STANZA_TYPE>,
+ XMLElement&) const = 0;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/IQSerializer.h b/Swiften/Serializer/IQSerializer.h
new file mode 100644
index 0000000..3623f24
--- /dev/null
+++ b/Swiften/Serializer/IQSerializer.h
@@ -0,0 +1,30 @@
+#ifndef SWIFTEN_IQSerializer_H
+#define SWIFTEN_IQSerializer_H
+
+#include <cassert>
+
+#include "Swiften/Serializer/GenericStanzaSerializer.h"
+#include "Swiften/Elements/IQ.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+ class IQSerializer : public GenericStanzaSerializer<IQ> {
+ public:
+ IQSerializer(PayloadSerializerCollection* payloadSerializers) :
+ GenericStanzaSerializer<IQ>("iq", payloadSerializers) {}
+
+ private:
+ virtual void setStanzaSpecificAttributesGeneric(
+ boost::shared_ptr<IQ> iq,
+ XMLElement& element) const {
+ switch (iq->getType()) {
+ case IQ::Get: element.setAttribute("type","get"); break;
+ case IQ::Set: element.setAttribute("type","set"); break;
+ case IQ::Result: element.setAttribute("type","result"); break;
+ case IQ::Error: element.setAttribute("type","error"); break;
+ }
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/Makefile.inc b/Swiften/Serializer/Makefile.inc
new file mode 100644
index 0000000..5fbe57a
--- /dev/null
+++ b/Swiften/Serializer/Makefile.inc
@@ -0,0 +1,15 @@
+SWIFTEN_SOURCES += \
+ Swiften/Serializer/ElementSerializer.cpp \
+ Swiften/Serializer/CompressRequestSerializer.cpp \
+ Swiften/Serializer/AuthRequestSerializer.cpp \
+ Swiften/Serializer/StreamFeaturesSerializer.cpp \
+ Swiften/Serializer/XMPPSerializer.cpp \
+ Swiften/Serializer/StanzaSerializer.cpp \
+ Swiften/Serializer/PresenceSerializer.cpp \
+ Swiften/Serializer/MessageSerializer.cpp \
+ Swiften/Serializer/PayloadSerializer.cpp \
+ Swiften/Serializer/PayloadSerializerCollection.cpp
+
+include Swiften/Serializer/UnitTest/Makefile.inc
+include Swiften/Serializer/XML/Makefile.inc
+include Swiften/Serializer/PayloadSerializers/Makefile.inc
diff --git a/Swiften/Serializer/MessageSerializer.cpp b/Swiften/Serializer/MessageSerializer.cpp
new file mode 100644
index 0000000..a3cf2ad
--- /dev/null
+++ b/Swiften/Serializer/MessageSerializer.cpp
@@ -0,0 +1,27 @@
+#include "Swiften/Serializer/MessageSerializer.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+
+MessageSerializer::MessageSerializer(PayloadSerializerCollection* payloadSerializers) :
+ GenericStanzaSerializer<Message>("message", payloadSerializers) {
+}
+
+void MessageSerializer::setStanzaSpecificAttributesGeneric(
+ boost::shared_ptr<Message> message,
+ XMLElement& element) const {
+ if (message->getType() == Message::Chat) {
+ element.setAttribute("type", "chat");
+ }
+ else if (message->getType() == Message::Groupchat) {
+ element.setAttribute("type", "groupchat");
+ }
+ else if (message->getType() == Message::Headline) {
+ element.setAttribute("type", "headline");
+ }
+ else if (message->getType() == Message::Error) {
+ element.setAttribute("type", "error");
+ }
+}
+
+}
diff --git a/Swiften/Serializer/MessageSerializer.h b/Swiften/Serializer/MessageSerializer.h
new file mode 100644
index 0000000..8cb32c7
--- /dev/null
+++ b/Swiften/Serializer/MessageSerializer.h
@@ -0,0 +1,21 @@
+#ifndef SWIFTEN_MessageSerializer_H
+#define SWIFTEN_MessageSerializer_H
+
+#include "Swiften/Serializer/GenericStanzaSerializer.h"
+#include "Swiften/Elements/Message.h"
+
+namespace Swift {
+ class XMLElement;
+
+ class MessageSerializer : public GenericStanzaSerializer<Message> {
+ public:
+ MessageSerializer(PayloadSerializerCollection* payloadSerializers);
+
+ private:
+ void setStanzaSpecificAttributesGeneric(
+ boost::shared_ptr<Message> message,
+ XMLElement& element) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializer.cpp
new file mode 100644
index 0000000..47295ac
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializer.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/Serializer/PayloadSerializer.h"
+
+namespace Swift {
+
+PayloadSerializer::~PayloadSerializer() {
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializer.h b/Swiften/Serializer/PayloadSerializer.h
new file mode 100644
index 0000000..935ff4b
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializer.h
@@ -0,0 +1,19 @@
+#ifndef SWIFTEN_PAYLOADSERIALIZER_H
+#define SWIFTEN_PAYLOADSERIALIZER_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Base/String.h"
+#include "Swiften/Elements/Payload.h"
+
+namespace Swift {
+ class PayloadSerializer {
+ public:
+ virtual ~PayloadSerializer();
+
+ virtual bool canSerialize(boost::shared_ptr<Payload>) const = 0;
+ virtual String serialize(boost::shared_ptr<Payload>) const = 0;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializerCollection.cpp
new file mode 100644
index 0000000..db86eea
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializerCollection.cpp
@@ -0,0 +1,27 @@
+#include <boost/bind.hpp>
+#include <algorithm>
+
+#include "Swiften/Serializer/PayloadSerializerCollection.h"
+#include "Swiften/Serializer/PayloadSerializer.h"
+
+namespace Swift {
+
+PayloadSerializerCollection::PayloadSerializerCollection() {
+}
+
+void PayloadSerializerCollection::addSerializer(PayloadSerializer* serializer) {
+ serializers_.push_back(serializer);
+}
+
+void PayloadSerializerCollection::removeSerializer(PayloadSerializer* serializer) {
+ serializers_.erase(remove(serializers_.begin(), serializers_.end(), serializer), serializers_.end());
+}
+
+PayloadSerializer* PayloadSerializerCollection::getPayloadSerializer(boost::shared_ptr<Payload> payload) const {
+ std::vector<PayloadSerializer*>::const_iterator i = std::find_if(
+ serializers_.begin(), serializers_.end(),
+ boost::bind(&PayloadSerializer::canSerialize, _1, payload));
+ return (i != serializers_.end() ? *i : NULL);
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializerCollection.h b/Swiften/Serializer/PayloadSerializerCollection.h
new file mode 100644
index 0000000..a126989
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializerCollection.h
@@ -0,0 +1,26 @@
+#ifndef SWIFTEN_PAYLOADSERIALIZERCOLLECTION_H
+#define SWIFTEN_PAYLOADSERIALIZERCOLLECTION_H
+
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/Payload.h"
+
+namespace Swift {
+ class PayloadSerializer;
+ class String;
+
+ class PayloadSerializerCollection {
+ public:
+ PayloadSerializerCollection();
+
+ void addSerializer(PayloadSerializer* factory);
+ void removeSerializer(PayloadSerializer* factory);
+ PayloadSerializer* getPayloadSerializer(boost::shared_ptr<Payload>) const;
+
+ private:
+ std::vector<PayloadSerializer*> serializers_;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/BodySerializer.h b/Swiften/Serializer/PayloadSerializers/BodySerializer.h
new file mode 100644
index 0000000..7fba561
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/BodySerializer.h
@@ -0,0 +1,20 @@
+#ifndef SWIFTEN_BodySerializer_H
+#define SWIFTEN_BodySerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+#include "Swiften/Elements/Body.h"
+
+namespace Swift {
+ class BodySerializer : public GenericPayloadSerializer<Body> {
+ public:
+ BodySerializer() : GenericPayloadSerializer<Body>() {}
+
+ virtual String serializePayload(boost::shared_ptr<Body> body) const {
+ XMLTextNode textNode(body->getText());
+ return "<body>" + textNode.serialize() + "</body>";
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.cpp b/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.cpp
new file mode 100644
index 0000000..fbb72af
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.cpp
@@ -0,0 +1,20 @@
+#include "Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+
+CapsInfoSerializer::CapsInfoSerializer() : GenericPayloadSerializer<CapsInfo>() {
+}
+
+String CapsInfoSerializer::serializePayload(boost::shared_ptr<CapsInfo> capsInfo) const {
+ XMLElement capsElement("c", "http://jabber.org/protocol/caps");
+ capsElement.setAttribute("node", capsInfo->getNode());
+ capsElement.setAttribute("hash", capsInfo->getHash());
+ capsElement.setAttribute("ver", capsInfo->getVersion());
+ return capsElement.serialize();
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h b/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h
new file mode 100644
index 0000000..cb4fa33
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h
@@ -0,0 +1,16 @@
+#ifndef SWIFTEN_CapsInfoSerializer_H
+#define SWIFTEN_CapsInfoSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/CapsInfo.h"
+
+namespace Swift {
+ class CapsInfoSerializer : public GenericPayloadSerializer<CapsInfo> {
+ public:
+ CapsInfoSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<CapsInfo>) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.cpp b/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.cpp
new file mode 100644
index 0000000..4c39574
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.cpp
@@ -0,0 +1,36 @@
+#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+
+DiscoInfoSerializer::DiscoInfoSerializer() : GenericPayloadSerializer<DiscoInfo>() {
+}
+
+String DiscoInfoSerializer::serializePayload(boost::shared_ptr<DiscoInfo> discoInfo) const {
+ XMLElement queryElement("query", "http://jabber.org/protocol/disco#info");
+ if (!discoInfo->getNode().isEmpty()) {
+ queryElement.setAttribute("node", discoInfo->getNode());
+ }
+ foreach(const DiscoInfo::Identity& identity, discoInfo->getIdentities()) {
+ boost::shared_ptr<XMLElement> identityElement(new XMLElement("identity"));
+ if (!identity.getLanguage().isEmpty()) {
+ identityElement->setAttribute("xml:lang", identity.getLanguage());
+ }
+ identityElement->setAttribute("category", identity.getCategory());
+ identityElement->setAttribute("name", identity.getName());
+ identityElement->setAttribute("type", identity.getType());
+ queryElement.addNode(identityElement);
+ }
+ foreach(const String& feature, discoInfo->getFeatures()) {
+ boost::shared_ptr<XMLElement> featureElement(new XMLElement("feature"));
+ featureElement->setAttribute("var", feature);
+ queryElement.addNode(featureElement);
+ }
+ return queryElement.serialize();
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h b/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h
new file mode 100644
index 0000000..929a455
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h
@@ -0,0 +1,16 @@
+#ifndef SWIFTEN_DiscoInfoSerializer_H
+#define SWIFTEN_DiscoInfoSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/DiscoInfo.h"
+
+namespace Swift {
+ class DiscoInfoSerializer : public GenericPayloadSerializer<DiscoInfo> {
+ public:
+ DiscoInfoSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<DiscoInfo>) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/ErrorSerializer.cpp b/Swiften/Serializer/PayloadSerializers/ErrorSerializer.cpp
new file mode 100644
index 0000000..347e1a5
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/ErrorSerializer.cpp
@@ -0,0 +1,56 @@
+#include "Swiften/Serializer/PayloadSerializers/ErrorSerializer.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+
+namespace Swift {
+
+ErrorSerializer::ErrorSerializer() : GenericPayloadSerializer<Error>() {
+}
+
+String ErrorSerializer::serializePayload(boost::shared_ptr<Error> error) const {
+ String result("<error type=\"");
+ switch (error->getType()) {
+ case Error::Continue: result += "continue"; break;
+ case Error::Modify: result += "modify"; break;
+ case Error::Auth: result += "auth"; break;
+ case Error::Wait: result += "wait"; break;
+ default: result += "cancel"; break;
+ }
+ result += "\">";
+
+ String conditionElement;
+ switch (error->getCondition()) {
+ case Error::BadRequest: conditionElement = "bad-request"; break;
+ case Error::Conflict: conditionElement = "conflict"; break;
+ case Error::FeatureNotImplemented: conditionElement = "feature-not-implemented"; break;
+ case Error::Forbidden: conditionElement = "forbidden"; break;
+ case Error::Gone: conditionElement = "gone"; break;
+ case Error::InternalServerError: conditionElement = "internal-server-error"; break;
+ case Error::ItemNotFound: conditionElement = "item-not-found"; break;
+ case Error::JIDMalformed: conditionElement = "jid-malformed"; break;
+ case Error::NotAcceptable: conditionElement = "not-acceptable"; break;
+ case Error::NotAllowed: conditionElement = "not-allowed"; break;
+ case Error::NotAuthorized: conditionElement = "not-authorized"; break;
+ case Error::PaymentRequired: conditionElement = "payment-required"; break;
+ case Error::RecipientUnavailable: conditionElement = "recipient-unavailable"; break;
+ case Error::Redirect: conditionElement = "redirect"; break;
+ case Error::RegistrationRequired: conditionElement = "registration-required"; break;
+ case Error::RemoteServerNotFound: conditionElement = "remote-server-not-found"; break;
+ case Error::RemoteServerTimeout: conditionElement = "remote-server-timeout"; break;
+ case Error::ResourceConstraint: conditionElement = "resource-constraint"; break;
+ case Error::ServiceUnavailable: conditionElement = "service-unavailable"; break;
+ case Error::SubscriptionRequired: conditionElement = "subscription-required"; break;
+ case Error::UnexpectedRequest: conditionElement = "unexpected-request"; break;
+ default: conditionElement = "undefined-condition"; break;
+ }
+ result += "<" + conditionElement + " xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>";
+
+ if (!error->getText().isEmpty()) {
+ XMLTextNode textNode(error->getText());
+ result += "<text xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">" + textNode.serialize() + "</text>";
+ }
+
+ result += "</error>";
+ return result;
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/ErrorSerializer.h b/Swiften/Serializer/PayloadSerializers/ErrorSerializer.h
new file mode 100644
index 0000000..ecf73dc
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/ErrorSerializer.h
@@ -0,0 +1,16 @@
+#ifndef SWIFTEN_ErrorSerializer_H
+#define SWIFTEN_ErrorSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/Error.h"
+
+namespace Swift {
+ class ErrorSerializer : public GenericPayloadSerializer<Error> {
+ public:
+ ErrorSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<Error> error) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
new file mode 100644
index 0000000..9799802
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
@@ -0,0 +1,49 @@
+#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Serializer/PayloadSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/BodySerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/PrioritySerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/ErrorSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/RosterSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/StatusSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h"
+#include "Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h"
+
+namespace Swift {
+
+FullPayloadSerializerCollection::FullPayloadSerializerCollection() {
+ serializers_.push_back(new BodySerializer());
+ serializers_.push_back(new PrioritySerializer());
+ serializers_.push_back(new ErrorSerializer());
+ serializers_.push_back(new RosterSerializer());
+ serializers_.push_back(new MUCPayloadSerializer());
+ serializers_.push_back(new SoftwareVersionSerializer());
+ serializers_.push_back(new StatusSerializer());
+ serializers_.push_back(new StatusShowSerializer());
+ serializers_.push_back(new DiscoInfoSerializer());
+ serializers_.push_back(new CapsInfoSerializer());
+ serializers_.push_back(new ResourceBindSerializer());
+ serializers_.push_back(new StartSessionSerializer());
+ serializers_.push_back(new SecurityLabelSerializer());
+ serializers_.push_back(new SecurityLabelsCatalogSerializer());
+ foreach(PayloadSerializer* serializer, serializers_) {
+ addSerializer(serializer);
+ }
+}
+
+FullPayloadSerializerCollection::~FullPayloadSerializerCollection() {
+ foreach(PayloadSerializer* serializer, serializers_) {
+ removeSerializer(serializer);
+ delete serializer;
+ }
+ serializers_.clear();
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h
new file mode 100644
index 0000000..e1655b5
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h
@@ -0,0 +1,19 @@
+#ifndef SWIFTEN_FULLPAYLOADSERIALIZERCOLLECTION_H
+#define SWIFTEN_FULLPAYLOADSERIALIZERCOLLECTION_H
+
+#include <vector>
+
+#include "Swiften/Serializer/PayloadSerializerCollection.h"
+
+namespace Swift {
+ class FullPayloadSerializerCollection : public PayloadSerializerCollection {
+ public:
+ FullPayloadSerializerCollection();
+ ~FullPayloadSerializerCollection();
+
+ private:
+ std::vector<PayloadSerializer*> serializers_;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.cpp
new file mode 100644
index 0000000..9c701cc
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.cpp
@@ -0,0 +1,13 @@
+#include "Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h"
+
+namespace Swift {
+
+MUCPayloadSerializer::MUCPayloadSerializer() : GenericPayloadSerializer<MUCPayload>() {
+}
+
+String MUCPayloadSerializer::serializePayload(boost::shared_ptr<MUCPayload>) const {
+ String result("<x xmlns='http://jabber.org/protocol/muc'/>");
+ return result;
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h
new file mode 100644
index 0000000..504c969
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h
@@ -0,0 +1,16 @@
+#ifndef SWIFTEN_MUCPayloadSerializer_H
+#define SWIFTEN_MUCPayloadSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/MUCPayload.h"
+
+namespace Swift {
+ class MUCPayloadSerializer : public GenericPayloadSerializer<MUCPayload> {
+ public:
+ MUCPayloadSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<MUCPayload> version) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/Makefile.inc b/Swiften/Serializer/PayloadSerializers/Makefile.inc
new file mode 100644
index 0000000..61f603a
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/Makefile.inc
@@ -0,0 +1,13 @@
+SWIFTEN_SOURCES += \
+ Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp \
+ Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp \
+ Swiften/Serializer/PayloadSerializers/ErrorSerializer.cpp \
+ Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.cpp \
+ Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp \
+ Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.cpp \
+ Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.cpp \
+ Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.cpp \
+ Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.cpp \
+ Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp
+
+include Swiften/Serializer/PayloadSerializers/UnitTest/Makefile.inc
diff --git a/Swiften/Serializer/PayloadSerializers/PrioritySerializer.h b/Swiften/Serializer/PayloadSerializers/PrioritySerializer.h
new file mode 100644
index 0000000..f132b6e
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/PrioritySerializer.h
@@ -0,0 +1,20 @@
+#ifndef SWIFTEN_PrioritySerializer_H
+#define SWIFTEN_PrioritySerializer_H
+
+#include <boost/lexical_cast.hpp>
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/Priority.h"
+
+namespace Swift {
+ class PrioritySerializer : public GenericPayloadSerializer<Priority> {
+ public:
+ PrioritySerializer() : GenericPayloadSerializer<Priority>() {}
+
+ virtual String serializePayload(boost::shared_ptr<Priority> priority) const {
+ return "<priority>" + boost::lexical_cast<std::string>(priority->getPriority()) + "</priority>";
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.cpp b/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.cpp
new file mode 100644
index 0000000..93ab136
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.cpp
@@ -0,0 +1,28 @@
+#include "Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Serializer/XML/XMLElement.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+
+namespace Swift {
+
+ResourceBindSerializer::ResourceBindSerializer() : GenericPayloadSerializer<ResourceBind>() {
+}
+
+String ResourceBindSerializer::serializePayload(boost::shared_ptr<ResourceBind> resourceBind) const {
+ XMLElement bindElement("bind", "urn:ietf:params:xml:ns:xmpp-bind");
+ if (resourceBind->getJID().isValid()) {
+ boost::shared_ptr<XMLElement> jidNode(new XMLElement("jid"));
+ jidNode->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(resourceBind->getJID().toString())));
+ bindElement.addNode(jidNode);
+ }
+ else if (!resourceBind->getResource().isEmpty()) {
+ boost::shared_ptr<XMLElement> resourceNode(new XMLElement("resource"));
+ resourceNode->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(resourceBind->getResource())));
+ bindElement.addNode(resourceNode);
+ }
+ return bindElement.serialize();
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h b/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h
new file mode 100644
index 0000000..61cf539
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h
@@ -0,0 +1,16 @@
+#ifndef SWIFTEN_ResourceBindSerializer_H
+#define SWIFTEN_ResourceBindSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/ResourceBind.h"
+
+namespace Swift {
+ class ResourceBindSerializer : public GenericPayloadSerializer<ResourceBind> {
+ public:
+ ResourceBindSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<ResourceBind>) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp b/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp
new file mode 100644
index 0000000..6329f86
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp
@@ -0,0 +1,45 @@
+#include "Swiften/Serializer/PayloadSerializers/RosterSerializer.h"
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+
+RosterSerializer::RosterSerializer() : GenericPayloadSerializer<RosterPayload>() {
+}
+
+String RosterSerializer::serializePayload(boost::shared_ptr<RosterPayload> roster) const {
+ XMLElement queryElement("query", "jabber:iq:roster");
+ foreach(const RosterItemPayload& item, roster->getItems()) {
+ boost::shared_ptr<XMLElement> itemElement(new XMLElement("item"));
+ itemElement->setAttribute("jid", item.getJID());
+ itemElement->setAttribute("name", item.getName());
+
+ switch (item.getSubscription()) {
+ case RosterItemPayload::To: itemElement->setAttribute("subscription", "to"); break;
+ case RosterItemPayload::From: itemElement->setAttribute("subscription", "from"); break;
+ case RosterItemPayload::Both: itemElement->setAttribute("subscription", "both"); break;
+ case RosterItemPayload::Remove: itemElement->setAttribute("subscription", "remove"); break;
+ case RosterItemPayload::None: itemElement->setAttribute("subscription", "none"); break;
+ }
+
+ if (item.getSubscriptionRequested()) {
+ itemElement->setAttribute("ask", "subscribe");
+ }
+
+ foreach(const String& group, item.getGroups()) {
+ boost::shared_ptr<XMLElement> groupElement(new XMLElement("group"));
+ groupElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(group)));
+ itemElement->addNode(groupElement);
+ }
+
+ queryElement.addNode(itemElement);
+ }
+
+ return queryElement.serialize();
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/RosterSerializer.h b/Swiften/Serializer/PayloadSerializers/RosterSerializer.h
new file mode 100644
index 0000000..fb6a713
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/RosterSerializer.h
@@ -0,0 +1,16 @@
+#ifndef SWIFTEN_RosterSerializer_H
+#define SWIFTEN_RosterSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/RosterPayload.h"
+
+namespace Swift {
+ class RosterSerializer : public GenericPayloadSerializer<RosterPayload> {
+ public:
+ RosterSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<RosterPayload>) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.cpp b/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.cpp
new file mode 100644
index 0000000..e53c6b7
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.cpp
@@ -0,0 +1,38 @@
+#include "Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h"
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Serializer/XML/XMLRawTextNode.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+
+SecurityLabelSerializer::SecurityLabelSerializer() : GenericPayloadSerializer<SecurityLabel>() {
+}
+
+String SecurityLabelSerializer::serializePayload(boost::shared_ptr<SecurityLabel> label) const {
+ XMLElement element("securitylabel", "urn:xmpp:sec-label:0");
+ if (!label->getDisplayMarking().isEmpty()) {
+ boost::shared_ptr<XMLElement> displayMarking(new XMLElement("displaymarking"));
+ if (!label->getForegroundColor().isEmpty()) {
+ displayMarking->setAttribute("fgcolor", label->getForegroundColor());
+ }
+ if (!label->getBackgroundColor().isEmpty()) {
+ displayMarking->setAttribute("bgcolor", label->getBackgroundColor());
+ }
+ displayMarking->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(label->getDisplayMarking())));
+ element.addNode(displayMarking);
+ }
+ if (!label->getLabel().isEmpty()) {
+ boost::shared_ptr<XMLElement> labelElement(new XMLElement("label"));
+ labelElement->addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(label->getLabel())));
+ element.addNode(labelElement);
+ }
+ foreach(const String& equivalentLabel, label->getEquivalentLabels()) {
+ boost::shared_ptr<XMLElement> equivalentLabelElement(new XMLElement("equivalentlabel"));
+ equivalentLabelElement->addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(equivalentLabel)));
+ element.addNode(equivalentLabelElement);
+ }
+ return element.serialize();
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h b/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h
new file mode 100644
index 0000000..b0b0804
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h
@@ -0,0 +1,16 @@
+#ifndef SWIFTEN_SecurityLabelSerializer_H
+#define SWIFTEN_SecurityLabelSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/SecurityLabel.h"
+
+namespace Swift {
+ class SecurityLabelSerializer : public GenericPayloadSerializer<SecurityLabel> {
+ public:
+ SecurityLabelSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<SecurityLabel> version) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp b/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp
new file mode 100644
index 0000000..bc6a41f
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp
@@ -0,0 +1,30 @@
+#include "Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h"
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+#include "Swiften/Serializer/XML/XMLRawTextNode.h"
+#include "Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h"
+
+namespace Swift {
+
+SecurityLabelsCatalogSerializer::SecurityLabelsCatalogSerializer() : GenericPayloadSerializer<SecurityLabelsCatalog>() {
+}
+
+String SecurityLabelsCatalogSerializer::serializePayload(boost::shared_ptr<SecurityLabelsCatalog> catalog) const {
+ XMLElement element("catalog", "urn:xmpp:sec-label:catalog:0");
+ if (!catalog->getName().isEmpty()) {
+ element.setAttribute("name", catalog->getName());
+ }
+ if (catalog->getTo().isValid()) {
+ element.setAttribute("to", catalog->getTo());
+ }
+ if (!catalog->getDescription().isEmpty()) {
+ element.setAttribute("desc", catalog->getDescription());
+ }
+ foreach (const SecurityLabel& label, catalog->getLabels()) {
+ String serializedLabel = SecurityLabelSerializer().serialize(boost::shared_ptr<SecurityLabel>(new SecurityLabel(label)));
+ element.addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(serializedLabel)));
+ }
+ return element.serialize();
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h b/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h
new file mode 100644
index 0000000..d086c79
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h
@@ -0,0 +1,16 @@
+#ifndef SWIFTEN_SecurityLabelsCatalogSerializer_H
+#define SWIFTEN_SecurityLabelsCatalogSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/SecurityLabelsCatalog.h"
+
+namespace Swift {
+ class SecurityLabelsCatalogSerializer : public GenericPayloadSerializer<SecurityLabelsCatalog> {
+ public:
+ SecurityLabelsCatalogSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<SecurityLabelsCatalog> version) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp b/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp
new file mode 100644
index 0000000..71ad9a2
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp
@@ -0,0 +1,23 @@
+#include "Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h"
+
+namespace Swift {
+
+SoftwareVersionSerializer::SoftwareVersionSerializer() : GenericPayloadSerializer<SoftwareVersion>() {
+}
+
+String SoftwareVersionSerializer::serializePayload(boost::shared_ptr<SoftwareVersion> version) const {
+ String result("<query xmlns=\"jabber:iq:version\">");
+ if (!version->getName().isEmpty()) {
+ result += "<name>" + version->getName() + "</name>";
+ }
+ if (!version->getVersion().isEmpty()) {
+ result += "<version>" + version->getVersion() + "</version>";
+ }
+ if (!version->getOS().isEmpty()) {
+ result += "<os>" + version->getOS() + "</os>";
+ }
+ result += "</query>";
+ return result;
+}
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h b/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h
new file mode 100644
index 0000000..50242f2
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h
@@ -0,0 +1,16 @@
+#ifndef SWIFTEN_SoftwareVersionSerializer_H
+#define SWIFTEN_SoftwareVersionSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/SoftwareVersion.h"
+
+namespace Swift {
+ class SoftwareVersionSerializer : public GenericPayloadSerializer<SoftwareVersion> {
+ public:
+ SoftwareVersionSerializer();
+
+ virtual String serializePayload(boost::shared_ptr<SoftwareVersion> version) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h b/Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h
new file mode 100644
index 0000000..df35054
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h
@@ -0,0 +1,20 @@
+#ifndef SWIFTEN_StartSessionSerializer_H
+#define SWIFTEN_StartSessionSerializer_H
+
+#include <boost/lexical_cast.hpp>
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/StartSession.h"
+
+namespace Swift {
+ class StartSessionSerializer : public GenericPayloadSerializer<StartSession> {
+ public:
+ StartSessionSerializer() : GenericPayloadSerializer<StartSession>() {}
+
+ virtual String serializePayload(boost::shared_ptr<StartSession>) const {
+ return XMLElement("session", "urn:ietf:params:xml:ns:xmpp-session").serialize();
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/StatusSerializer.h b/Swiften/Serializer/PayloadSerializers/StatusSerializer.h
new file mode 100644
index 0000000..dc5f6d1
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/StatusSerializer.h
@@ -0,0 +1,22 @@
+#ifndef SWIFTEN_StatusSerializer_H
+#define SWIFTEN_StatusSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+#include "Swiften/Elements/Status.h"
+
+namespace Swift {
+ class StatusSerializer : public GenericPayloadSerializer<Status> {
+ public:
+ StatusSerializer() : GenericPayloadSerializer<Status>() {}
+
+ virtual String serializePayload(boost::shared_ptr<Status> status) const {
+ XMLElement element("status");
+ element.addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(status->getText())));
+ return element.serialize();
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h b/Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h
new file mode 100644
index 0000000..f66c09c
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h
@@ -0,0 +1,33 @@
+#ifndef SWIFTEN_StatusShowSerializer_H
+#define SWIFTEN_StatusShowSerializer_H
+
+#include "Swiften/Serializer/GenericPayloadSerializer.h"
+#include "Swiften/Elements/StatusShow.h"
+
+namespace Swift {
+ class StatusShowSerializer : public GenericPayloadSerializer<StatusShow> {
+ public:
+ StatusShowSerializer() : GenericPayloadSerializer<StatusShow>() {}
+
+ virtual String serializePayload(boost::shared_ptr<StatusShow> statusShow) const {
+ if (statusShow->getType () == StatusShow::Online || statusShow->getType() == StatusShow::None) {
+ return "";
+ }
+ else {
+ String result("<show>");
+ switch (statusShow->getType()) {
+ case StatusShow::Away: result += "away"; break;
+ case StatusShow::XA: result += "xa"; break;
+ case StatusShow::FFC: result += "chat"; break;
+ case StatusShow::DND: result += "dnd"; break;
+ case StatusShow::Online: assert(false); break;
+ case StatusShow::None: assert(false); break;
+ }
+ result += "</show>";
+ return result;
+ }
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp
new file mode 100644
index 0000000..650a7ee
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp
@@ -0,0 +1,25 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h"
+
+using namespace Swift;
+
+class CapsInfoSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(CapsInfoSerializerTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ CapsInfoSerializerTest() {}
+
+ void testSerialize() {
+ CapsInfoSerializer testling;
+ boost::shared_ptr<CapsInfo> priority(new CapsInfo("http://swift.im", "myversion", "sha-1"));
+
+ CPPUNIT_ASSERT_EQUAL(String("<c hash=\"sha-1\" node=\"http://swift.im\" ver=\"myversion\" xmlns=\"http://jabber.org/protocol/caps\"/>"), testling.serialize(priority));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(CapsInfoSerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/DiscoInfoSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/DiscoInfoSerializerTest.cpp
new file mode 100644
index 0000000..d3e247f
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/DiscoInfoSerializerTest.cpp
@@ -0,0 +1,38 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h"
+
+using namespace Swift;
+
+class DiscoInfoSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(DiscoInfoSerializerTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ DiscoInfoSerializerTest() {}
+
+ void testSerialize() {
+ DiscoInfoSerializer testling;
+ boost::shared_ptr<DiscoInfo> discoInfo(new DiscoInfo());
+ discoInfo->addIdentity(DiscoInfo::Identity("Swift", "client", "pc"));
+ discoInfo->addIdentity(DiscoInfo::Identity("Vlug", "client", "pc", "nl"));
+ discoInfo->addFeature("http://jabber.org/protocol/caps");
+ discoInfo->addFeature("http://jabber.org/protocol/disco#info");
+ discoInfo->setNode("http://swift.im#bla");
+
+ String expectedResult =
+ "<query node=\"http://swift.im#bla\" xmlns=\"http://jabber.org/protocol/disco#info\">"
+ "<identity category=\"client\" name=\"Swift\" type=\"pc\"/>"
+ "<identity category=\"client\" name=\"Vlug\" type=\"pc\" xml:lang=\"nl\"/>"
+ "<feature var=\"http://jabber.org/protocol/caps\"/>"
+ "<feature var=\"http://jabber.org/protocol/disco#info\"/>"
+ "</query>";
+
+ CPPUNIT_ASSERT_EQUAL(expectedResult, testling.serialize(discoInfo));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DiscoInfoSerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/ErrorSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/ErrorSerializerTest.cpp
new file mode 100644
index 0000000..2d68a3d
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/ErrorSerializerTest.cpp
@@ -0,0 +1,25 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/ErrorSerializer.h"
+
+using namespace Swift;
+
+class ErrorSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(ErrorSerializerTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ ErrorSerializerTest() {}
+
+ void testSerialize() {
+ ErrorSerializer testling;
+ boost::shared_ptr<Error> error(new Error(Error::BadRequest, Error::Cancel, "My Error"));
+
+ CPPUNIT_ASSERT_EQUAL(String("<error type=\"cancel\"><bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/><text xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">My Error</text></error>"), testling.serialize(error));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ErrorSerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/Makefile.inc b/Swiften/Serializer/PayloadSerializers/UnitTest/Makefile.inc
new file mode 100644
index 0000000..fce7ab9
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/Makefile.inc
@@ -0,0 +1,12 @@
+UNITTEST_SOURCES += \
+ Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp \
+ Swiften/Serializer/PayloadSerializers/UnitTest/ErrorSerializerTest.cpp \
+ Swiften/Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp \
+ Swiften/Serializer/PayloadSerializers/UnitTest/ResourceBindSerializerTest.cpp \
+ Swiften/Serializer/PayloadSerializers/UnitTest/PrioritySerializerTest.cpp \
+ Swiften/Serializer/PayloadSerializers/UnitTest/DiscoInfoSerializerTest.cpp \
+ Swiften/Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp \
+ Swiften/Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp \
+ Swiften/Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp \
+ Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelSerializerTest.cpp \
+ Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/PrioritySerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/PrioritySerializerTest.cpp
new file mode 100644
index 0000000..5f6432b
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/PrioritySerializerTest.cpp
@@ -0,0 +1,25 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/PrioritySerializer.h"
+
+using namespace Swift;
+
+class PrioritySerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(PrioritySerializerTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ PrioritySerializerTest() {}
+
+ void testSerialize() {
+ PrioritySerializer testling;
+ boost::shared_ptr<Priority> priority(new Priority(-113));
+
+ CPPUNIT_ASSERT_EQUAL(String("<priority>-113</priority>"), testling.serialize(priority));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(PrioritySerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/ResourceBindSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/ResourceBindSerializerTest.cpp
new file mode 100644
index 0000000..ff09966
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/ResourceBindSerializerTest.cpp
@@ -0,0 +1,49 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h"
+
+using namespace Swift;
+
+class ResourceBindSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(ResourceBindSerializerTest);
+ CPPUNIT_TEST(testSerialize_JID);
+ CPPUNIT_TEST(testSerialize_Resource);
+ CPPUNIT_TEST(testSerialize_Empty);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ ResourceBindSerializerTest() {}
+
+ void testSerialize_JID() {
+ ResourceBindSerializer testling;
+ boost::shared_ptr<ResourceBind> resourceBind(new ResourceBind());
+ resourceBind->setJID(JID("somenode@example.com/someresource"));
+
+ CPPUNIT_ASSERT_EQUAL(String(
+ "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\">"
+ "<jid>somenode@example.com/someresource</jid>"
+ "</bind>"), testling.serialize(resourceBind));
+ }
+
+ void testSerialize_Resource() {
+ ResourceBindSerializer testling;
+ boost::shared_ptr<ResourceBind> resourceBind(new ResourceBind());
+ resourceBind->setResource("someresource");
+
+ CPPUNIT_ASSERT_EQUAL(String(
+ "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\">"
+ "<resource>someresource</resource>"
+ "</bind>"), testling.serialize(resourceBind));
+ }
+
+ void testSerialize_Empty() {
+ ResourceBindSerializer testling;
+ boost::shared_ptr<ResourceBind> resourceBind(new ResourceBind());
+
+ CPPUNIT_ASSERT_EQUAL(String("<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/>"), testling.serialize(resourceBind));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ResourceBindSerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp
new file mode 100644
index 0000000..81fdc09
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/RosterSerializerTest.cpp
@@ -0,0 +1,48 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/RosterSerializer.h"
+
+using namespace Swift;
+
+class RosterSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(RosterSerializerTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ RosterSerializerTest() {}
+
+ void testSerialize() {
+ RosterSerializer testling;
+ boost::shared_ptr<RosterPayload> roster(new RosterPayload());
+
+ RosterItemPayload item1;
+ item1.setJID(JID("foo@bar.com"));
+ item1.setName("Foo @ Bar");
+ item1.setSubscription(RosterItemPayload::From);
+ item1.addGroup("Group 1");
+ item1.addGroup("Group 2");
+ item1.setSubscriptionRequested();
+ roster->addItem(item1);
+
+ RosterItemPayload item2;
+ item2.setJID(JID("baz@blo.com"));
+ item2.setName("Baz");
+ roster->addItem(item2);
+
+ String expectedResult =
+ "<query xmlns=\"jabber:iq:roster\">"
+ "<item ask=\"subscribe\" jid=\"foo@bar.com\" name=\"Foo @ Bar\" subscription=\"from\">"
+ "<group>Group 1</group>"
+ "<group>Group 2</group>"
+ "</item>"
+ "<item jid=\"baz@blo.com\" name=\"Baz\" subscription=\"none\"/>"
+ "</query>";
+
+ CPPUNIT_ASSERT_EQUAL(expectedResult, testling.serialize(roster));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(RosterSerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelSerializerTest.cpp
new file mode 100644
index 0000000..e8b89ad
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelSerializerTest.cpp
@@ -0,0 +1,43 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h"
+
+using namespace Swift;
+
+class SecurityLabelSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(SecurityLabelSerializerTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ SecurityLabelSerializerTest() {}
+
+ void testSerialize() {
+ SecurityLabelSerializer testling;
+ boost::shared_ptr<SecurityLabel> securityLabel(new SecurityLabel());
+ securityLabel->setDisplayMarking("SECRET");
+ securityLabel->setForegroundColor("black");
+ securityLabel->setBackgroundColor("red");
+ securityLabel->setLabel("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQYCAQQGASk=</esssecuritylabel>");
+ securityLabel->addEquivalentLabel("<icismlabel xmlns=\"http://example.gov/IC-ISM/0\" classification=\"S\" ownerProducer=\"USA\" disseminationControls=\"FOUO\"/>");
+ securityLabel->addEquivalentLabel("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MRUCAgD9DA9BcXVhIChvYnNvbGV0ZSk=</esssecuritylabel>");
+
+ CPPUNIT_ASSERT_EQUAL(String(
+ "<securitylabel xmlns=\"urn:xmpp:sec-label:0\">"
+ "<displaymarking bgcolor=\"red\" fgcolor=\"black\">SECRET</displaymarking>"
+ "<label>"
+ "<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQYCAQQGASk=</esssecuritylabel>"
+ "</label>"
+ "<equivalentlabel>"
+ "<icismlabel xmlns=\"http://example.gov/IC-ISM/0\" classification=\"S\" ownerProducer=\"USA\" disseminationControls=\"FOUO\"/>"
+ "</equivalentlabel>"
+ "<equivalentlabel>"
+ "<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MRUCAgD9DA9BcXVhIChvYnNvbGV0ZSk=</esssecuritylabel>"
+ "</equivalentlabel>"
+ "</securitylabel>"), testling.serialize(securityLabel));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SecurityLabelSerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp
new file mode 100644
index 0000000..acea1e4
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp
@@ -0,0 +1,52 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.h"
+
+using namespace Swift;
+
+class SecurityLabelsCatalogSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(SecurityLabelsCatalogSerializerTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ SecurityLabelsCatalogSerializerTest() {}
+
+ void testSerialize() {
+ SecurityLabelsCatalogSerializer testling;
+ boost::shared_ptr<SecurityLabelsCatalog> catalog(new SecurityLabelsCatalog());
+ catalog->setTo(JID("example.com"));
+ catalog->setName("Default");
+ catalog->setDescription("an example set of labels");
+
+ SecurityLabel securityLabel1;
+ securityLabel1.setDisplayMarking("SECRET");
+ securityLabel1.setForegroundColor("black");
+ securityLabel1.setBackgroundColor("red");
+ securityLabel1.setLabel("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQYCAQQGASk=</esssecuritylabel>");
+ catalog->addLabel(securityLabel1);
+
+ SecurityLabel securityLabel2;
+ securityLabel2.setDisplayMarking("CONFIDENTIAL");
+ securityLabel2.setForegroundColor("black");
+ securityLabel2.setBackgroundColor("navy");
+ securityLabel2.setLabel("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQMGASk=</esssecuritylabel>");
+ catalog->addLabel(securityLabel2);
+
+ CPPUNIT_ASSERT_EQUAL(String(
+ "<catalog desc=\"an example set of labels\" name=\"Default\" to=\"example.com\" xmlns=\"urn:xmpp:sec-label:catalog:0\">"
+ "<securitylabel xmlns=\"urn:xmpp:sec-label:0\">"
+ "<displaymarking bgcolor=\"red\" fgcolor=\"black\">SECRET</displaymarking>"
+ "<label><esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQYCAQQGASk=</esssecuritylabel></label>"
+ "</securitylabel>"
+ "<securitylabel xmlns=\"urn:xmpp:sec-label:0\">"
+ "<displaymarking bgcolor=\"navy\" fgcolor=\"black\">CONFIDENTIAL</displaymarking>"
+ "<label><esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQMGASk=</esssecuritylabel></label>"
+ "</securitylabel>"
+ "</catalog>"), testling.serialize(catalog));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SecurityLabelsCatalogSerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp
new file mode 100644
index 0000000..fd5dba5
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp
@@ -0,0 +1,25 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h"
+
+using namespace Swift;
+
+class SoftwareVersionSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(SoftwareVersionSerializerTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ SoftwareVersionSerializerTest() {}
+
+ void testSerialize() {
+ SoftwareVersionSerializer testling;
+ boost::shared_ptr<SoftwareVersion> softwareVersion(new SoftwareVersion("Swift", "0.1", "Mac OS X"));
+
+ CPPUNIT_ASSERT_EQUAL(String("<query xmlns=\"jabber:iq:version\"><name>Swift</name><version>0.1</version><os>Mac OS X</os></query>"), testling.serialize(softwareVersion));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SoftwareVersionSerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp
new file mode 100644
index 0000000..6dedacd
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp
@@ -0,0 +1,25 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/StatusSerializer.h"
+
+using namespace Swift;
+
+class StatusSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(StatusSerializerTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ StatusSerializerTest() {}
+
+ void testSerialize() {
+ StatusSerializer testling;
+ boost::shared_ptr<Status> status(new Status("I am away"));
+
+ CPPUNIT_ASSERT_EQUAL(String("<status>I am away</status>"), testling.serialize(status));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(StatusSerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp
new file mode 100644
index 0000000..42e1c7c
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp
@@ -0,0 +1,58 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h"
+
+using namespace Swift;
+
+class StatusShowSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(StatusShowSerializerTest);
+ CPPUNIT_TEST(testSerialize_Online);
+ CPPUNIT_TEST(testSerialize_Away);
+ CPPUNIT_TEST(testSerialize_FFC);
+ CPPUNIT_TEST(testSerialize_XA);
+ CPPUNIT_TEST(testSerialize_DND);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ StatusShowSerializerTest() {}
+
+ void testSerialize_Online() {
+ StatusShowSerializer testling;
+ boost::shared_ptr<StatusShow> statusShow(new StatusShow(StatusShow::Online));
+ CPPUNIT_ASSERT_EQUAL(String(""), testling.serialize(statusShow));
+ }
+
+ void testSerialize_Away() {
+ StatusShowSerializer testling;
+ boost::shared_ptr<StatusShow> statusShow(new StatusShow(StatusShow::Away));
+ CPPUNIT_ASSERT_EQUAL(String("<show>away</show>"), testling.serialize(statusShow));
+ }
+
+ void testSerialize_FFC() {
+ StatusShowSerializer testling;
+ boost::shared_ptr<StatusShow> statusShow(new StatusShow(StatusShow::FFC));
+ CPPUNIT_ASSERT_EQUAL(String("<show>chat</show>"), testling.serialize(statusShow));
+ }
+
+ void testSerialize_XA() {
+ StatusShowSerializer testling;
+ boost::shared_ptr<StatusShow> statusShow(new StatusShow(StatusShow::XA));
+ CPPUNIT_ASSERT_EQUAL(String("<show>xa</show>"), testling.serialize(statusShow));
+ }
+
+ void testSerialize_DND() {
+ StatusShowSerializer testling;
+ boost::shared_ptr<StatusShow> statusShow(new StatusShow(StatusShow::DND));
+ CPPUNIT_ASSERT_EQUAL(String("<show>dnd</show>"), testling.serialize(statusShow));
+ }
+
+ void testSerialize_None() {
+ StatusShowSerializer testling;
+ boost::shared_ptr<StatusShow> statusShow(new StatusShow(StatusShow::None));
+ CPPUNIT_ASSERT_EQUAL(String(""), testling.serialize(statusShow));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(StatusShowSerializerTest);
diff --git a/Swiften/Serializer/PresenceSerializer.cpp b/Swiften/Serializer/PresenceSerializer.cpp
new file mode 100644
index 0000000..f7585d5
--- /dev/null
+++ b/Swiften/Serializer/PresenceSerializer.cpp
@@ -0,0 +1,27 @@
+#include "Swiften/Serializer/PresenceSerializer.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+#include "boost/shared_ptr.hpp"
+
+namespace Swift {
+
+PresenceSerializer::PresenceSerializer(PayloadSerializerCollection* payloadSerializers) :
+ GenericStanzaSerializer<Presence>("presence", payloadSerializers) {
+}
+
+void PresenceSerializer::setStanzaSpecificAttributesGeneric(
+ boost::shared_ptr<Presence> presence,
+ XMLElement& element) const {
+ switch (presence->getType()) {
+ case Presence::Unavailable: element.setAttribute("type","unavailable"); break;
+ case Presence::Probe: element.setAttribute("type","probe"); break;
+ case Presence::Subscribe: element.setAttribute("type","subscribe"); break;
+ case Presence::Subscribed: element.setAttribute("type","subscribed"); break;
+ case Presence::Unsubscribe: element.setAttribute("type","unsubscribe"); break;
+ case Presence::Unsubscribed: element.setAttribute("type","unsubscribed"); break;
+ case Presence::Error: element.setAttribute("type","error"); break;
+ case Presence::Available: break;
+ }
+}
+
+}
diff --git a/Swiften/Serializer/PresenceSerializer.h b/Swiften/Serializer/PresenceSerializer.h
new file mode 100644
index 0000000..158d4f2
--- /dev/null
+++ b/Swiften/Serializer/PresenceSerializer.h
@@ -0,0 +1,21 @@
+#ifndef SWIFTEN_PresenceSerializer_H
+#define SWIFTEN_PresenceSerializer_H
+
+#include <cassert>
+
+#include "Swiften/Serializer/GenericStanzaSerializer.h"
+#include "Swiften/Elements/Presence.h"
+
+namespace Swift {
+ class PresenceSerializer : public GenericStanzaSerializer<Presence> {
+ public:
+ PresenceSerializer(PayloadSerializerCollection* payloadSerializers);
+
+ private:
+ virtual void setStanzaSpecificAttributesGeneric(
+ boost::shared_ptr<Presence> presence,
+ XMLElement& element) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/StanzaSerializer.cpp b/Swiften/Serializer/StanzaSerializer.cpp
new file mode 100644
index 0000000..d940634
--- /dev/null
+++ b/Swiften/Serializer/StanzaSerializer.cpp
@@ -0,0 +1,50 @@
+#include "Swiften/Serializer/StanzaSerializer.h"
+
+#include <sstream>
+#include <typeinfo>
+#include <iostream>
+
+#include "Swiften/Serializer/XML/XMLElement.h"
+#include "Swiften/Serializer/XML/XMLRawTextNode.h"
+#include "Swiften/Serializer/PayloadSerializer.h"
+#include "Swiften/Serializer/PayloadSerializerCollection.h"
+#include "Swiften/Elements/Stanza.h"
+
+namespace Swift {
+
+StanzaSerializer::StanzaSerializer(const String& tag, PayloadSerializerCollection* payloadSerializers) : tag_(tag), payloadSerializers_(payloadSerializers) {
+}
+
+String StanzaSerializer::serialize(boost::shared_ptr<Element> element) const {
+ boost::shared_ptr<Stanza> stanza(boost::dynamic_pointer_cast<Stanza>(element));
+
+ XMLElement stanzaElement(tag_);
+ if (stanza->getFrom().isValid()) {
+ stanzaElement.setAttribute("from", stanza->getFrom());
+ }
+ if (stanza->getTo().isValid()) {
+ stanzaElement.setAttribute("to", stanza->getTo());
+ }
+ if (!stanza->getID().isEmpty()) {
+ stanzaElement.setAttribute("id", stanza->getID());
+ }
+ setStanzaSpecificAttributes(stanza, stanzaElement);
+
+ String serializedPayloads;
+ foreach (const boost::shared_ptr<Payload>& payload, stanza->getPayloads()) {
+ PayloadSerializer* serializer = payloadSerializers_->getPayloadSerializer(payload);
+ if (serializer) {
+ serializedPayloads += serializer->serialize(payload);
+ }
+ else {
+ std::cerr << "Could not find serializer for " << typeid(*(payload.get())).name() << std::endl;
+ }
+ }
+ if (!serializedPayloads.isEmpty()) {
+ stanzaElement.addNode(boost::shared_ptr<XMLNode>(new XMLRawTextNode(serializedPayloads)));
+ }
+
+ return stanzaElement.serialize();
+}
+
+}
diff --git a/Swiften/Serializer/StanzaSerializer.h b/Swiften/Serializer/StanzaSerializer.h
new file mode 100644
index 0000000..0f7abaf
--- /dev/null
+++ b/Swiften/Serializer/StanzaSerializer.h
@@ -0,0 +1,25 @@
+#ifndef SWIFTEN_STANZASERIALIZER_H
+#define SWIFTEN_STANZASERIALIZER_H
+
+#include "Swiften/Elements/Stanza.h"
+#include "Swiften/Serializer/ElementSerializer.h"
+#include "Swiften/Base/String.h"
+
+namespace Swift {
+ class PayloadSerializerCollection;
+ class XMLElement;
+
+ class StanzaSerializer : public ElementSerializer {
+ public:
+ StanzaSerializer(const String& tag, PayloadSerializerCollection* payloadSerializers);
+
+ virtual String serialize(boost::shared_ptr<Element>) const;
+ virtual void setStanzaSpecificAttributes(boost::shared_ptr<Element>, XMLElement&) const = 0;
+
+ private:
+ String tag_;
+ PayloadSerializerCollection* payloadSerializers_;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/StartTLSFailureSerializer.h b/Swiften/Serializer/StartTLSFailureSerializer.h
new file mode 100644
index 0000000..472fea0
--- /dev/null
+++ b/Swiften/Serializer/StartTLSFailureSerializer.h
@@ -0,0 +1,22 @@
+#ifndef SWIFTEN_StartTLSFailureSerializer_H
+#define SWIFTEN_StartTLSFailureSerializer_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/StartTLSFailure.h"
+#include "Swiften/Serializer/GenericElementSerializer.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+ class StartTLSFailureSerializer : public GenericElementSerializer<StartTLSFailure> {
+ public:
+ StartTLSFailureSerializer() : GenericElementSerializer<StartTLSFailure>() {
+ }
+
+ virtual String serialize(boost::shared_ptr<Element>) const {
+ return XMLElement("failure", "urn:ietf:params:xml:ns:xmpp-tls").serialize();
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/StartTLSRequestSerializer.h b/Swiften/Serializer/StartTLSRequestSerializer.h
new file mode 100644
index 0000000..fa85fe2
--- /dev/null
+++ b/Swiften/Serializer/StartTLSRequestSerializer.h
@@ -0,0 +1,22 @@
+#ifndef SWIFTEN_StartTLSRequestSerializer_H
+#define SWIFTEN_StartTLSRequestSerializer_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/StartTLSRequest.h"
+#include "Swiften/Serializer/GenericElementSerializer.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+ class StartTLSRequestSerializer : public GenericElementSerializer<StartTLSRequest> {
+ public:
+ StartTLSRequestSerializer() : GenericElementSerializer<StartTLSRequest>() {
+ }
+
+ virtual String serialize(boost::shared_ptr<Element>) const {
+ return XMLElement("starttls", "urn:ietf:params:xml:ns:xmpp-tls").serialize();
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/StreamFeaturesSerializer.cpp b/Swiften/Serializer/StreamFeaturesSerializer.cpp
new file mode 100644
index 0000000..49e62c4
--- /dev/null
+++ b/Swiften/Serializer/StreamFeaturesSerializer.cpp
@@ -0,0 +1,46 @@
+#include "Swiften/Serializer/StreamFeaturesSerializer.h"
+
+#include "Swiften/Serializer/XML/XMLElement.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+#include "Swiften/Base/foreach.h"
+
+namespace Swift {
+
+StreamFeaturesSerializer::StreamFeaturesSerializer() {
+}
+
+String StreamFeaturesSerializer::serialize(boost::shared_ptr<Element> element) const {
+ boost::shared_ptr<StreamFeatures> streamFeatures(boost::dynamic_pointer_cast<StreamFeatures>(element));
+
+ XMLElement streamFeaturesElement("stream:features");
+ if (streamFeatures->hasStartTLS()) {
+ streamFeaturesElement.addNode(boost::shared_ptr<XMLElement>(new XMLElement("starttls", "urn:ietf:params:xml:ns:xmpp-tls")));
+ }
+ if (!streamFeatures->getCompressionMethods().empty()) {
+ boost::shared_ptr<XMLElement> compressionElement(new XMLElement("compression", "http://jabber.org/features/compress"));
+ foreach(const String& method, streamFeatures->getCompressionMethods()) {
+ boost::shared_ptr<XMLElement> methodElement(new XMLElement("method"));
+ methodElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(method)));
+ compressionElement->addNode(methodElement);
+ }
+ streamFeaturesElement.addNode(compressionElement);
+ }
+ if (!streamFeatures->getAuthenticationMechanisms().empty()) {
+ boost::shared_ptr<XMLElement> mechanismsElement(new XMLElement("mechanisms", "urn:ietf:params:xml:ns:xmpp-sasl"));
+ foreach(const String& mechanism, streamFeatures->getAuthenticationMechanisms()) {
+ boost::shared_ptr<XMLElement> mechanismElement(new XMLElement("mechanism"));
+ mechanismElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(mechanism)));
+ mechanismsElement->addNode(mechanismElement);
+ }
+ streamFeaturesElement.addNode(mechanismsElement);
+ }
+ if (streamFeatures->hasResourceBind()) {
+ streamFeaturesElement.addNode(boost::shared_ptr<XMLElement>(new XMLElement("bind", "urn:ietf:params:xml:ns:xmpp-bind")));
+ }
+ if (streamFeatures->hasSession()) {
+ streamFeaturesElement.addNode(boost::shared_ptr<XMLElement>(new XMLElement("session", "urn:ietf:params:xml:ns:xmpp-session")));
+ }
+ return streamFeaturesElement.serialize();
+}
+
+}
diff --git a/Swiften/Serializer/StreamFeaturesSerializer.h b/Swiften/Serializer/StreamFeaturesSerializer.h
new file mode 100644
index 0000000..f2da1bf
--- /dev/null
+++ b/Swiften/Serializer/StreamFeaturesSerializer.h
@@ -0,0 +1,18 @@
+#ifndef SWIFTEN_StreamFeaturesSerializer_H
+#define SWIFTEN_StreamFeaturesSerializer_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/StreamFeatures.h"
+#include "Swiften/Serializer/GenericElementSerializer.h"
+
+namespace Swift {
+ class StreamFeaturesSerializer : public GenericElementSerializer<StreamFeatures> {
+ public:
+ StreamFeaturesSerializer();
+
+ virtual String serialize(boost::shared_ptr<Element> element) const;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/TLSProceedSerializer.h b/Swiften/Serializer/TLSProceedSerializer.h
new file mode 100644
index 0000000..d3829ac
--- /dev/null
+++ b/Swiften/Serializer/TLSProceedSerializer.h
@@ -0,0 +1,22 @@
+#ifndef SWIFTEN_TLSProceedSerializer_H
+#define SWIFTEN_TLSProceedSerializer_H
+
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Elements/TLSProceed.h"
+#include "Swiften/Serializer/GenericElementSerializer.h"
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+namespace Swift {
+ class TLSProceedSerializer : public GenericElementSerializer<TLSProceed> {
+ public:
+ TLSProceedSerializer() : GenericElementSerializer<TLSProceed>() {
+ }
+
+ virtual String serialize(boost::shared_ptr<Element>) const {
+ return XMLElement("proceed", "urn:ietf:params:xml:ns:xmpp-tls").serialize();
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/UnitTest/Makefile.inc b/Swiften/Serializer/UnitTest/Makefile.inc
new file mode 100644
index 0000000..818663b
--- /dev/null
+++ b/Swiften/Serializer/UnitTest/Makefile.inc
@@ -0,0 +1,2 @@
+UNITTEST_SOURCES += \
+ Swiften/Serializer/UnitTest/StreamFeaturesSerializerTest.cpp
diff --git a/Swiften/Serializer/UnitTest/StreamFeaturesSerializerTest.cpp b/Swiften/Serializer/UnitTest/StreamFeaturesSerializerTest.cpp
new file mode 100644
index 0000000..187fe64
--- /dev/null
+++ b/Swiften/Serializer/UnitTest/StreamFeaturesSerializerTest.cpp
@@ -0,0 +1,46 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/StreamFeaturesSerializer.h"
+#include "Swiften/Elements/StreamFeatures.h"
+
+using namespace Swift;
+
+class StreamFeaturesSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(StreamFeaturesSerializerTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ StreamFeaturesSerializerTest() {}
+
+ void testSerialize() {
+ StreamFeaturesSerializer testling;
+ boost::shared_ptr<StreamFeatures> streamFeatures(new StreamFeatures());
+ streamFeatures->setHasStartTLS();
+ streamFeatures->addCompressionMethod("zlib");
+ streamFeatures->addCompressionMethod("lzw");
+ streamFeatures->addAuthenticationMechanism("DIGEST-MD5");
+ streamFeatures->addAuthenticationMechanism("PLAIN");
+ streamFeatures->setHasResourceBind();
+ streamFeatures->setHasSession();
+
+ CPPUNIT_ASSERT_EQUAL(String(
+ "<stream:features>"
+ "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>"
+ "<compression xmlns=\"http://jabber.org/features/compress\">"
+ "<method>zlib</method>"
+ "<method>lzw</method>"
+ "</compression>"
+ "<mechanisms xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"
+ "<mechanism>DIGEST-MD5</mechanism>"
+ "<mechanism>PLAIN</mechanism>"
+ "</mechanisms>"
+ "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/>"
+ "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>"
+ "</stream:features>"), testling.serialize(streamFeatures));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(StreamFeaturesSerializerTest);
diff --git a/Swiften/Serializer/XML/Makefile.inc b/Swiften/Serializer/XML/Makefile.inc
new file mode 100644
index 0000000..6daca82
--- /dev/null
+++ b/Swiften/Serializer/XML/Makefile.inc
@@ -0,0 +1,5 @@
+SWIFTEN_SOURCES += \
+ Swiften/Serializer/XML/XMLNode.cpp \
+ Swiften/Serializer/XML/XMLElement.cpp
+
+include Swiften/Serializer/XML/UnitTest/Makefile.inc
diff --git a/Swiften/Serializer/XML/UnitTest/Makefile.inc b/Swiften/Serializer/XML/UnitTest/Makefile.inc
new file mode 100644
index 0000000..fa00b76
--- /dev/null
+++ b/Swiften/Serializer/XML/UnitTest/Makefile.inc
@@ -0,0 +1,2 @@
+UNITTEST_SOURCES += \
+ Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp
diff --git a/Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp b/Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp
new file mode 100644
index 0000000..49eb109
--- /dev/null
+++ b/Swiften/Serializer/XML/UnitTest/XMLElementTest.cpp
@@ -0,0 +1,62 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Serializer/XML/XMLElement.h"
+#include "Swiften/Serializer/XML/XMLTextNode.h"
+
+using namespace Swift;
+
+class XMLElementTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(XMLElementTest);
+ CPPUNIT_TEST(testSerialize);
+ CPPUNIT_TEST(testSerialize_NoChildren);
+ CPPUNIT_TEST(testSerialize_SpecialAttributeCharacters);
+ CPPUNIT_TEST(testSerialize_EmptyAttributeValue);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ XMLElementTest() {}
+
+ void testSerialize() {
+ XMLElement testling("foo", "http://example.com");
+ testling.setAttribute("myatt", "myval");
+ boost::shared_ptr<XMLElement> barElement(new XMLElement("bar"));
+ barElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode("Blo")));
+ testling.addNode(barElement);
+ boost::shared_ptr<XMLElement> bazElement(new XMLElement("baz"));
+ bazElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode("Bli")));
+ testling.addNode(bazElement);
+
+ String result = testling.serialize();
+ String expectedResult =
+ "<foo myatt=\"myval\" xmlns=\"http://example.com\">"
+ "<bar>Blo</bar>"
+ "<baz>Bli</baz>"
+ "</foo>";
+
+ CPPUNIT_ASSERT_EQUAL(expectedResult, result);
+ }
+
+ void testSerialize_NoChildren() {
+ XMLElement testling("foo", "http://example.com");
+
+ CPPUNIT_ASSERT_EQUAL(String("<foo xmlns=\"http://example.com\"/>"), testling.serialize());
+ }
+
+ void testSerialize_SpecialAttributeCharacters() {
+ XMLElement testling("foo");
+ testling.setAttribute("myatt", "<\"'&>");
+
+ CPPUNIT_ASSERT_EQUAL(String("<foo myatt=\"&lt;&quot;&apos;&amp;&gt;\"/>"), testling.serialize());
+ }
+
+ void testSerialize_EmptyAttributeValue() {
+ XMLElement testling("foo");
+ testling.setAttribute("myatt", "");
+
+ CPPUNIT_ASSERT_EQUAL(String("<foo myatt=\"\"/>"), testling.serialize());
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(XMLElementTest);
diff --git a/Swiften/Serializer/XML/XMLElement.cpp b/Swiften/Serializer/XML/XMLElement.cpp
new file mode 100644
index 0000000..af2cb34
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLElement.cpp
@@ -0,0 +1,49 @@
+#include "Swiften/Serializer/XML/XMLElement.h"
+
+#include "Swiften/Base/foreach.h"
+
+namespace Swift {
+
+XMLElement::XMLElement(const String& tag, const String& xmlns) :
+ tag_(tag) {
+ if (!xmlns.isEmpty()) {
+ setAttribute("xmlns", xmlns);
+ }
+}
+
+String XMLElement::serialize() {
+ String result;
+ result += "<" + tag_;
+ typedef std::pair<String,String> Pair;
+ foreach(const Pair& p, attributes_) {
+ result += " " + p.first + "=\"" + p.second + "\"";
+ }
+
+ if (childNodes_.size() > 0) {
+ result += ">";
+ foreach (boost::shared_ptr<XMLNode> node, childNodes_) {
+ result += node->serialize();
+ }
+ result += "</" + tag_ + ">";
+ }
+ else {
+ result += "/>";
+ }
+ return result;
+}
+
+void XMLElement::setAttribute(const String& attribute, const String& value) {
+ String escapedValue(value);
+ escapedValue.replaceAll('&', "&amp;");
+ escapedValue.replaceAll('<', "&lt;");
+ escapedValue.replaceAll('>', "&gt;");
+ escapedValue.replaceAll('\'', "&apos;");
+ escapedValue.replaceAll('"', "&quot;");
+ attributes_[attribute] = escapedValue;
+}
+
+void XMLElement::addNode(boost::shared_ptr<XMLNode> node) {
+ childNodes_.push_back(node);
+}
+
+}
diff --git a/Swiften/Serializer/XML/XMLElement.h b/Swiften/Serializer/XML/XMLElement.h
new file mode 100644
index 0000000..f2eb8bf
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLElement.h
@@ -0,0 +1,27 @@
+#ifndef SWIFTEN_XMLElement_H
+#define SWIFTEN_XMLElement_H
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include <map>
+
+#include "Swiften/Base/String.h"
+#include "Swiften/Serializer/XML/XMLNode.h"
+
+namespace Swift {
+ class XMLElement : public XMLNode {
+ public:
+ XMLElement(const String& tag, const String& xmlns = "");
+
+ void setAttribute(const String& attribute, const String& value);
+ void addNode(boost::shared_ptr<XMLNode> node);
+
+ virtual String serialize();
+
+ private:
+ String tag_;
+ std::map<String, String> attributes_;
+ std::vector< boost::shared_ptr<XMLNode> > childNodes_;
+ };
+}
+#endif
diff --git a/Swiften/Serializer/XML/XMLNode.cpp b/Swiften/Serializer/XML/XMLNode.cpp
new file mode 100644
index 0000000..1bef64a
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLNode.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/Serializer/XML/XMLNode.h"
+
+namespace Swift {
+
+XMLNode::~XMLNode() {
+}
+
+}
diff --git a/Swiften/Serializer/XML/XMLNode.h b/Swiften/Serializer/XML/XMLNode.h
new file mode 100644
index 0000000..b31c0d6
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLNode.h
@@ -0,0 +1,15 @@
+#ifndef SWIFTEN_XMLNode_H
+#define SWIFTEN_XMLNode_H
+
+#include "Swiften/Base/String.h"
+
+namespace Swift {
+ class XMLNode {
+ public:
+ virtual ~XMLNode();
+
+ virtual String serialize() = 0;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/XML/XMLRawTextNode.h b/Swiften/Serializer/XML/XMLRawTextNode.h
new file mode 100644
index 0000000..e5800c3
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLRawTextNode.h
@@ -0,0 +1,21 @@
+#ifndef SWIFTEN_XMLRawTextNode_H
+#define SWIFTEN_XMLRawTextNode_H
+
+#include "Swiften/Serializer/XML/XMLNode.h"
+
+namespace Swift {
+ class XMLRawTextNode : public XMLNode {
+ public:
+ XMLRawTextNode(const String& text) : text_(text) {
+ }
+
+ String serialize() {
+ return text_;
+ }
+
+ private:
+ String text_;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/XML/XMLTextNode.h b/Swiften/Serializer/XML/XMLTextNode.h
new file mode 100644
index 0000000..a142325
--- /dev/null
+++ b/Swiften/Serializer/XML/XMLTextNode.h
@@ -0,0 +1,23 @@
+#ifndef SWIFTEN_XMLTextNode_H
+#define SWIFTEN_XMLTextNode_H
+
+#include "Swiften/Serializer/XML/XMLNode.h"
+
+namespace Swift {
+ class XMLTextNode : public XMLNode {
+ public:
+ XMLTextNode(const String& text) : text_(text) {
+ text_.replaceAll('&', "&amp;"); // Should come first
+ text_.replaceAll('<', "&lt;");
+ }
+
+ String serialize() {
+ return text_;
+ }
+
+ private:
+ String text_;
+ };
+}
+
+#endif
diff --git a/Swiften/Serializer/XMPPSerializer.cpp b/Swiften/Serializer/XMPPSerializer.cpp
new file mode 100644
index 0000000..c43f9db
--- /dev/null
+++ b/Swiften/Serializer/XMPPSerializer.cpp
@@ -0,0 +1,58 @@
+#include "Swiften/Serializer/XMPPSerializer.h"
+
+#include <boost/bind.hpp>
+#include <iostream>
+
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Serializer/CompressRequestSerializer.h"
+#include "Swiften/Serializer/CompressFailureSerializer.h"
+#include "Swiften/Serializer/StreamFeaturesSerializer.h"
+#include "Swiften/Serializer/AuthRequestSerializer.h"
+#include "Swiften/Serializer/AuthFailureSerializer.h"
+#include "Swiften/Serializer/AuthSuccessSerializer.h"
+#include "Swiften/Serializer/StartTLSRequestSerializer.h"
+#include "Swiften/Serializer/StartTLSFailureSerializer.h"
+#include "Swiften/Serializer/TLSProceedSerializer.h"
+#include "Swiften/Serializer/MessageSerializer.h"
+#include "Swiften/Serializer/PresenceSerializer.h"
+#include "Swiften/Serializer/IQSerializer.h"
+
+namespace Swift {
+
+XMPPSerializer::XMPPSerializer(PayloadSerializerCollection* payloadSerializers) {
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new PresenceSerializer(payloadSerializers)));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new IQSerializer(payloadSerializers)));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new MessageSerializer(payloadSerializers)));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new CompressRequestSerializer()));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new CompressFailureSerializer()));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthRequestSerializer()));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthFailureSerializer()));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new AuthSuccessSerializer()));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StartTLSRequestSerializer()));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StartTLSFailureSerializer()));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new TLSProceedSerializer()));
+ serializers_.push_back(boost::shared_ptr<ElementSerializer>(new StreamFeaturesSerializer()));
+}
+
+String XMPPSerializer::serializeHeader(const String& domain) const {
+ return "<?xml version='1.0'?><stream:stream to='" + domain + "' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' >";
+}
+
+String XMPPSerializer::serializeElement(boost::shared_ptr<Element> element) const {
+ std::vector< boost::shared_ptr<ElementSerializer> >::const_iterator i = std::find_if(
+ serializers_.begin(), serializers_.end(),
+ boost::bind(&ElementSerializer::canSerialize, _1, element));
+ if (i != serializers_.end()) {
+ return (*i)->serialize(element);
+ }
+ else {
+ std::cerr << "Could not find serializer for " << typeid(*(element.get())).name() << std::endl;
+ return "";
+ }
+}
+
+String XMPPSerializer::serializeFooter() const {
+ return "</stream:stream>";
+}
+
+}
diff --git a/Swiften/Serializer/XMPPSerializer.h b/Swiften/Serializer/XMPPSerializer.h
new file mode 100644
index 0000000..1fc8b9d
--- /dev/null
+++ b/Swiften/Serializer/XMPPSerializer.h
@@ -0,0 +1,28 @@
+#ifndef SWIFTEN_XMPPSERIALIZER_H
+#define SWIFTEN_XMPPSERIALIZER_H
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+#include "Swiften/Elements/Element.h"
+#include "Swiften/Base/String.h"
+#include "Swiften/Serializer/ElementSerializer.h"
+
+namespace Swift {
+ class PayloadSerializerCollection;
+ class CompressRequestSerializer;
+
+ class XMPPSerializer {
+ public:
+ XMPPSerializer(PayloadSerializerCollection*);
+
+ String serializeHeader(const String& domain) const;
+ String serializeElement(boost::shared_ptr<Element> stanza) const;
+ String serializeFooter() const;
+
+ private:
+ std::vector< boost::shared_ptr<ElementSerializer> > serializers_;
+ };
+}
+
+#endif