From bab047c1bef2936124db1346863a902e1064af12 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Wed, 28 Sep 2011 19:42:54 +0200
Subject: Pass read data from connection via shared_ptr.

This should avoid unnecessary copying of the received data
while being processed by the event loop.

diff --git a/QA/Checker/SConscript b/QA/Checker/SConscript
index 96479db..ed17be5 100644
--- a/QA/Checker/SConscript
+++ b/QA/Checker/SConscript
@@ -10,5 +10,6 @@ if env["TEST"] :
 
 	if env["SCONS_STAGE"] == "build" :
 			checker_env = env.Clone()
+			checker_env.MergeFlags(env["BOOST_FLAGS"])
 			checker_env.MergeFlags(env["CPPUNIT_FLAGS"])
 			checker_env.Library("Checker", ["checker.cpp", "IO.cpp"])
diff --git a/Swiften/Base/SafeByteArray.h b/Swiften/Base/SafeByteArray.h
index 032a6d5..1ef1d84 100644
--- a/Swiften/Base/SafeByteArray.h
+++ b/Swiften/Base/SafeByteArray.h
@@ -10,6 +10,7 @@
 
 #include <Swiften/Base/SafeAllocator.h>
 #include <Swiften/Base/ByteArray.h>
+#include <boost/smart_ptr/make_shared.hpp>
 
 namespace Swift {
 	typedef std::vector<unsigned char, SafeAllocator<unsigned char> > SafeByteArray;
@@ -24,6 +25,10 @@ namespace Swift {
 		return SafeByteArray(s.begin(), s.end());
 	}
 
+	inline boost::shared_ptr<SafeByteArray> createSafeByteArrayRef(const std::string& s) {
+		return boost::make_shared<SafeByteArray>(s.begin(), s.end());
+	}
+
 	inline SafeByteArray createSafeByteArray(char c) {
 		return SafeByteArray(1, c);
 	}
@@ -32,10 +37,18 @@ namespace Swift {
 		return SafeByteArray(c, c + n);
 	}
 
+	inline boost::shared_ptr<SafeByteArray> createSafeByteArrayRef(const char* c, size_t n) {
+		return boost::make_shared<SafeByteArray>(c, c + n);
+	}
+
 	inline SafeByteArray createSafeByteArray(const unsigned char* c, size_t n) {
 		return SafeByteArray(c, c + n);
 	}
 
+	inline boost::shared_ptr<SafeByteArray> createSafeByteArrayRef(const unsigned char* c, size_t n) {
+		return boost::make_shared<SafeByteArray>(c, c + n);
+	}
+
 	/* WARNING! This breaks the safety of the data in the safe byte array.
 	 * Do not use in modes that require data safety. */
 	inline std::string safeByteArrayToString(const SafeByteArray& b) {
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp
index a18b998..db3d83f 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp
+++ b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.cpp
@@ -209,15 +209,15 @@ void SOCKS5BytestreamClientSession::handleConnectFinished(bool error) {
 	}
 }
 
-void SOCKS5BytestreamClientSession::handleDataRead(const SafeByteArray& data) {
-	SWIFT_LOG(debug) << "state: " << state << " data.size() = " << data.size() << std::endl;
+void SOCKS5BytestreamClientSession::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
+	SWIFT_LOG(debug) << "state: " << state << " data.size() = " << data->size() << std::endl;
 	if (state != Reading) {
-		append(unprocessedData, data);
+		append(unprocessedData, *data);
 		process();
 	}
 	else {
-		writeBytestream->write(createByteArray(vecptr(data), data.size()));
-		onBytesReceived(data.size());
+		writeBytestream->write(createByteArray(vecptr(*data), data->size()));
+		onBytesReceived(data->size());
 	}
 }
 
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h
index 894e977..ea45955 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h
+++ b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h
@@ -66,7 +66,7 @@ private:
 	void authenticate();
 
 	void handleConnectFinished(bool error);
-	void handleDataRead(const SafeByteArray&);
+	void handleDataRead(boost::shared_ptr<SafeByteArray>);
 	void handleDisconnected(const boost::optional<Connection::Error>&);
 	void handleWeFailedTimeout();
 
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp b/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp
index fa7e054..def9e33 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp
+++ b/Swiften/FileTransfer/SOCKS5BytestreamServerSession.cpp
@@ -65,13 +65,13 @@ HostAddressPort SOCKS5BytestreamServerSession::getAddressPort() const {
 	return connection->getLocalAddress();
 }
 
-void SOCKS5BytestreamServerSession::handleDataRead(const SafeByteArray& data) {
+void SOCKS5BytestreamServerSession::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
 	if (state != ReadingData) {
-		append(unprocessedData, data);
+		append(unprocessedData, *data);
 		process();
 	} else {
-		writeBytestream->write(createByteArray(vecptr(data), data.size()));
-		onBytesReceived(data.size());
+		writeBytestream->write(createByteArray(vecptr(*data), data->size()));
+		onBytesReceived(data->size());
 	}
 }
 
diff --git a/Swiften/FileTransfer/SOCKS5BytestreamServerSession.h b/Swiften/FileTransfer/SOCKS5BytestreamServerSession.h
index 3e1018f..4557a36 100644
--- a/Swiften/FileTransfer/SOCKS5BytestreamServerSession.h
+++ b/Swiften/FileTransfer/SOCKS5BytestreamServerSession.h
@@ -52,7 +52,7 @@ namespace Swift {
 		private:
 			void finish(bool error);
 			void process();
-			void handleDataRead(const SafeByteArray&);
+			void handleDataRead(boost::shared_ptr<SafeByteArray>);
 			void handleDisconnected(const boost::optional<Connection::Error>&);
 			void sendData();
 
diff --git a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp
index 75b9faf..527e0ca 100644
--- a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp
+++ b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamClientSessionTest.cpp
@@ -164,7 +164,7 @@ public:
 		clientSession->startReceiving(output);
 
 		ByteArray transferData = generateRandomByteArray(1024);
-		connection->onDataRead(createSafeByteArray(transferData.data(), transferData.size()));
+		connection->onDataRead(createSafeByteArrayRef(transferData.data(), transferData.size()));
 		CPPUNIT_ASSERT_EQUAL(transferData, output->getData());
 	}
 
@@ -212,35 +212,35 @@ private:
 
 	// Server responses
 	void serverRespondHelloOK() {
-		connection->onDataRead(createSafeByteArray("\x05\00", 2));
+		connection->onDataRead(createSafeByteArrayRef("\x05\00", 2));
 	}
 
 	void serverRespondHelloAuthFail() {
-		connection->onDataRead(createSafeByteArray("\x05\xFF", 2));
+		connection->onDataRead(createSafeByteArrayRef("\x05\xFF", 2));
 	}
 
 	void serverRespondRequestOK() {
-		SafeByteArray dataToSend = createSafeByteArray("\x05\x00\x00\x03", 4);
-		append(dataToSend, createSafeByteArray(destination.size()));
-		append(dataToSend, createSafeByteArray(destination));
-		append(dataToSend, createSafeByteArray("\x00", 1));
+		boost::shared_ptr<SafeByteArray> dataToSend = createSafeByteArrayRef("\x05\x00\x00\x03", 4);
+		append(*dataToSend, createSafeByteArray(destination.size()));
+		append(*dataToSend, createSafeByteArray(destination));
+		append(*dataToSend, createSafeByteArray("\x00", 1));
 		connection->onDataRead(dataToSend);
 	}
 
 	void serverRespondRequestFail() {
-		SafeByteArray correctData = createSafeByteArray("\x05\x00\x00\x03", 4);
-		append(correctData, createSafeByteArray(destination.size()));
-		append(correctData, createSafeByteArray(destination));
-		append(correctData, createSafeByteArray("\x00", 1));
+		boost::shared_ptr<SafeByteArray> correctData = createSafeByteArrayRef("\x05\x00\x00\x03", 4);
+		append(*correctData, createSafeByteArray(destination.size()));
+		append(*correctData, createSafeByteArray(destination));
+		append(*correctData, createSafeByteArray("\x00", 1));
 
-		SafeByteArray dataToSend;
+		boost::shared_ptr<SafeByteArray> dataToSend;
 		//ByteArray failingData = Hexify::unhexify("8417947d1d305c72c11520ea7d2c6e787396705e72c312c6ccc3f66613d7cae1b91b7ab48e8b59a17d559c15fb51");
 		//append(dataToSend, failingData);
 		//SWIFT_LOG(debug) << "hexed: " << Hexify::hexify(failingData) << std::endl;
 		do {
-			ByteArray rndArray = generateRandomByteArray(correctData.size());
-			dataToSend = createSafeByteArray(rndArray.data(), rndArray.size());
-		} while (dataToSend == correctData);
+			ByteArray rndArray = generateRandomByteArray(correctData->size());
+			dataToSend = createSafeByteArrayRef(rndArray.data(), rndArray.size());
+		} while (*dataToSend == *correctData);
 		connection->onDataRead(dataToSend);
 	}
 
diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp
index ac3b444..043743e 100644
--- a/Swiften/Network/BoostConnection.cpp
+++ b/Swiften/Network/BoostConnection.cpp
@@ -13,6 +13,7 @@
 #include <boost/thread.hpp>
 #include <boost/asio/placeholders.hpp>
 #include <boost/asio/write.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
 
 #include <Swiften/Base/Log.h>
 #include <Swiften/Base/Algorithm.h>
@@ -50,7 +51,7 @@ class SharedBuffer {
 // -----------------------------------------------------------------------------
 
 BoostConnection::BoostConnection(boost::shared_ptr<boost::asio::io_service> ioService, EventLoop* eventLoop) :
-		eventLoop(eventLoop), ioService(ioService), socket_(*ioService), readBuffer_(BUFFER_SIZE), writing_(false) {
+		eventLoop(eventLoop), ioService(ioService), socket_(*ioService), writing_(false) {
 }
 
 BoostConnection::~BoostConnection() {
@@ -108,16 +109,17 @@ void BoostConnection::handleConnectFinished(const boost::system::error_code& err
 }
 
 void BoostConnection::doRead() {
+	readBuffer_ = boost::make_shared<SafeByteArray>(BUFFER_SIZE);
 	socket_.async_read_some(
-			boost::asio::buffer(readBuffer_),
+			boost::asio::buffer(*readBuffer_),
 			boost::bind(&BoostConnection::handleSocketRead, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
 }
 
 void BoostConnection::handleSocketRead(const boost::system::error_code& error, size_t bytesTransferred) {
 	SWIFT_LOG(debug) << "Socket read " << error << std::endl;
 	if (!error) {
-		eventLoop->postEvent(boost::bind(boost::ref(onDataRead), createSafeByteArray(&readBuffer_[0], bytesTransferred)), shared_from_this());
-		std::fill(readBuffer_.begin(), readBuffer_.end(), 0);
+		readBuffer_->resize(bytesTransferred);
+		eventLoop->postEvent(boost::bind(boost::ref(onDataRead), readBuffer_), shared_from_this());
 		doRead();
 	}
 	else if (/*error == boost::asio::error::eof ||*/ error == boost::asio::error::operation_aborted) {
diff --git a/Swiften/Network/BoostConnection.h b/Swiften/Network/BoostConnection.h
index 259fcec..7d5ec60 100644
--- a/Swiften/Network/BoostConnection.h
+++ b/Swiften/Network/BoostConnection.h
@@ -59,7 +59,7 @@ namespace Swift {
 			EventLoop* eventLoop;
 			boost::shared_ptr<boost::asio::io_service> ioService;
 			boost::asio::ip::tcp::socket socket_;
-			SafeByteArray readBuffer_;
+			boost::shared_ptr<SafeByteArray> readBuffer_;
 			boost::mutex writeMutex_;
 			bool writing_;
 			SafeByteArray writeQueue_;
diff --git a/Swiften/Network/Connection.h b/Swiften/Network/Connection.h
index 1b9977f..6ad2999 100644
--- a/Swiften/Network/Connection.h
+++ b/Swiften/Network/Connection.h
@@ -36,7 +36,7 @@ namespace Swift {
 		public:
 			boost::signal<void (bool /* error */)> onConnectFinished;
 			boost::signal<void (const boost::optional<Error>&)> onDisconnected;
-			boost::signal<void (const SafeByteArray&)> onDataRead;
+			boost::signal<void (boost::shared_ptr<SafeByteArray>)> onDataRead;
 			boost::signal<void ()> onDataWritten;
 	};
 }
diff --git a/Swiften/Network/DummyConnection.cpp b/Swiften/Network/DummyConnection.cpp
index 9a9d138..09bd06d 100644
--- a/Swiften/Network/DummyConnection.cpp
+++ b/Swiften/Network/DummyConnection.cpp
@@ -7,6 +7,7 @@
 #include <Swiften/Network/DummyConnection.h>
 
 #include <boost/bind.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
 #include <cassert>
 
 namespace Swift {
@@ -15,7 +16,7 @@ DummyConnection::DummyConnection(EventLoop* eventLoop) : eventLoop(eventLoop) {
 }
 
 void DummyConnection::receive(const SafeByteArray& data) {
-	eventLoop->postEvent(boost::bind(boost::ref(onDataRead), SafeByteArray(data)), shared_from_this());
+	eventLoop->postEvent(boost::bind(boost::ref(onDataRead), boost::make_shared<SafeByteArray>(data)), shared_from_this());
 }
 
 void DummyConnection::listen() {
diff --git a/Swiften/Network/HTTPConnectProxiedConnection.cpp b/Swiften/Network/HTTPConnectProxiedConnection.cpp
index 20819ff..e05a933 100644
--- a/Swiften/Network/HTTPConnectProxiedConnection.cpp
+++ b/Swiften/Network/HTTPConnectProxiedConnection.cpp
@@ -73,10 +73,10 @@ void HTTPConnectProxiedConnection::handleConnectionConnectFinished(bool error) {
 	}
 }
 
-void HTTPConnectProxiedConnection::handleDataRead(const SafeByteArray& data) {
+void HTTPConnectProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
 	if (!connected_) {
-		SWIFT_LOG(debug) << byteArrayToString(ByteArray(data.begin(), data.end())) << std::endl;
-		std::vector<std::string> tmp = String::split(byteArrayToString(ByteArray(data.begin(), data.end())), ' ');
+		SWIFT_LOG(debug) << byteArrayToString(ByteArray(data->begin(), data->end())) << std::endl;
+		std::vector<std::string> tmp = String::split(byteArrayToString(ByteArray(data->begin(), data->end())), ' ');
 		if(tmp.size() > 1) {
 			int status = boost::lexical_cast<int> (tmp[1].c_str()); 
 			SWIFT_LOG(debug) << "Proxy Status: " << status << std::endl;
@@ -85,7 +85,7 @@ void HTTPConnectProxiedConnection::handleDataRead(const SafeByteArray& data) {
 				onConnectFinished(false);
 				return;
 			}
-			SWIFT_LOG(debug) << "HTTP Proxy returned an error: " << byteArrayToString(ByteArray(data.begin(), data.end())) << std::endl;
+			SWIFT_LOG(debug) << "HTTP Proxy returned an error: " << byteArrayToString(ByteArray(data->begin(), data->end())) << std::endl;
 		}
 		disconnect();
 		onConnectFinished(true);
diff --git a/Swiften/Network/HTTPConnectProxiedConnection.h b/Swiften/Network/HTTPConnectProxiedConnection.h
index 96c6be8..d3f5b7a 100644
--- a/Swiften/Network/HTTPConnectProxiedConnection.h
+++ b/Swiften/Network/HTTPConnectProxiedConnection.h
@@ -41,7 +41,7 @@ namespace Swift {
 			HTTPConnectProxiedConnection(ConnectionFactory* connectionFactory, HostAddressPort proxy);
 
 			void handleConnectionConnectFinished(bool error);
-			void handleDataRead(const SafeByteArray& data);
+			void handleDataRead(boost::shared_ptr<SafeByteArray> data);
 			void handleDisconnected(const boost::optional<Error>& error);
 
 		private:
diff --git a/Swiften/Network/SOCKS5ProxiedConnection.cpp b/Swiften/Network/SOCKS5ProxiedConnection.cpp
index f8084ab..163e23a 100644
--- a/Swiften/Network/SOCKS5ProxiedConnection.cpp
+++ b/Swiften/Network/SOCKS5ProxiedConnection.cpp
@@ -86,15 +86,15 @@ void SOCKS5ProxiedConnection::handleConnectionConnectFinished(bool error) {
 	}
 }
 
-void SOCKS5ProxiedConnection::handleDataRead(const SafeByteArray& data) {
+void SOCKS5ProxiedConnection::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
 	SafeByteArray socksConnect;
 	boost::asio::ip::address rawAddress = server_.getAddress().getRawAddress();
 	assert(rawAddress.is_v4() || rawAddress.is_v6());
 	if (!connected_) {
 		if (proxyState_ == ProxyAuthenticating) {
 			SWIFT_LOG(debug) << "ProxyAuthenticating response received, reply with the connect BYTEs" << std::endl;
-			unsigned char choosenMethod = static_cast<unsigned char> (data[1]);
-			if (data[0] == 0x05 && choosenMethod != 0xFF) {
+			unsigned char choosenMethod = static_cast<unsigned char> ((*data)[1]);
+			if ((*data)[0] == 0x05 && choosenMethod != 0xFF) {
 				switch(choosenMethod) { // use the correct Method
 					case 0x00:
 						try {
@@ -134,7 +134,7 @@ void SOCKS5ProxiedConnection::handleDataRead(const SafeByteArray& data) {
 		}
 		else if (proxyState_ == ProxyConnecting) {
 			SWIFT_LOG(debug) << "Connect response received, check if successfully." << std::endl;
-			SWIFT_LOG(debug) << "Errorbyte: 0x" << std::hex << static_cast<int> (data[1]) << std::dec << std::endl;
+			SWIFT_LOG(debug) << "Errorbyte: 0x" << std::hex << static_cast<int> ((*data)[1]) << std::dec << std::endl;
 			/*
 
 			data.at(1) can be one of the following:
@@ -149,14 +149,14 @@ void SOCKS5ProxiedConnection::handleDataRead(const SafeByteArray& data) {
 			0x08 	Address type not supported (ATYP)
 			0x09 bis 0xFF 	unassigned
 			*/
-			if (data[0] == 0x05 && data[1] == 0x0) {
+			if ((*data)[0] == 0x05 && (*data)[1] == 0x0) {
 				SWIFT_LOG(debug) << "Successfully connected the server via the proxy." << std::endl;
 				connected_ = true;
 				onConnectFinished(false);
 				return;
 			}
 			else {
-				std::cerr << "SOCKS Proxy returned an error: " << std::hex << data[1] << std::endl;
+				std::cerr << "SOCKS Proxy returned an error: " << std::hex << (*data)[1] << std::endl;
 			}
 			return;
 		}
diff --git a/Swiften/Network/SOCKS5ProxiedConnection.h b/Swiften/Network/SOCKS5ProxiedConnection.h
index 942b6ce..592ce7d 100644
--- a/Swiften/Network/SOCKS5ProxiedConnection.h
+++ b/Swiften/Network/SOCKS5ProxiedConnection.h
@@ -42,7 +42,7 @@ namespace Swift {
 			SOCKS5ProxiedConnection(ConnectionFactory* connectionFactory, const HostAddressPort& proxy);
 
 			void handleConnectionConnectFinished(bool error);
-			void handleDataRead(const SafeByteArray& data);
+			void handleDataRead(boost::shared_ptr<SafeByteArray> data);
 			void handleDisconnected(const boost::optional<Error>& error);
 
 		private:
diff --git a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp
index 48189ab..133773f 100644
--- a/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp
+++ b/Swiften/Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp
@@ -76,7 +76,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
 			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
 			eventLoop->processEvents();
 
-			connectionFactory->connections[0]->onDataRead(createSafeByteArray("HTTP/1.0 200 Connection established\r\n\r\n"));
+			connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n"));
 			eventLoop->processEvents();
 
 			CPPUNIT_ASSERT(connectFinished);
@@ -89,7 +89,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
 			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
 			eventLoop->processEvents();
 
-			connectionFactory->connections[0]->onDataRead(createSafeByteArray("FLOOP"));
+			connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("FLOOP"));
 			eventLoop->processEvents();
 
 			CPPUNIT_ASSERT(connectFinished);
@@ -102,7 +102,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
 			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
 			eventLoop->processEvents();
 
-			connectionFactory->connections[0]->onDataRead(createSafeByteArray("HTTP/1.0 401 Unauthorized\r\n\r\n"));
+			connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 401 Unauthorized\r\n\r\n"));
 			eventLoop->processEvents();
 
 			CPPUNIT_ASSERT(connectFinished);
@@ -114,10 +114,10 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
 			HTTPConnectProxiedConnection::ref testling(createTestling());
 			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
 			eventLoop->processEvents();
-			connectionFactory->connections[0]->onDataRead(createSafeByteArray("HTTP/1.0 200 Connection established\r\n\r\n"));
+			connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n"));
 			eventLoop->processEvents();
 
-			connectionFactory->connections[0]->onDataRead(createSafeByteArray("abcdef"));
+			connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("abcdef"));
 
 			CPPUNIT_ASSERT_EQUAL(createByteArray("abcdef"), dataRead);
 		}
@@ -126,7 +126,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
 			HTTPConnectProxiedConnection::ref testling(createTestling());
 			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
 			eventLoop->processEvents();
-			connectionFactory->connections[0]->onDataRead(createSafeByteArray("HTTP/1.0 200 Connection established\r\n\r\n"));
+			connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n"));
 			eventLoop->processEvents();
 			connectionFactory->connections[0]->dataWritten.clear();
 
@@ -151,7 +151,7 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
 			HTTPConnectProxiedConnection::ref testling(createTestling());
 			testling->connect(HostAddressPort(HostAddress("2.2.2.2"), 2345));
 			eventLoop->processEvents();
-			connectionFactory->connections[0]->onDataRead(createSafeByteArray("HTTP/1.0 200 Connection established\r\n\r\n"));
+			connectionFactory->connections[0]->onDataRead(createSafeByteArrayRef("HTTP/1.0 200 Connection established\r\n\r\n"));
 			eventLoop->processEvents();
 
 			testling->disconnect();
@@ -180,8 +180,8 @@ class HTTPConnectProxiedConnectionTest : public CppUnit::TestFixture {
 			disconnectedError = e;
 		}
 
-		void handleDataRead(const SafeByteArray& d) {
-			append(dataRead, d);
+		void handleDataRead(boost::shared_ptr<SafeByteArray> d) {
+			append(dataRead, *d);
 		}
 
 		struct MockConnection : public Connection {
diff --git a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
index 31d5d82..335f2d2 100644
--- a/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
+++ b/Swiften/QA/NetworkTest/BoostConnectionTest.cpp
@@ -131,8 +131,8 @@ class BoostConnectionTest : public CppUnit::TestFixture {
 			connection->write(createSafeByteArray("\r\n\r\n")); // Temporarily, while we don't have an xmpp server running on ipv6
 		}
 
-		void handleDataRead(const SafeByteArray& data) {
-			append(receivedData, data);
+		void handleDataRead(boost::shared_ptr<SafeByteArray> data) {
+			append(receivedData, *data);
 		}
 
 		void handleDisconnected() {
diff --git a/Swiften/StreamStack/ConnectionLayer.cpp b/Swiften/StreamStack/ConnectionLayer.cpp
index 00b4289..5ea06eb 100644
--- a/Swiften/StreamStack/ConnectionLayer.cpp
+++ b/Swiften/StreamStack/ConnectionLayer.cpp
@@ -10,12 +10,16 @@
 namespace Swift {
 
 ConnectionLayer::ConnectionLayer(boost::shared_ptr<Connection> connection) : connection(connection) {
-	connection->onDataRead.connect(boost::bind(&ConnectionLayer::writeDataToParentLayer, this, _1));
+	connection->onDataRead.connect(boost::bind(&ConnectionLayer::handleDataRead, this, _1));
 }
 
 ConnectionLayer::~ConnectionLayer() {
 	connection->onDataRead.disconnect(boost::bind(&ConnectionLayer::writeDataToParentLayer, this, _1));
 }
 
+void ConnectionLayer::handleDataRead(boost::shared_ptr<SafeByteArray> data) {
+	writeDataToParentLayer(*data);
+}
+
 
 }
diff --git a/Swiften/StreamStack/ConnectionLayer.h b/Swiften/StreamStack/ConnectionLayer.h
index 8ccd33c..6776751 100644
--- a/Swiften/StreamStack/ConnectionLayer.h
+++ b/Swiften/StreamStack/ConnectionLayer.h
@@ -22,6 +22,9 @@ namespace Swift {
 			}
 
 		private:
+			void handleDataRead(boost::shared_ptr<SafeByteArray>);
+
+		private:
 			boost::shared_ptr<Connection> connection;
 	};
 }
-- 
cgit v0.10.2-6-g49f6