summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qringbuffer_p.h47
-rw-r--r--src/network/access/qhttpnetworkreply.cpp8
-rw-r--r--src/network/access/qhttpnetworkreply_p.h1
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp16
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp3
5 files changed, 62 insertions, 13 deletions
diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h
index b8e08ac..f3daca7 100644
--- a/src/corelib/tools/qringbuffer_p.h
+++ b/src/corelib/tools/qringbuffer_p.h
@@ -301,6 +301,51 @@ public:
return read(size());
}
+ // read an unspecified amount (will read the first buffer)
+ inline QByteArray read() {
+ // multiple buffers, just take the first one
+ if (head == 0 && tailBuffer != 0) {
+ QByteArray qba = buffers.takeFirst();
+ --tailBuffer;
+ bufferSize -= qba.length();
+ return qba;
+ }
+
+ // one buffer with good value for head. Just take it.
+ if (head == 0 && tailBuffer == 0) {
+ QByteArray qba = buffers.takeFirst();
+ qba.resize(tail);
+ buffers << QByteArray();
+ bufferSize = 0;
+ tail = 0;
+ return qba;
+ }
+
+ // Bad case: We have to memcpy.
+ // We can avoid by initializing the QRingBuffer with basicBlockSize of 0
+ // and only using this read() function.
+ QByteArray qba(readPointer(), nextDataBlockSize());
+ buffers.takeFirst();
+ head = 0;
+ if (tailBuffer == 0) {
+ buffers << QByteArray();
+ tail = 0;
+ } else {
+ --tailBuffer;
+ }
+ bufferSize -= qba.length();
+ return qba;
+ }
+
+ // append a new buffer to the end
+ inline void append(const QByteArray &qba) {
+ buffers[tailBuffer].resize(tail);
+ buffers << qba;
+ ++tailBuffer;
+ tail = qba.length();
+ bufferSize += qba.length();
+ }
+
inline QByteArray peek(int maxLength) const {
int bytesToRead = qMin(size(), maxLength);
if(maxLength <= 0)
@@ -355,7 +400,7 @@ public:
private:
QList<QByteArray> buffers;
int head, tail;
- int tailBuffer;
+ int tailBuffer; // always buffers.size() - 1
int basicBlockSize;
int bufferSize;
};
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 72aec99..483589b 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -185,6 +185,12 @@ QByteArray QHttpNetworkReply::read(qint64 maxSize)
return data;
}
+QByteArray QHttpNetworkReply::readAny()
+{
+ Q_D(QHttpNetworkReply);
+ return d->responseData.read();
+}
+
bool QHttpNetworkReply::isFinished() const
{
return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState;
@@ -196,7 +202,7 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
: QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100),
majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0),
currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false),
- autoDecompress(false), requestIsPrepared(false)
+ autoDecompress(false), responseData(0), requestIsPrepared(false)
{
}
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index 26e1047..b86cfaa 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -123,6 +123,7 @@ public:
qint64 bytesAvailable() const;
qint64 bytesAvailableNextBlock() const;
QByteArray read(qint64 maxSize = -1);
+ QByteArray readAny();
bool isFinished() const;
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index 71808d4..db84e58 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -649,16 +649,14 @@ void QNetworkAccessHttpBackend::readFromHttp()
if (!httpReply)
return;
- // We implement the download rate control
- // Don't read from QHttpNetworkAccess more than QNetworkAccessBackend wants
- // One of the two functions above will be called when we can read again
+ // We read possibly more than nextDownstreamBlockSize(), but
+ // this is not a critical thing since it is already in the
+ // memory anyway
- qint64 bytesToRead = qBound<qint64>(0, httpReply->bytesAvailable(), nextDownstreamBlockSize());
- if (!bytesToRead)
- return;
-
- QByteArray data = httpReply->read(bytesToRead);
- writeDownstreamData(data);
+ while (httpReply->bytesAvailable() != 0 && nextDownstreamBlockSize() != 0) {
+ const QByteArray data = httpReply->readAny();
+ writeDownstreamData(data);
+ }
}
void QNetworkAccessHttpBackend::replyFinished()
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 6eacdf1..de39970 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -393,8 +393,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(const QByteArray &data)
if (!q->isOpen())
return;
- char *ptr = readBuffer.reserve(data.size());
- memcpy(ptr, data.constData(), data.size());
+ readBuffer.append(data);
if (cacheEnabled && !cacheSaveDevice) {
// save the meta data