summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2010-03-28 15:46:49 (GMT)
committerRemko Tronçon <git@el-tramo.be>2010-03-28 15:46:49 (GMT)
commitf53a1ef582494458301b97bf6e546be52d7ff7e8 (patch)
tree7571b5cbcbd8a8f1dd1c966c9045b6cb69f0e295 /Swiften/Network/BoostConnection.cpp
parent638345680d72ca6acaf123f2c8c1c391f696e371 (diff)
downloadswift-f53a1ef582494458301b97bf6e546be52d7ff7e8.zip
swift-f53a1ef582494458301b97bf6e546be52d7ff7e8.tar.bz2
Moving submodule contents back.
Diffstat (limited to 'Swiften/Network/BoostConnection.cpp')
-rw-r--r--Swiften/Network/BoostConnection.cpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/Swiften/Network/BoostConnection.cpp b/Swiften/Network/BoostConnection.cpp
new file mode 100644
index 0000000..0d62300
--- /dev/null
+++ b/Swiften/Network/BoostConnection.cpp
@@ -0,0 +1,109 @@
+#include "Swiften/Network/BoostConnection.h"
+
+#include <iostream>
+#include <boost/bind.hpp>
+#include <boost/thread.hpp>
+
+#include "Swiften/EventLoop/MainEventLoop.h"
+#include "Swiften/Base/String.h"
+#include "Swiften/Base/ByteArray.h"
+#include "Swiften/Network/HostAddressPort.h"
+
+namespace Swift {
+
+static const size_t BUFFER_SIZE = 4096;
+
+// -----------------------------------------------------------------------------
+
+// A reference-counted non-modifiable buffer class.
+class SharedBuffer {
+ public:
+ SharedBuffer(const ByteArray& data) :
+ data_(new std::vector<char>(data.begin(), data.end())),
+ buffer_(boost::asio::buffer(*data_)) {
+ }
+
+ // ConstBufferSequence requirements.
+ typedef boost::asio::const_buffer value_type;
+ typedef const boost::asio::const_buffer* const_iterator;
+ const boost::asio::const_buffer* begin() const { return &buffer_; }
+ const boost::asio::const_buffer* end() const { return &buffer_ + 1; }
+
+ private:
+ boost::shared_ptr< std::vector<char> > data_;
+ boost::asio::const_buffer buffer_;
+};
+
+// -----------------------------------------------------------------------------
+
+BoostConnection::BoostConnection(boost::asio::io_service* ioService) :
+ socket_(*ioService), readBuffer_(BUFFER_SIZE) {
+}
+
+BoostConnection::~BoostConnection() {
+}
+
+void BoostConnection::listen() {
+ doRead();
+}
+
+void BoostConnection::connect(const HostAddressPort& addressPort) {
+ boost::asio::ip::tcp::endpoint endpoint(
+ boost::asio::ip::address::from_string(addressPort.getAddress().toString()), addressPort.getPort());
+ socket_.async_connect(
+ endpoint,
+ boost::bind(&BoostConnection::handleConnectFinished, shared_from_this(), boost::asio::placeholders::error));
+}
+
+void BoostConnection::disconnect() {
+ //MainEventLoop::removeEventsFromOwner(shared_from_this());
+ socket_.close();
+}
+
+void BoostConnection::write(const ByteArray& data) {
+ boost::asio::async_write(socket_, SharedBuffer(data),
+ boost::bind(&BoostConnection::handleDataWritten, shared_from_this(), boost::asio::placeholders::error));
+}
+
+void BoostConnection::handleConnectFinished(const boost::system::error_code& error) {
+ if (!error) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onConnectFinished), false), shared_from_this());
+ doRead();
+ }
+ else if (error != boost::asio::error::operation_aborted) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onConnectFinished), true), shared_from_this());
+ }
+}
+
+void BoostConnection::doRead() {
+ socket_.async_read_some(
+ 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) {
+ if (!error) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onDataRead), ByteArray(&readBuffer_[0], bytesTransferred)), shared_from_this());
+ doRead();
+ }
+ else if (error == boost::asio::error::eof) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onDisconnected), boost::optional<Error>()), shared_from_this());
+ }
+ else if (error != boost::asio::error::operation_aborted) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onDisconnected), ReadError), shared_from_this());
+ }
+}
+
+void BoostConnection::handleDataWritten(const boost::system::error_code& error) {
+ if (!error) {
+ return;
+ }
+ if (error == boost::asio::error::eof) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onDisconnected), boost::optional<Error>()), shared_from_this());
+ }
+ else if (error && error != boost::asio::error::operation_aborted) {
+ MainEventLoop::postEvent(boost::bind(boost::ref(onDisconnected), WriteError), shared_from_this());
+ }
+}
+
+}