From d67ecb18c1178ecf69e6cb5e8c8ee1fecee35e4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sun, 19 Dec 2010 15:10:39 +0100
Subject: Refactoring streamstack to not use signal/slots.


diff --git a/Swiften/Session/BasicSessionStream.cpp b/Swiften/Session/BasicSessionStream.cpp
index 45489cf..c4d1b6d 100644
--- a/Swiften/Session/BasicSessionStream.cpp
+++ b/Swiften/Session/BasicSessionStream.cpp
@@ -19,12 +19,29 @@
 
 namespace Swift {
 
-BasicSessionStream::BasicSessionStream(StreamType streamType, boost::shared_ptr<Connection> connection, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers, TLSContextFactory* tlsContextFactory, TimerFactory* timerFactory) : available(false), connection(connection), payloadParserFactories(payloadParserFactories), payloadSerializers(payloadSerializers), tlsContextFactory(tlsContextFactory), timerFactory(timerFactory), streamType(streamType) {
+BasicSessionStream::BasicSessionStream(
+		StreamType streamType, 
+		boost::shared_ptr<Connection> connection, 
+		PayloadParserFactoryCollection* payloadParserFactories, 
+		PayloadSerializerCollection* payloadSerializers, 
+		TLSContextFactory* tlsContextFactory, 
+		TimerFactory* timerFactory) : 
+			available(false), 
+			connection(connection), 
+			payloadParserFactories(payloadParserFactories), 
+			payloadSerializers(payloadSerializers), 
+			tlsContextFactory(tlsContextFactory), 
+			timerFactory(timerFactory), 
+			streamType(streamType),
+			xmppLayer(NULL),
+			connectionLayer(NULL),
+			compressionLayer(NULL),
+			tlsLayer(NULL),
+			whitespacePingLayer(NULL) {
 }
 
 void BasicSessionStream::initialize() {
-	xmppLayer = boost::shared_ptr<XMPPLayer>(
-			new XMPPLayer(payloadParserFactories, payloadSerializers, streamType));
+	xmppLayer = new XMPPLayer(payloadParserFactories, payloadSerializers, streamType);
 	xmppLayer->onStreamStart.connect(boost::bind(&BasicSessionStream::handleStreamStartReceived, shared_from_this(), _1));
 	xmppLayer->onElement.connect(boost::bind(&BasicSessionStream::handleElementReceived, shared_from_this(), _1));
 	xmppLayer->onError.connect(boost::bind(
@@ -33,8 +50,7 @@ void BasicSessionStream::initialize() {
 	xmppLayer->onWriteData.connect(boost::bind(&BasicSessionStream::handleDataWritten, shared_from_this(), _1));
 
 	connection->onDisconnected.connect(boost::bind(&BasicSessionStream::handleConnectionError, shared_from_this(), _1));
-	connectionLayer = boost::shared_ptr<ConnectionLayer>(
-			new ConnectionLayer(connection));
+	connectionLayer = new ConnectionLayer(connection);
 
 	streamStack = new StreamStack(xmppLayer, connectionLayer);
 
@@ -42,7 +58,12 @@ void BasicSessionStream::initialize() {
 }
 
 BasicSessionStream::~BasicSessionStream() {
+	delete compressionLayer;
+	delete tlsLayer;
+	delete whitespacePingLayer;
 	delete streamStack;
+	delete connectionLayer;
+	delete xmppLayer;
 }
 
 void BasicSessionStream::writeHeader(const ProtocolHeader& header) {
@@ -70,7 +91,7 @@ bool BasicSessionStream::supportsTLSEncryption() {
 
 void BasicSessionStream::addTLSEncryption() {
 	assert(available);
-	tlsLayer = boost::shared_ptr<TLSLayer>(new TLSLayer(tlsContextFactory));
+	tlsLayer = new TLSLayer(tlsContextFactory);
 	if (hasTLSCertificate() && !tlsLayer->setClientCertificate(getTLSCertificate())) {
 		onError(boost::shared_ptr<Error>(new Error(Error::InvalidTLSCertificateError)));
 	}
@@ -99,14 +120,14 @@ ByteArray BasicSessionStream::getTLSFinishMessage() const {
 }
 
 void BasicSessionStream::addZLibCompression() {
-	boost::shared_ptr<CompressionLayer> compressionLayer(new CompressionLayer());
+	compressionLayer = new CompressionLayer();
 	streamStack->addLayer(compressionLayer);
 }
 
 void BasicSessionStream::setWhitespacePingEnabled(bool enabled) {
 	if (enabled) {
 		if (!whitespacePingLayer) {
-			whitespacePingLayer = boost::shared_ptr<WhitespacePingLayer>(new WhitespacePingLayer(timerFactory));
+			whitespacePingLayer = new WhitespacePingLayer(timerFactory);
 			streamStack->addLayer(whitespacePingLayer);
 		}
 		whitespacePingLayer->setActive();
diff --git a/Swiften/Session/BasicSessionStream.h b/Swiften/Session/BasicSessionStream.h
index 6927800..c601792 100644
--- a/Swiften/Session/BasicSessionStream.h
+++ b/Swiften/Session/BasicSessionStream.h
@@ -78,12 +78,12 @@ namespace Swift {
 			TLSContextFactory* tlsContextFactory;
 			TimerFactory* timerFactory;
 			StreamType streamType;
-			boost::shared_ptr<XMPPLayer> xmppLayer;
-			boost::shared_ptr<ConnectionLayer> connectionLayer;
+			XMPPLayer* xmppLayer;
+			ConnectionLayer* connectionLayer;
+			CompressionLayer* compressionLayer;
+			TLSLayer* tlsLayer;
+			WhitespacePingLayer* whitespacePingLayer;
 			StreamStack* streamStack;
-			boost::shared_ptr<CompressionLayer> compressionLayer;
-			boost::shared_ptr<TLSLayer> tlsLayer;
-			boost::shared_ptr<WhitespacePingLayer> whitespacePingLayer;
 	};
 
 }
diff --git a/Swiften/Session/Session.cpp b/Swiften/Session/Session.cpp
index 747d1d9..39fab14 100644
--- a/Swiften/Session/Session.cpp
+++ b/Swiften/Session/Session.cpp
@@ -20,12 +20,16 @@ Session::Session(
 			connection(connection),
 			payloadParserFactories(payloadParserFactories),
 			payloadSerializers(payloadSerializers),
+			xmppLayer(NULL),
+			connectionLayer(NULL),
 			streamStack(0),
 			finishing(false) {
 }
 
 Session::~Session() {
 	delete streamStack;
+	delete connectionLayer;
+	delete xmppLayer;
 }
 
 void Session::startSession() {
@@ -50,8 +54,7 @@ void Session::finishSession(const SessionError& error) {
 }
 
 void Session::initializeStreamStack() {
-	xmppLayer = boost::shared_ptr<XMPPLayer>(
-			new XMPPLayer(payloadParserFactories, payloadSerializers, ClientStreamType));
+	xmppLayer = new XMPPLayer(payloadParserFactories, payloadSerializers, ClientStreamType);
 	xmppLayer->onStreamStart.connect(
 			boost::bind(&Session::handleStreamStart, shared_from_this(), _1));
 	xmppLayer->onElement.connect(boost::bind(&Session::handleElement, shared_from_this(), _1));
@@ -61,7 +64,7 @@ void Session::initializeStreamStack() {
 	xmppLayer->onWriteData.connect(boost::bind(boost::ref(onDataWritten), _1));
 	connection->onDisconnected.connect(
 			boost::bind(&Session::handleDisconnected, shared_from_this(), _1));
-	connectionLayer = boost::shared_ptr<ConnectionLayer>(new ConnectionLayer(connection));
+	connectionLayer = new ConnectionLayer(connection);
 	streamStack = new StreamStack(xmppLayer, connectionLayer);
 }
 
diff --git a/Swiften/Session/Session.h b/Swiften/Session/Session.h
index d0ebabb..f8c8f0a 100644
--- a/Swiften/Session/Session.h
+++ b/Swiften/Session/Session.h
@@ -84,7 +84,7 @@ namespace Swift {
 
 			void initializeStreamStack();
 
-			boost::shared_ptr<XMPPLayer> getXMPPLayer() const {
+			XMPPLayer* getXMPPLayer() const {
 				return xmppLayer;
 			}
 
@@ -103,8 +103,8 @@ namespace Swift {
 			boost::shared_ptr<Connection> connection;
 			PayloadParserFactoryCollection* payloadParserFactories;
 			PayloadSerializerCollection* payloadSerializers;
-			boost::shared_ptr<XMPPLayer> xmppLayer;
-			boost::shared_ptr<ConnectionLayer> connectionLayer;
+			XMPPLayer* xmppLayer;
+			ConnectionLayer* connectionLayer;
 			StreamStack* streamStack;
 			bool finishing;
 	};
diff --git a/Swiften/StreamStack/CompressionLayer.h b/Swiften/StreamStack/CompressionLayer.h
index 4da053d..b8293a8 100644
--- a/Swiften/StreamStack/CompressionLayer.h
+++ b/Swiften/StreamStack/CompressionLayer.h
@@ -4,8 +4,7 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#ifndef SWIFTEN_COMPRESSIONLAYER_H
-#define SWIFTEN_COMPRESSIONLAYER_H
+#pragma once
 
 #include <boost/noncopyable.hpp>
 #include "Swiften/Base/boost_bsignals.h"
@@ -26,7 +25,7 @@ namespace Swift {
 
 			virtual void writeData(const ByteArray& data) {
 				try {
-					onWriteData(compressor_.process(data));
+					writeDataToChildLayer(compressor_.process(data));
 				}
 				catch (const ZLibException& e) {
 					onError();
@@ -35,7 +34,7 @@ namespace Swift {
 
 			virtual void handleDataRead(const ByteArray& data) {
 				try {
-					onDataRead(decompressor_.process(data));
+					writeDataToParentLayer(decompressor_.process(data));
 				}
 				catch (const ZLibException& e) {
 					onError();
@@ -50,5 +49,3 @@ namespace Swift {
 			ZLibDecompressor decompressor_;
 	};
 }
-
-#endif
diff --git a/Swiften/StreamStack/ConnectionLayer.h b/Swiften/StreamStack/ConnectionLayer.h
index be72979..fab014e 100644
--- a/Swiften/StreamStack/ConnectionLayer.h
+++ b/Swiften/StreamStack/ConnectionLayer.h
@@ -8,6 +8,7 @@
 
 #include "Swiften/Base/boost_bsignals.h"
 #include <boost/shared_ptr.hpp>
+#include <boost/bind.hpp>
 
 #include "Swiften/StreamStack/LowLayer.h"
 #include "Swiften/Network/Connection.h"
@@ -16,7 +17,7 @@ namespace Swift {
 	class ConnectionLayer : public LowLayer {
 		public:
 			ConnectionLayer(boost::shared_ptr<Connection> connection) : connection(connection) {
-				connection->onDataRead.connect(onDataRead);
+				connection->onDataRead.connect(boost::bind(&ConnectionLayer::writeDataToParentLayer, this, _1));
 			}
 
 			void writeData(const ByteArray& data) {
diff --git a/Swiften/StreamStack/HighLayer.cpp b/Swiften/StreamStack/HighLayer.cpp
index 78b890e..da1eec9 100644
--- a/Swiften/StreamStack/HighLayer.cpp
+++ b/Swiften/StreamStack/HighLayer.cpp
@@ -4,11 +4,21 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#include "Swiften/StreamStack/HighLayer.h"
+#include <Swiften/StreamStack/HighLayer.h>
+
+#include <Swiften/StreamStack/LowLayer.h>
 
 namespace Swift {
 
+HighLayer::HighLayer() : childLayer(NULL) {
+}
+
 HighLayer::~HighLayer() {
 }
 
+void HighLayer::writeDataToChildLayer(const ByteArray& data) {
+	assert(childLayer);
+	childLayer->writeData(data);
+}
+
 }
diff --git a/Swiften/StreamStack/HighLayer.h b/Swiften/StreamStack/HighLayer.h
index f15621e..ca983f9 100644
--- a/Swiften/StreamStack/HighLayer.h
+++ b/Swiften/StreamStack/HighLayer.h
@@ -4,22 +4,34 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#ifndef SWIFTEN_HIGHLAYER_H
-#define SWIFTEN_HIGHLAYER_H
-
-#include "Swiften/Base/boost_bsignals.h"
+#pragma once
 
 #include "Swiften/Base/ByteArray.h"
 
 namespace Swift {
+	class LowLayer;
+
 	class HighLayer {
+			friend class StreamStack;
+
 		public:
+			HighLayer();
 			virtual ~HighLayer();
 
 			virtual void handleDataRead(const ByteArray& data) = 0;
+	
+		protected:
+			LowLayer* getChildLayer() {
+				return childLayer;
+			}
 
-			boost::signal<void (const ByteArray&)> onWriteData;
+			void setChildLayer(LowLayer* childLayer) {
+				this->childLayer = childLayer;
+			}
+
+			void writeDataToChildLayer(const ByteArray& data);
+
+		private:
+			LowLayer* childLayer;
 	};
 }
-
-#endif
diff --git a/Swiften/StreamStack/LowLayer.cpp b/Swiften/StreamStack/LowLayer.cpp
index 6df73a2..ca7b72b 100644
--- a/Swiften/StreamStack/LowLayer.cpp
+++ b/Swiften/StreamStack/LowLayer.cpp
@@ -4,11 +4,21 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#include "Swiften/StreamStack/LowLayer.h"
+#include <Swiften/StreamStack/LowLayer.h>
+
+#include <Swiften/StreamStack/HighLayer.h>
 
 namespace Swift {
 
+LowLayer::LowLayer() : parentLayer(NULL) {
+}
+
 LowLayer::~LowLayer() {
 }
 
+void LowLayer::writeDataToParentLayer(const ByteArray& data) {
+	assert(parentLayer);
+	parentLayer->handleDataRead(data);
+}
+
 }
diff --git a/Swiften/StreamStack/LowLayer.h b/Swiften/StreamStack/LowLayer.h
index 2224adc..1f9645a 100644
--- a/Swiften/StreamStack/LowLayer.h
+++ b/Swiften/StreamStack/LowLayer.h
@@ -4,22 +4,34 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#ifndef SWIFTEN_LOWLAYER_H
-#define SWIFTEN_LOWLAYER_H
-
-#include "Swiften/Base/boost_bsignals.h"
+#pragma once
 
 #include "Swiften/Base/ByteArray.h"
 
 namespace Swift {
+	class HighLayer;
+
 	class LowLayer {
+			friend class StreamStack;
+
 		public:
+			LowLayer();
 			virtual ~LowLayer();
 
 			virtual void writeData(const ByteArray& data) = 0;
+	
+		protected:
+			HighLayer* getParentLayer() {
+				return parentLayer;
+			}
 
-			boost::signal<void (const ByteArray&)> onDataRead;
+			void setParentLayer(HighLayer* parentLayer) {
+				this->parentLayer = parentLayer;
+			}
+
+			void writeDataToParentLayer(const ByteArray& data);
+
+		private:
+			HighLayer* parentLayer;
 	};
 }
-
-#endif
diff --git a/Swiften/StreamStack/StreamLayer.h b/Swiften/StreamStack/StreamLayer.h
index 7ce1149..bcc5d79 100644
--- a/Swiften/StreamStack/StreamLayer.h
+++ b/Swiften/StreamStack/StreamLayer.h
@@ -4,10 +4,7 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#ifndef SWIFTEN_STREAMLAYER_H
-#define SWIFTEN_STREAMLAYER_H
-
-#include "Swiften/Base/boost_bsignals.h"
+#pragma once
 
 #include "Swiften/StreamStack/LowLayer.h"
 #include "Swiften/StreamStack/HighLayer.h"
@@ -18,5 +15,3 @@ namespace Swift {
 			StreamLayer() {}
 	};
 }
-
-#endif
diff --git a/Swiften/StreamStack/StreamStack.cpp b/Swiften/StreamStack/StreamStack.cpp
index b0c68cf..2a30768 100644
--- a/Swiften/StreamStack/StreamStack.cpp
+++ b/Swiften/StreamStack/StreamStack.cpp
@@ -15,31 +15,23 @@
 
 namespace Swift {
 
-StreamStack::StreamStack(boost::shared_ptr<XMPPLayer> xmppLayer, boost::shared_ptr<LowLayer> physicalLayer) : xmppLayer_(xmppLayer), physicalLayer_(physicalLayer) {
-	xmppReadSlotConnection_ = physicalLayer_->onDataRead.connect(boost::bind(&XMPPLayer::parseData, xmppLayer_, _1));
-	xmppWriteSignalConnection_ = xmppLayer_->onWriteData.connect(boost::bind(&LowLayer::writeData, physicalLayer_, _1));
+StreamStack::StreamStack(XMPPLayer* xmppLayer, LowLayer* physicalLayer) : xmppLayer_(xmppLayer), physicalLayer_(physicalLayer) {
+	physicalLayer_->setParentLayer(xmppLayer_);
+	xmppLayer_->setChildLayer(physicalLayer_);
 }
 
 StreamStack::~StreamStack() {
-	// Disconnect the write signal connections to break cyclic signal 
-	// dependencies. The read signal connections have
-	// to remain, since these can be reached from the main event loop.
-	xmppWriteSignalConnection_.disconnect();
-	foreach(const boost::bsignals::connection& connection, writeSignalConnections_) {
-		connection.disconnect();
-	}
 }
 
-void StreamStack::addLayer(boost::shared_ptr<StreamLayer> newLayer) {
-	xmppReadSlotConnection_.disconnect();
-	xmppWriteSignalConnection_.disconnect();
+void StreamStack::addLayer(StreamLayer* newLayer) {
+	LowLayer* lowLayer = layers_.empty() ? physicalLayer_ : *layers_.rbegin();
 
-	boost::shared_ptr<LowLayer> lowLayer = (layers_.empty() ? physicalLayer_ : *layers_.rbegin());
+	xmppLayer_->setChildLayer(newLayer);
+	newLayer->setParentLayer(xmppLayer_);
+	
+	lowLayer->setParentLayer(newLayer);
+	newLayer->setChildLayer(lowLayer);
 
-	lowLayer->onDataRead.connect(boost::bind(&HighLayer::handleDataRead, newLayer, _1), boost::bsignals::at_front);
-	writeSignalConnections_.push_back(newLayer->onWriteData.connect(boost::bind(&LowLayer::writeData, lowLayer, _1), boost::bsignals::at_front));
-	xmppWriteSignalConnection_ = xmppLayer_->onWriteData.connect(boost::bind(&LowLayer::writeData, newLayer, _1), boost::bsignals::at_front);
-	xmppReadSlotConnection_ = newLayer->onDataRead.connect(boost::bind(&XMPPLayer::parseData, xmppLayer_, _1), boost::bsignals::at_front);
 	layers_.push_back(newLayer);
 }
 
diff --git a/Swiften/StreamStack/StreamStack.h b/Swiften/StreamStack/StreamStack.h
index 56bc2de..562245e 100644
--- a/Swiften/StreamStack/StreamStack.h
+++ b/Swiften/StreamStack/StreamStack.h
@@ -20,31 +20,28 @@ namespace Swift {
 
 	class StreamStack {
 		public:
-			StreamStack(boost::shared_ptr<XMPPLayer> xmppLayer, boost::shared_ptr<LowLayer> physicalLayer);
+			StreamStack(XMPPLayer* xmppLayer, LowLayer* physicalLayer);
 			~StreamStack();
 
-			void addLayer(boost::shared_ptr<StreamLayer>);
+			void addLayer(StreamLayer*);
 
-			boost::shared_ptr<XMPPLayer> getXMPPLayer() const {
+			XMPPLayer* getXMPPLayer() const {
 				return xmppLayer_;
 			}
 
-			template<typename T> boost::shared_ptr<T> getLayer() {
-				foreach(const boost::shared_ptr<StreamLayer>& streamLayer, layers_) {
-					boost::shared_ptr<T> layer = boost::dynamic_pointer_cast<T>(streamLayer);
+			template<typename T> T* getLayer() {
+				foreach(StreamLayer* streamLayer, layers_) {
+					T* layer = dynamic_cast<T*>(streamLayer);
 					if (layer) {
 						return layer;
 					}
 				}
-				return boost::shared_ptr<T>();
+				return NULL;
 			}
 
 		private:
-			boost::shared_ptr<XMPPLayer> xmppLayer_;
-			boost::shared_ptr<LowLayer> physicalLayer_;
-			std::vector< boost::shared_ptr<StreamLayer> > layers_;
-			boost::bsignals::connection xmppReadSlotConnection_;
-			boost::bsignals::connection xmppWriteSignalConnection_;
-			std::vector< boost::bsignals::connection > writeSignalConnections_;
+			XMPPLayer* xmppLayer_;
+			LowLayer* physicalLayer_;
+			std::vector<StreamLayer*> layers_;
 	};
 }
diff --git a/Swiften/StreamStack/TLSLayer.cpp b/Swiften/StreamStack/TLSLayer.cpp
index 8cb06fc..8a6c008 100644
--- a/Swiften/StreamStack/TLSLayer.cpp
+++ b/Swiften/StreamStack/TLSLayer.cpp
@@ -5,6 +5,9 @@
  */
 
 #include "Swiften/StreamStack/TLSLayer.h"
+
+#include <boost/bind.hpp>
+
 #include "Swiften/TLS/TLSContextFactory.h"
 #include "Swiften/TLS/TLSContext.h"
 
@@ -12,8 +15,8 @@ namespace Swift {
 
 TLSLayer::TLSLayer(TLSContextFactory* factory) {
 	context = factory->createTLSContext();
-	context->onDataForNetwork.connect(onWriteData);
-	context->onDataForApplication.connect(onDataRead);
+	context->onDataForNetwork.connect(boost::bind(&TLSLayer::writeDataToChildLayer, this, _1));
+	context->onDataForApplication.connect(boost::bind(&TLSLayer::writeDataToParentLayer, this, _1));
 	context->onConnected.connect(onConnected);
 	context->onError.connect(onError);
 }
diff --git a/Swiften/StreamStack/WhitespacePingLayer.cpp b/Swiften/StreamStack/WhitespacePingLayer.cpp
index a99f300..35efc3c 100644
--- a/Swiften/StreamStack/WhitespacePingLayer.cpp
+++ b/Swiften/StreamStack/WhitespacePingLayer.cpp
@@ -21,16 +21,16 @@ WhitespacePingLayer::WhitespacePingLayer(TimerFactory* timerFactory) : isActive(
 }
 
 void WhitespacePingLayer::writeData(const ByteArray& data) {
-	onWriteData(data);
+	writeDataToChildLayer(data);
 }
 
 void WhitespacePingLayer::handleDataRead(const ByteArray& data) {
-	onDataRead(data);
+	writeDataToParentLayer(data);
 }
 
 void WhitespacePingLayer::handleTimerTick() {
 	timer->stop();
-	onWriteData(" ");
+	writeDataToChildLayer(" ");
 	timer->start();
 }
 
diff --git a/Swiften/StreamStack/XMPPLayer.cpp b/Swiften/StreamStack/XMPPLayer.cpp
index d4e329b..3ecda95 100644
--- a/Swiften/StreamStack/XMPPLayer.cpp
+++ b/Swiften/StreamStack/XMPPLayer.cpp
@@ -29,22 +29,27 @@ XMPPLayer::~XMPPLayer() {
 }
 
 void XMPPLayer::writeHeader(const ProtocolHeader& header) {
-	onWriteData(ByteArray(xmppSerializer_->serializeHeader(header)));
+	writeDataInternal(ByteArray(xmppSerializer_->serializeHeader(header)));
 }
 
 void XMPPLayer::writeFooter() {
-	onWriteData(ByteArray(xmppSerializer_->serializeFooter()));
+	writeDataInternal(ByteArray(xmppSerializer_->serializeFooter()));
 }
 
 void XMPPLayer::writeElement(boost::shared_ptr<Element> element) {
-	onWriteData(ByteArray(xmppSerializer_->serializeElement(element)));
+	writeDataInternal(ByteArray(xmppSerializer_->serializeElement(element)));
 }
 
 void XMPPLayer::writeData(const String& data) {
-	onWriteData(ByteArray(data));
+	writeDataInternal(ByteArray(data));
 }
 
-void XMPPLayer::parseData(ByteArray data) {
+void XMPPLayer::writeDataInternal(const ByteArray& data) {
+	onWriteData(data);
+	writeDataToChildLayer(data);
+}
+
+void XMPPLayer::handleDataRead(const ByteArray& data) {
 	onDataRead(data);
 	inParser_ = true;
 	if (!xmppParser_->parse(String(data.getData(), data.getSize()))) {
diff --git a/Swiften/StreamStack/XMPPLayer.h b/Swiften/StreamStack/XMPPLayer.h
index 7316afe..54bb22d 100644
--- a/Swiften/StreamStack/XMPPLayer.h
+++ b/Swiften/StreamStack/XMPPLayer.h
@@ -10,6 +10,7 @@
 #include "Swiften/Base/boost_bsignals.h"
 #include <boost/noncopyable.hpp>
 
+#include <Swiften/StreamStack/HighLayer.h>
 #include "Swiften/Base/ByteArray.h"
 #include "Swiften/Elements/Element.h"
 #include "Swiften/Elements/StreamType.h"
@@ -22,7 +23,7 @@ namespace Swift {
 	class XMPPSerializer;
 	class PayloadSerializerCollection;
 
-	class XMPPLayer : public XMPPParserClient, boost::noncopyable {
+	class XMPPLayer : public XMPPParserClient, public HighLayer, boost::noncopyable {
 		public:
 			XMPPLayer(
 					PayloadParserFactoryCollection* payloadParserFactories,
@@ -35,9 +36,12 @@ namespace Swift {
 			void writeElement(boost::shared_ptr<Element>);
 			void writeData(const String& data);
 
-			void parseData(ByteArray data);
 			void resetParser();
 
+		private:
+			void handleDataRead(const ByteArray& data);
+			void writeDataInternal(const ByteArray& data);
+
 		public:
 			boost::signal<void (const ProtocolHeader&)> onStreamStart;
 			boost::signal<void (boost::shared_ptr<Element>)> onElement;
-- 
cgit v0.10.2-6-g49f6