diff --git a/include/Swiften/Elements/XHTMLIMPayload.cpp b/include/Swiften/Elements/XHTMLIMPayload.cpp
new file mode 100644
index 00000000..75ceb6d0
--- /dev/null
+++ b/include/Swiften/Elements/XHTMLIMPayload.cpp
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2011 Jan Kaluza
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include
+
+namespace Swift {
+
+XHTMLIMPayload::XHTMLIMPayload(const std::string &body) : body_(body) {
+}
+
+}
diff --git a/include/Swiften/Elements/XHTMLIMPayload.h b/include/Swiften/Elements/XHTMLIMPayload.h
new file mode 100644
index 00000000..7972ffd3
--- /dev/null
+++ b/include/Swiften/Elements/XHTMLIMPayload.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011 Jan Kaluza
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include
+
+#include
+#include
+
+namespace Swift {
+ class XHTMLIMPayload : public Payload {
+ public:
+ XHTMLIMPayload(const std::string &body = "");
+
+ const std::string& getBody() const { return body_; }
+
+ void setBody(const std::string& body) {
+ body_ = body;
+ }
+
+ private:
+ std::string body_;
+ };
+}
diff --git a/include/Swiften/Parser/PayloadParsers/XHTMLIMParser.cpp b/include/Swiften/Parser/PayloadParsers/XHTMLIMParser.cpp
new file mode 100644
index 00000000..32f90d29
--- /dev/null
+++ b/include/Swiften/Parser/PayloadParsers/XHTMLIMParser.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011 Jan Kaluza
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include
+#include
+
+namespace Swift {
+
+XHTMLIMParser::XHTMLIMParser() : level_(TopLevel), bodyParser_(0) {
+}
+
+void XHTMLIMParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) {
+ ++level_;
+ if (level_ == BodyLevel) {
+ if (element == "body") {
+ assert(!bodyParser_);
+ bodyParser_ = new SerializingParser();
+ }
+ }
+ else if (level_ >= InsideBodyLevel && bodyParser_) {
+ bodyParser_->handleStartElement(element, ns, attributes);
+ }
+}
+
+void XHTMLIMParser::handleEndElement(const std::string& element, const std::string& ns) {
+ if (level_ == BodyLevel) {
+ if (bodyParser_) {
+ if (element == "body") {
+ getPayloadInternal()->setBody(bodyParser_->getResult());
+ }
+ delete bodyParser_;
+ bodyParser_ = 0;
+ }
+ }
+ else if (bodyParser_ && level_ >= InsideBodyLevel) {
+ bodyParser_->handleEndElement(element, ns);
+ }
+ --level_;
+}
+
+void XHTMLIMParser::handleCharacterData(const std::string& data) {
+ if (bodyParser_) {
+ bodyParser_->handleCharacterData(data);
+ }
+ else {
+ currentText_ += data;
+ }
+}
+
+boost::shared_ptr XHTMLIMParser::getLabelPayload() const {
+ return getPayloadInternal();
+}
+
+}
diff --git a/include/Swiften/Parser/PayloadParsers/XHTMLIMParser.h b/include/Swiften/Parser/PayloadParsers/XHTMLIMParser.h
new file mode 100644
index 00000000..25b11056
--- /dev/null
+++ b/include/Swiften/Parser/PayloadParsers/XHTMLIMParser.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011 Jan Kaluza
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include
+#include
+
+namespace Swift {
+ class SerializingParser;
+
+ class XHTMLIMParser : public GenericPayloadParser {
+ public:
+ XHTMLIMParser();
+
+ virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string&);
+ virtual void handleCharacterData(const std::string& data);
+ boost::shared_ptr getLabelPayload() const;
+ private:
+ enum Level {
+ TopLevel = 0,
+ PayloadLevel = 1,
+ BodyLevel = 2,
+ InsideBodyLevel = 3
+ };
+ int level_;
+ SerializingParser* bodyParser_;
+ std::string currentText_;
+ };
+}
diff --git a/include/Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.cpp b/include/Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.cpp
new file mode 100644
index 00000000..260aad2b
--- /dev/null
+++ b/include/Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011 Jan Kaluza
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+namespace Swift {
+
+XHTMLIMSerializer::XHTMLIMSerializer() : GenericPayloadSerializer() {
+}
+
+std::string XHTMLIMSerializer::serializePayload(boost::shared_ptr payload) const {
+ XMLElement html("html", "http://jabber.org/protocol/xhtml-im");
+
+ boost::shared_ptr body(new XMLElement("body", "http://www.w3.org/1999/xhtml"));
+ body->addNode(boost::shared_ptr(new XMLRawTextNode(payload->getBody())));
+ html.addNode(body);
+
+ return html.serialize();
+}
+
+}
diff --git a/include/Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h b/include/Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h
new file mode 100644
index 00000000..0abc523c
--- /dev/null
+++ b/include/Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2011 Jan Kaluza
+ * Licensed under the Simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include
+#include
+
+namespace Swift {
+ class XHTMLIMSerializer : public GenericPayloadSerializer {
+ public:
+ XHTMLIMSerializer();
+
+ virtual std::string serializePayload(boost::shared_ptr xhtml) const;
+ };
+}
diff --git a/src/transport.cpp b/src/transport.cpp
index dce9bfc5..ac8746ce 100644
--- a/src/transport.cpp
+++ b/src/transport.cpp
@@ -30,6 +30,8 @@
#include "Swiften/TLS/OpenSSL/OpenSSLServerContextFactory.h"
#include "Swiften/Parser/PayloadParsers/AttentionParser.h"
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
+#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
+#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
#include "log4cxx/logger.h"
#include "log4cxx/consoleappender.h"
#include "log4cxx/patternlayout.h"
@@ -104,8 +106,10 @@ Component::Component(Swift::EventLoop *loop, Config *config, Factory *factory) {
m_server->addPayloadParserFactory(new GenericPayloadParserFactory("private", "jabber:iq:private"));
m_server->addPayloadParserFactory(new GenericPayloadParserFactory("attention", "urn:xmpp:attention:0"));
+ m_server->addPayloadParserFactory(new GenericPayloadParserFactory("html", "http://jabber.org/protocol/xhtml-im"));
m_server->addPayloadSerializer(new Swift::AttentionSerializer());
+ m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer());
m_server->onDataRead.connect(bind(&Component::handleDataRead, this, _1));
m_server->onDataWritten.connect(bind(&Component::handleDataWritten, this, _1));