summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarkus Goetz <Markus.Goetz@nokia.com>2010-09-28 16:32:16 (GMT)
committerMarkus Goetz <Markus.Goetz@nokia.com>2010-09-29 09:58:34 (GMT)
commitcf4f2847c1a1df101e2983a0e1e8682ace323c0d (patch)
tree6a054961d4e3ca66cbad075b25309ab4468c5d63 /src
parentd49a7e382c69076de179103c9072e49a72db264d (diff)
downloadQt-cf4f2847c1a1df101e2983a0e1e8682ace323c0d.zip
Qt-cf4f2847c1a1df101e2983a0e1e8682ace323c0d.tar.gz
Qt-cf4f2847c1a1df101e2983a0e1e8682ace323c0d.tar.bz2
QNAM: More zerocopy changes
The zerocopy download buffer is now QSharedPointer<char> instead of the QSharedPointer to QVarLengthArray<char>. This will be a bit leaner to handle by QML and QtWebKit and does not tie us to a QVLA that much. Also fix some bugs related to signal emissions and the return value of bytesAvailable(). Now the behaviour should be the same if a zerocopy buffer is used or not. Reviewed-by: Peter Hartmann Reviewed-by: Thiago Macieira
Diffstat (limited to 'src')
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp3
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp41
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h9
3 files changed, 30 insertions, 23 deletions
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index e39f9ed..617602d 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -427,7 +427,8 @@ void QHttpNetworkConnectionChannel::_q_receiveReply()
replyPrivate->totalProgress += haveRead;
// the user will get notified of it via progress signal
- emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
+ if (haveRead > 0)
+ emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
} else if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress
&& replyPrivate->bodyLength > 0) {
// bulk files like images should fulfill these properties and
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 3a629cf..2dbd21c 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -49,16 +49,12 @@
#include "QtNetwork/qnetworksession.h"
#include "qnetworkaccesshttpbackend_p.h"
#include "qnetworkaccessmanager_p.h"
-#include <QVarLengthArray>
#include <QtCore/QCoreApplication>
QT_BEGIN_NAMESPACE
-typedef QSharedPointer<QVarLengthArray<char, 0> > QVarLengthArraySharedPointer;
-QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QVarLengthArraySharedPointer)
-QT_BEGIN_NAMESPACE
+Q_DECLARE_METATYPE(QSharedPointer<char>)
inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate()
: backend(0), outgoingData(0), outgoingDataBuffer(0),
@@ -69,7 +65,9 @@ inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate()
httpStatusCode(0),
state(Idle)
, downloadBuffer(0)
- , downloadBufferPosition(0)
+ , downloadBufferReadPosition(0)
+ , downloadBufferCurrentSize(0)
+ , downloadBufferMaximumSize(0)
{
}
@@ -603,6 +601,11 @@ void QNetworkReplyImplPrivate::appendDownstreamData(const QByteArray &data)
qFatal("QNetworkReplyImplPrivate::appendDownstreamData not implemented");
}
+static void downloadBufferDeleter(char *ptr)
+{
+ delete[] ptr;
+}
+
char* QNetworkReplyImplPrivate::getDownloadBuffer(qint64 size)
{
Q_Q(QNetworkReplyImpl);
@@ -611,12 +614,12 @@ char* QNetworkReplyImplPrivate::getDownloadBuffer(qint64 size)
if (!downloadBuffer) {
QVariant bufferAllocationPolicy = request.attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute);
if (bufferAllocationPolicy.isValid() && bufferAllocationPolicy.toLongLong() >= size) {
- downloadBufferArray = QSharedPointer<QVarLengthArray<char, 0> >(new QVarLengthArray<char, 0>());
- downloadBufferArray->reserve(size);
-
- downloadBuffer = downloadBufferArray->data();
+ downloadBufferCurrentSize = 0;
+ downloadBufferMaximumSize = size;
+ downloadBuffer = new char[downloadBufferMaximumSize]; // throws if allocation fails
+ downloadBufferPointer = QSharedPointer<char>(downloadBuffer, downloadBufferDeleter);
- q->setAttribute(QNetworkRequest::DownloadBufferAttribute, qVariantFromValue<QSharedPointer<QVarLengthArray<char, 0> > > (downloadBufferArray));
+ q->setAttribute(QNetworkRequest::DownloadBufferAttribute, qVariantFromValue<QSharedPointer<char> > (downloadBufferPointer));
}
}
@@ -644,12 +647,12 @@ void QNetworkReplyImplPrivate::appendDownstreamDataDownloadBuffer(qint64 bytesRe
bytesDownloaded = bytesReceived;
lastBytesDownloaded = bytesReceived;
- // Update the array so our user (e.g. QtWebKit) knows the real size
- if (bytesReceived > 0)
- downloadBufferArray->resize(bytesReceived);
+ downloadBufferCurrentSize = bytesReceived;
emit q->downloadProgress(bytesDownloaded, bytesTotal);
- emit q->readyRead();
+ // Only emit readyRead when actual data is there
+ if (bytesDownloaded > 0)
+ emit q->readyRead();
}
void QNetworkReplyImplPrivate::finished()
@@ -846,7 +849,7 @@ qint64 QNetworkReplyImpl::bytesAvailable() const
// Special case for the "zero copy" download buffer
Q_D(const QNetworkReplyImpl);
if (d->downloadBuffer) {
- qint64 maxAvail = d->downloadBufferArray->size() - d->downloadBufferPosition;
+ qint64 maxAvail = d->downloadBufferCurrentSize - d->downloadBufferReadPosition;
return QNetworkReply::bytesAvailable() + maxAvail;
}
@@ -907,12 +910,12 @@ qint64 QNetworkReplyImpl::readData(char *data, qint64 maxlen)
// Special case code if we have the "zero copy" download buffer
if (d->downloadBuffer) {
- qint64 maxAvail = qMin<qint64>(d->downloadBufferArray->size() - d->downloadBufferPosition, maxlen);
+ qint64 maxAvail = qMin<qint64>(d->downloadBufferCurrentSize - d->downloadBufferReadPosition, maxlen);
if (maxAvail == 0)
return d->state == QNetworkReplyImplPrivate::Finished ? -1 : 0;
// FIXME what about "Aborted" state?
- qMemCopy(data, d->downloadBuffer + d->downloadBufferPosition, maxAvail);
- d->downloadBufferPosition += maxAvail;
+ qMemCopy(data, d->downloadBuffer + d->downloadBufferReadPosition, maxAvail);
+ d->downloadBufferReadPosition += maxAvail;
return maxAvail;
}
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index 2cb3082..e944601 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -62,7 +62,7 @@
#include "QtCore/qbuffer.h"
#include "private/qringbuffer_p.h"
#include "private/qbytedata_p.h"
-#include <QVarLengthArray>
+#include <QSharedPointer>
QT_BEGIN_NAMESPACE
@@ -206,9 +206,12 @@ public:
State state;
// only used when the "zero copy" style is used. Else readBuffer is used.
- QSharedPointer< QVarLengthArray<char, 0> > downloadBufferArray;
+ // Please note that the whole "zero copy" download buffer API is private right now. Do not use it.
+ qint64 downloadBufferReadPosition;
+ qint64 downloadBufferCurrentSize;
+ qint64 downloadBufferMaximumSize;
+ QSharedPointer<char> downloadBufferPointer;
char* downloadBuffer;
- qint64 downloadBufferPosition;
Q_DECLARE_PUBLIC(QNetworkReplyImpl)
};