diff options
Diffstat (limited to 'Swiften/FileTransfer/IBBSendSession.cpp')
-rw-r--r-- | Swiften/FileTransfer/IBBSendSession.cpp | 56 |
1 files changed, 38 insertions, 18 deletions
diff --git a/Swiften/FileTransfer/IBBSendSession.cpp b/Swiften/FileTransfer/IBBSendSession.cpp index 0fb47d3..c24cc0a 100644 --- a/Swiften/FileTransfer/IBBSendSession.cpp +++ b/Swiften/FileTransfer/IBBSendSession.cpp @@ -4,24 +4,27 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/IBBSendSession.h" +#include <Swiften/FileTransfer/IBBSendSession.h> #include <boost/bind.hpp> -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/FileTransfer/IBBRequest.h" -#include "Swiften/FileTransfer/BytestreamException.h" +#include <Swiften/Base/ByteArray.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/FileTransfer/IBBRequest.h> +#include <Swiften/FileTransfer/BytestreamException.h> namespace Swift { -IBBSendSession::IBBSendSession(const std::string& id, const JID& to, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* router) : id(id), to(to), bytestream(bytestream), router(router), blockSize(4096), sequenceNumber(0), active(false) { +IBBSendSession::IBBSendSession(const std::string& id, const JID& from, const JID& to, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* router) : id(id), from(from), to(to), bytestream(bytestream), router(router), blockSize(4096), sequenceNumber(0), active(false), waitingForData(false) { + bytestream->onDataAvailable.connect(boost::bind(&IBBSendSession::handleDataAvailable, this)); } IBBSendSession::~IBBSendSession() { + bytestream->onDataAvailable.disconnect(boost::bind(&IBBSendSession::handleDataAvailable, this)); } void IBBSendSession::start() { - IBBRequest::ref request = IBBRequest::create(to, IBB::createIBBOpen(id, blockSize), router); + IBBRequest::ref request = IBBRequest::create(from, to, IBB::createIBBOpen(id, blockSize), router); request->onResponse.connect(boost::bind(&IBBSendSession::handleIBBResponse, this, _1, _2)); active = true; request->send(); @@ -29,24 +32,15 @@ void IBBSendSession::start() { void IBBSendSession::stop() { if (active && router->isAvailable()) { - IBBRequest::create(to, IBB::createIBBClose(id), router)->send(); + IBBRequest::create(from, to, IBB::createIBBClose(id), router)->send(); } finish(boost::optional<FileTransferError>()); } void IBBSendSession::handleIBBResponse(IBB::ref, ErrorPayload::ref error) { - if (!error) { + if (!error && active) { if (!bytestream->isFinished()) { - try { - ByteArray data = bytestream->read(blockSize); - IBBRequest::ref request = IBBRequest::create(to, IBB::createIBBData(id, sequenceNumber, data), router); - sequenceNumber++; - request->onResponse.connect(boost::bind(&IBBSendSession::handleIBBResponse, this, _1, _2)); - request->send(); - } - catch (const BytestreamException& e) { - finish(FileTransferError(FileTransferError::ReadError)); - } + sendMoreData(); } else { finish(boost::optional<FileTransferError>()); @@ -57,9 +51,35 @@ void IBBSendSession::handleIBBResponse(IBB::ref, ErrorPayload::ref error) { } } +void IBBSendSession::sendMoreData() { + try { + boost::shared_ptr<ByteArray> data = bytestream->read(blockSize); + if (!data->empty()) { + waitingForData = false; + IBBRequest::ref request = IBBRequest::create(from, to, IBB::createIBBData(id, sequenceNumber, *data), router); + sequenceNumber++; + request->onResponse.connect(boost::bind(&IBBSendSession::handleIBBResponse, this, _1, _2)); + request->send(); + onBytesSent(data->size()); + } + else { + waitingForData = true; + } + } + catch (const BytestreamException&) { + finish(FileTransferError(FileTransferError::ReadError)); + } +} + void IBBSendSession::finish(boost::optional<FileTransferError> error) { active = false; onFinished(error); } +void IBBSendSession::handleDataAvailable() { + if (waitingForData) { + sendMoreData(); + } +} + } |