summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/FileTransfer/IBBSendSession.cpp')
-rw-r--r--Swiften/FileTransfer/IBBSendSession.cpp56
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();
+ }
+}
+
}