Fixed file downloader.

This commit is contained in:
codestation
2015-02-15 23:13:41 -04:30
parent f39d441da3
commit dcd6964d6a
2 changed files with 27 additions and 56 deletions

View File

@@ -30,8 +30,8 @@ volatile qint64 HTTPDownloader::m_contentLength = -1;
QMutex HTTPDownloader::dataAvailable; QMutex HTTPDownloader::dataAvailable;
QMutex HTTPDownloader::dataRead; QMutex HTTPDownloader::dataRead;
char *HTTPDownloader::buffer = NULL; QByteArray HTTPDownloader::buffer;
qint64 HTTPDownloader::bufferSize = 0; bool HTTPDownloader::bufferReady = false;
qint64 HTTPDownloader::downloadLeft = 0; qint64 HTTPDownloader::downloadLeft = 0;
HTTPDownloader::HTTPDownloader(const QString &url, QObject *parent) : HTTPDownloader::HTTPDownloader(const QString &url, QObject *parent) :
@@ -44,7 +44,6 @@ HTTPDownloader::~HTTPDownloader()
{ {
lengthMutex.unlock(); lengthMutex.unlock();
dataAvailable.unlock(); dataAvailable.unlock();
free(buffer);
} }
void HTTPDownloader::downloadFile() void HTTPDownloader::downloadFile()
@@ -66,7 +65,9 @@ void HTTPDownloader::metadataChanged()
QVariant len = reply->header(QNetworkRequest::ContentLengthHeader); QVariant len = reply->header(QNetworkRequest::ContentLengthHeader);
if(len.isValid()) { if(len.isValid()) {
m_contentLength = len.toInt(); m_contentLength = len.toInt();
downloadLeft = m_contentLength + 8; buffer.resize(8);
*(uint64_t *)buffer.data() = m_contentLength;
downloadLeft = m_contentLength;
} else { } else {
m_contentLength = -1; m_contentLength = -1;
} }
@@ -81,71 +82,40 @@ qint64 HTTPDownloader::getFileSize()
void HTTPDownloader::readyRead() void HTTPDownloader::readyRead()
{ {
dataRead.lock(); QMutexLocker locker(&dataRead);
int currOffset = bufferSize; downloadLeft -= reply->bytesAvailable();
if(bufferSize == 0) { buffer.append(reply->readAll());
bufferSize = reply->bytesAvailable();
if(firstRead) { if(buffer.size() >= 16 * 1024 || downloadLeft == 0) {
bufferSize += 8;
currOffset += 8;
// start with a 16KiB buffer
buffer = (char *)malloc(16384);
*(uint64_t *)buffer = m_contentLength;
firstRead = false;
}
} else {
bufferSize += reply->bytesAvailable();
if(bufferSize > 16384) {
buffer = (char *)realloc(buffer, bufferSize);
}
}
reply->read(buffer + currOffset, reply->bytesAvailable());
downloadLeft -= bufferSize;
if(bufferSize >= 16384 || downloadLeft == 0) {
dataAvailable.unlock(); dataAvailable.unlock();
} }
dataRead.unlock();
if(downloadLeft == 0)
qDebug() << "remote download complete";
} }
int HTTPDownloader::readCallback(unsigned char *data, unsigned long wantlen, unsigned long *gotlen) int HTTPDownloader::readCallback(unsigned char *data, unsigned long wantlen, unsigned long *gotlen)
{ {
if(!dataAvailable.tryLock(30000)) { if(downloadLeft && !dataAvailable.tryLock(30000)) {
qWarning("Connection timeout while receiving data from network, aborting"); qWarning("Connection timeout while receiving data from network, aborting");
return -1; return -1;
} }
dataRead.lock(); QMutexLocker locker(&dataRead);
if(bufferSize == 0) { if(buffer.size() == 0)
dataRead.unlock();
return -1; return -1;
}
if(bufferSize < wantlen) { int read_size = wantlen > (unsigned long)buffer.size() ? buffer.size() : wantlen;
wantlen = bufferSize;
}
memcpy(data, buffer, wantlen); memcpy(data, buffer.data(), read_size);
bufferSize -= wantlen; buffer.remove(0, read_size);
*gotlen = wantlen;
if(bufferSize > 0) { qDebug() << "sending data: " << read_size << ", left in buffer: " << buffer.size();
memmove(buffer, buffer + wantlen, bufferSize);
if(bufferSize >= 16384 || downloadLeft == 0) {
dataAvailable.unlock();
}
}
*gotlen = wantlen; *gotlen = read_size;
dataRead.unlock();
return PTP_RC_OK; return PTP_RC_OK;
} }
@@ -158,9 +128,9 @@ void HTTPDownloader::error(QNetworkReply::NetworkError errorCode)
qWarning() << "Network error:" << error; qWarning() << "Network error:" << error;
emit messageSent(tr("Network error: %1").arg(error)); emit messageSent(tr("Network error: %1").arg(error));
// set buffer to zero so a read callback can be aborted
dataRead.lock();
bufferSize = 0;
dataRead.unlock();
lengthMutex.unlock(); lengthMutex.unlock();
// clear the buffer so a read callback can be aborted
QMutexLocker locker(&dataRead);
buffer.clear();
} }

View File

@@ -20,6 +20,7 @@
#ifndef HTTPDOWNLOADER_H #ifndef HTTPDOWNLOADER_H
#define HTTPDOWNLOADER_H #define HTTPDOWNLOADER_H
#include <QByteArray>
#include <QMutex> #include <QMutex>
#include <QNetworkReply> #include <QNetworkReply>
#include <QObject> #include <QObject>
@@ -57,8 +58,8 @@ private:
static QNetworkReply *reply; static QNetworkReply *reply;
volatile static qint64 m_contentLength; volatile static qint64 m_contentLength;
static char *buffer; static QByteArray buffer;
static qint64 bufferSize; static bool bufferReady;
static qint64 downloadLeft; static qint64 downloadLeft;
}; };