summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Alpert <aalpert@rim.com>2012-11-26 13:29:32 -0800
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-11-28 09:59:16 +0100
commite5783b79887299d094e6976630373a4899bd7074 (patch)
tree264a8555718ab47b3553d73ead39295517c451fa
parent70579cf5f1b82460443b764aef1f2d2b23732acd (diff)
QML file loading: honor synchronous requests made through QNAM
So that it can skip loading state when the underlying QNetworkReply is already finished. Change-Id: Ic2d26271868b64bf8a411b4b54d7e5be7ee5d2b5 Parts-of-the-patch-by: Jeremy Nicholl Task-number: QTBUG-27723 Reviewed-by: Alan Alpert <aalpert@rim.com>
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp34
-rw-r--r--src/declarative/qml/qdeclarativetypeloader_p.h2
-rw-r--r--tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp50
3 files changed, 78 insertions, 8 deletions
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
index ed7914a8..012afb39 100644
--- a/src/declarative/qml/qdeclarativetypeloader.cpp
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -552,21 +552,28 @@ void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob)
blob->m_manager = this;
QNetworkReply *reply = m_engine->networkAccessManager()->get(QNetworkRequest(blob->m_url));
- QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(networkReplyProgress(qint64,qint64)));
- QObject::connect(reply, SIGNAL(finished()),
- this, SLOT(networkReplyFinished()));
- m_networkReplies.insert(reply, blob);
+ m_networkReplies.insert(reply, blob);
blob->addref();
+
+ if (reply->isFinished()) {
+ // Short-circuit synchronous replies.
+ qint64 size = reply->size();
+ networkReplyProgress(reply, size, size);
+ networkReplyFinished(reply);
+ } else {
+ QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
+ this, SLOT(networkReplyProgress(qint64,qint64)));
+ QObject::connect(reply, SIGNAL(finished()),
+ this, SLOT(networkReplyFinished()));
+ }
}
}
#define DATALOADER_MAXIMUM_REDIRECT_RECURSION 16
-void QDeclarativeDataLoader::networkReplyFinished()
+void QDeclarativeDataLoader::networkReplyFinished(QNetworkReply *reply)
{
- QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
reply->deleteLater();
QDeclarativeDataBlob *blob = m_networkReplies.take(reply);
@@ -598,9 +605,14 @@ void QDeclarativeDataLoader::networkReplyFinished()
blob->release();
}
-void QDeclarativeDataLoader::networkReplyProgress(qint64 bytesReceived, qint64 bytesTotal)
+void QDeclarativeDataLoader::networkReplyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ networkReplyFinished(reply);
+}
+
+void QDeclarativeDataLoader::networkReplyProgress(QNetworkReply *reply, qint64 bytesReceived, qint64 bytesTotal)
+{
QDeclarativeDataBlob *blob = m_networkReplies.value(reply);
Q_ASSERT(blob);
@@ -611,6 +623,12 @@ void QDeclarativeDataLoader::networkReplyProgress(qint64 bytesReceived, qint64 b
}
}
+void QDeclarativeDataLoader::networkReplyProgress(qint64 bytesReceived, qint64 bytesTotal)
+{
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ networkReplyProgress(reply, bytesReceived, bytesTotal);
+}
+
/*!
Load the provided \a blob with \a data. The blob's URL is not used by the data loader in this case.
*/
diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h
index 03e79ad0..12b65edc 100644
--- a/src/declarative/qml/qdeclarativetypeloader_p.h
+++ b/src/declarative/qml/qdeclarativetypeloader_p.h
@@ -172,6 +172,8 @@ private slots:
private:
void setData(QDeclarativeDataBlob *, const QByteArray &);
+ void networkReplyFinished(QNetworkReply *);
+ void networkReplyProgress(QNetworkReply *, qint64, qint64);
QDeclarativeEngine *m_engine;
typedef QHash<QNetworkReply *, QDeclarativeDataBlob *> NetworkReplies;
diff --git a/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp b/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp
index 803f42b1..70dc3c0b 100644
--- a/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp
+++ b/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp
@@ -43,6 +43,7 @@
#include <QDeclarativeEngine>
#include <QDeclarativeContext>
#include <QNetworkAccessManager>
+#include <QNetworkReply>
#include <QPointer>
#include <QDir>
#include <QStandardPaths>
@@ -65,6 +66,7 @@ private slots:
void clearComponentCache();
void outputWarningsToStandardError();
void objectOwnership();
+ void synchronousNetworkReply();
};
void tst_qdeclarativeengine::rootContext()
@@ -323,6 +325,54 @@ void tst_qdeclarativeengine::objectOwnership()
}
+class MyReply : public QNetworkReply {
+
+ Q_OBJECT
+
+public:
+ MyReply() {
+ setFinished(true);
+ }
+ virtual qint64 readData(char* buffer, qint64 number) {
+ return 0;
+ }
+ virtual void abort() { }
+};
+
+class MyManager : public QNetworkAccessManager {
+
+ Q_OBJECT
+
+public:
+ MyManager(QObject *parent = 0) : QNetworkAccessManager(parent) {
+ }
+
+ QNetworkReply *createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0) {
+ return new MyReply;
+ }
+};
+
+class MyFactory : public QDeclarativeNetworkAccessManagerFactory {
+
+public:
+ QNetworkAccessManager *create(QObject *parent) {
+ return new MyManager;
+ }
+};
+
+void tst_qdeclarativeengine::synchronousNetworkReply()
+{
+ MyFactory factory;
+ QDeclarativeEngine engine;
+ engine.setNetworkAccessManagerFactory(&factory);
+ QDeclarativeComponent c(&engine, QUrl("myScheme://test.qml"));
+ // we get an error, but we only care about whether we are finished or not in this test
+ QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
+ c.create();
+ // reply is finished, so should not be in loading state.
+ QVERIFY(!c.isLoading());
+}
+
QTEST_MAIN(tst_qdeclarativeengine)
#include "tst_qdeclarativeengine.moc"