diff options
author | Markus Goetz <Markus.Goetz@nokia.com> | 2010-09-28 16:32:16 (GMT) |
---|---|---|
committer | Markus Goetz <Markus.Goetz@nokia.com> | 2010-09-29 09:58:34 (GMT) |
commit | cf4f2847c1a1df101e2983a0e1e8682ace323c0d (patch) | |
tree | 6a054961d4e3ca66cbad075b25309ab4468c5d63 /src/network | |
parent | d49a7e382c69076de179103c9072e49a72db264d (diff) | |
download | Qt-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/network')
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel.cpp | 3 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl.cpp | 41 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyimpl_p.h | 9 |
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) }; |