From 2f6459ff25a59e913b5695dcd8919ead8d58947c Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 18 Jan 2010 14:56:22 +0100 Subject: don't assert when calling QtScript-wrapped method of deleted QObject Make it behave the same as the old (4.5) back-end. Reviewed-by: Jedrzej Nowacki --- src/script/bridge/qscriptqobject.cpp | 3 ++- tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index fb0dddb..3f4f6bb 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -978,7 +978,8 @@ JSC::JSValue QtFunction::execute(JSC::ExecState *exec, JSC::JSValue thisValue, QScriptObjectDelegate *delegate = scriptObject->delegate(); Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); QObject *qobj = static_cast(delegate)->value(); - Q_ASSERT_X(qobj != 0, "QtFunction::call", "handle the case when QObject has been deleted"); + if (!qobj) + return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("cannot call function of deleted QObject")); QScriptEnginePrivate *engine = scriptEngineFromExec(exec); const QMetaObject *meta = qobj->metaObject(); diff --git a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp index 3415163..de9d37e 100644 --- a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp +++ b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp @@ -2913,7 +2913,8 @@ void tst_QScriptExtQObject::objectDeleted() v.setProperty("intProperty", QScriptValue(&eng, 123)); QCOMPARE(qobj->intProperty(), 123); qobj->resetQtFunctionInvoked(); - v.property("myInvokable").call(v); + QScriptValue invokable = v.property("myInvokable"); + invokable.call(v); QCOMPARE(qobj->qtFunctionInvoked(), 0); // now delete the object @@ -2951,6 +2952,14 @@ void tst_QScriptExtQObject::objectDeleted() QCOMPARE(ret.toString(), QLatin1String("Error: cannot access member `myInvokableWithIntArg' of deleted QObject")); } + // Meta-method wrappers are still valid, but throw error when called + QVERIFY(invokable.isFunction()); + { + QScriptValue ret = invokable.call(v); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("Error: cannot call function of deleted QObject")); + } + // access from script eng.globalObject().setProperty("o", v); { -- cgit v0.12 From c7b3f408f772d565666910cb4495a7057796b648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 13 Jan 2010 18:03:52 +0100 Subject: QFile: Fix a pre-mature pessimization Don't repeatedly call the fileEngine virtual function. Instead re-use the private data member if we know it has been filled. Reviewed-by: Markus Goetz --- src/corelib/io/qfile.cpp | 86 +++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 4c7f3f0..7405339 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -650,7 +650,7 @@ QFile::remove() unsetError(); return true; } - d->setError(QFile::RemoveError, fileEngine()->errorString()); + d->setError(QFile::RemoveError, d->fileEngine->errorString()); } return false; } @@ -704,7 +704,7 @@ QFile::rename(const QString &newName) if (fileEngine()->rename(newName)) { unsetError(); // engine was able to handle the new name so we just reset it - fileEngine()->setFileName(newName); + d->fileEngine->setFileName(newName); d->fileName = newName; return true; } @@ -740,7 +740,7 @@ QFile::rename(const QString &newName) if (error) { out.remove(); } else { - fileEngine()->setFileName(newName); + d->fileEngine->setFileName(newName); setPermissions(permissions()); unsetError(); setFileName(newName); @@ -805,7 +805,7 @@ QFile::link(const QString &linkName) unsetError(); return true; } - d->setError(QFile::RenameError, fileEngine()->errorString()); + d->setError(QFile::RenameError, d->fileEngine->errorString()); return false; } @@ -994,10 +994,10 @@ bool QFile::open(OpenMode mode) seek(size()); return true; } - QFile::FileError err = fileEngine()->error(); + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::OpenError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); return false; } @@ -1155,8 +1155,8 @@ QFile::handle() const if (!isOpen()) return -1; - if (QAbstractFileEngine *engine = fileEngine()) - return engine->handle(); + if (fileEngine()) + return d->fileEngine->handle(); return -1; } @@ -1189,13 +1189,12 @@ QFile::handle() const uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags) { Q_D(QFile); - QAbstractFileEngine *engine = fileEngine(); - if (engine - && engine->supportsExtension(QAbstractFileEngine::MapExtension)) { + if (fileEngine() + && d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) { unsetError(); - uchar *address = engine->map(offset, size, flags); + uchar *address = d->fileEngine->map(offset, size, flags); if (address == 0) - d->setError(engine->error(), engine->errorString()); + d->setError(d->fileEngine->error(), d->fileEngine->errorString()); return address; } return 0; @@ -1212,13 +1211,12 @@ uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags) bool QFile::unmap(uchar *address) { Q_D(QFile); - QAbstractFileEngine *engine = fileEngine(); - if (engine - && engine->supportsExtension(QAbstractFileEngine::UnMapExtension)) { + if (fileEngine() + && d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) { unsetError(); - bool success = engine->unmap(address); + bool success = d->fileEngine->unmap(address); if (!success) - d->setError(engine->error(), engine->errorString()); + d->setError(d->fileEngine->error(), d->fileEngine->errorString()); return success; } return false; @@ -1251,13 +1249,14 @@ QFile::resize(qint64 sz) Q_D(QFile); if (!d->ensureFlushed()) return false; - if (isOpen() && fileEngine()->pos() > sz) + fileEngine(); + if (isOpen() && d->fileEngine->pos() > sz) seek(sz); - if(fileEngine()->setSize(sz)) { + if(d->fileEngine->setSize(sz)) { unsetError(); return true; } - d->setError(QFile::ResizeError, fileEngine()->errorString()); + d->setError(QFile::ResizeError, d->fileEngine->errorString()); return false; } @@ -1321,7 +1320,7 @@ QFile::setPermissions(Permissions permissions) unsetError(); return true; } - d->setError(QFile::PermissionsError, fileEngine()->errorString()); + d->setError(QFile::PermissionsError, d->fileEngine->errorString()); return false; } @@ -1354,23 +1353,23 @@ bool QFile::flush() { Q_D(QFile); + fileEngine(); if (!d->writeBuffer.isEmpty()) { qint64 size = d->writeBuffer.size(); - if (_qfile_writeData(d->fileEngine ? d->fileEngine : fileEngine(), - &d->writeBuffer) != size) { - QFile::FileError err = fileEngine()->error(); + if (_qfile_writeData(d->fileEngine, &d->writeBuffer) != size) { + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::WriteError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); return false; } } - if (!fileEngine()->flush()) { - QFile::FileError err = fileEngine()->error(); + if (!d->fileEngine->flush()) { + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::WriteError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); return false; } return true; @@ -1398,7 +1397,7 @@ QFile::close() if (fileEngine()->close() && flushed) unsetError(); else if (flushed) - d->setError(fileEngine()->error(), fileEngine()->errorString()); + d->setError(d->fileEngine->error(), d->fileEngine->errorString()); } /*! @@ -1451,10 +1450,10 @@ bool QFile::atEnd() const return false; // If the file engine knows best, say what it says. - if (fileEngine()->supportsExtension(QAbstractFileEngine::AtEndExtension)) { + if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) { // Check if the file engine supports AtEndExtension, and if it does, // check if the file engine claims to be at the end. - return fileEngine()->atEnd(); + return d->fileEngine->atEnd(); } // Fall back to checking how much is available (will stat files). @@ -1476,11 +1475,11 @@ bool QFile::seek(qint64 off) if (!d->ensureFlushed()) return false; - if (!fileEngine()->seek(off) || !QIODevice::seek(off)) { - QFile::FileError err = fileEngine()->error(); + if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) { + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::PositionError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); return false; } unsetError(); @@ -1496,8 +1495,8 @@ qint64 QFile::readLineData(char *data, qint64 maxlen) if (!d->ensureFlushed()) return -1; - if (fileEngine()->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) - return fileEngine()->readLine(data, maxlen); + if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) + return d->fileEngine->readLine(data, maxlen); // Fall back to QIODevice's readLine implementation if the engine // cannot do it faster. @@ -1516,15 +1515,15 @@ qint64 QFile::readData(char *data, qint64 len) return -1; qint64 ret = -1; - qint64 read = fileEngine()->read(data, len); + qint64 read = d->fileEngine->read(data, len); if (read != -1) ret = read; if(ret < 0) { - QFile::FileError err = fileEngine()->error(); + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::ReadError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); } return ret; } @@ -1606,13 +1605,12 @@ QFile::writeData(const char *data, qint64 len) // Write directly to the engine if the block size is larger than // the write buffer size. if (!buffered || len > QFILE_WRITEBUFFER_SIZE) { - QAbstractFileEngine *fe = d->fileEngine ? d->fileEngine : fileEngine(); - qint64 ret = fe->write(data, len); + qint64 ret = d->fileEngine->write(data, len); if(ret < 0) { - QFile::FileError err = fileEngine()->error(); + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::WriteError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); } return ret; } -- cgit v0.12 From 54069f7c2c235dc9e302f96a6111bf6cd34a766b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 13 Jan 2010 18:09:18 +0100 Subject: If the file is open, there must be an engine. Don't try to allocate one for QFile::handle and QFile::flush since they'll be useless there. Reviewed-by: Markus Goetz --- src/corelib/io/qfile.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 7405339..df470b9 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -1152,12 +1152,11 @@ bool QFile::open(int fd, OpenMode mode) int QFile::handle() const { - if (!isOpen()) + Q_D(const QFile); + if (!isOpen() || !d->fileEngine) return -1; - if (fileEngine()) - return d->fileEngine->handle(); - return -1; + return d->fileEngine->handle(); } /*! @@ -1353,7 +1352,11 @@ bool QFile::flush() { Q_D(QFile); - fileEngine(); + if (!d->fileEngine) { + qWarning("QFile::flush: No file engine. Is IODevice open?"); + return false; + } + if (!d->writeBuffer.isEmpty()) { qint64 size = d->writeBuffer.size(); if (_qfile_writeData(d->fileEngine, &d->writeBuffer) != size) { @@ -1394,7 +1397,7 @@ QFile::close() d->writeBuffer.clear(); // keep earlier error from flush - if (fileEngine()->close() && flushed) + if (d->fileEngine->close() && flushed) unsetError(); else if (flushed) d->setError(d->fileEngine->error(), d->fileEngine->errorString()); -- cgit v0.12 From 4974742bb85b5f22ade3e1a59c2b5fe7ac84e684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 13 Jan 2010 18:13:11 +0100 Subject: QFile::readData: Simplify code Reviewed-by: Markus Goetz --- src/corelib/io/qfile.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index df470b9..728c316 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -1517,18 +1517,14 @@ qint64 QFile::readData(char *data, qint64 len) if (!d->ensureFlushed()) return -1; - qint64 ret = -1; qint64 read = d->fileEngine->read(data, len); - if (read != -1) - ret = read; - - if(ret < 0) { + if(read < 0) { QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::ReadError; d->setError(err, d->fileEngine->errorString()); } - return ret; + return read; } /*! -- cgit v0.12 From ee889d2404f6a55a8fae812dc5809dc805905d2b Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Mon, 18 Jan 2010 16:10:24 +0100 Subject: Avoid painting while loading in the anomaly demo browser At load time, loading, layouting and painting are fighting for the CPU. By skipping painting and layouting, we achieve a better loading time, and the experience is better. --- demos/embedded/anomaly/anomaly.pro | 6 +++-- demos/embedded/anomaly/src/BrowserView.cpp | 5 ++-- demos/embedded/anomaly/src/BrowserView.h | 4 +++- demos/embedded/anomaly/src/webview.cpp | 37 ++++++++++++++++++++++++++++++ demos/embedded/anomaly/src/webview.h | 25 ++++++++++++++++++++ 5 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 demos/embedded/anomaly/src/webview.cpp create mode 100644 demos/embedded/anomaly/src/webview.h diff --git a/demos/embedded/anomaly/anomaly.pro b/demos/embedded/anomaly/anomaly.pro index 2871ba7..165ce89 100644 --- a/demos/embedded/anomaly/anomaly.pro +++ b/demos/embedded/anomaly/anomaly.pro @@ -8,7 +8,8 @@ HEADERS += src/BrowserWindow.h \ src/BookmarksView.h \ src/flickcharm.h \ src/ZoomStrip.h \ - src/ControlStrip.h + src/ControlStrip.h \ + src/webview.h SOURCES += src/Main.cpp \ src/BrowserWindow.cpp \ src/BrowserView.cpp \ @@ -18,7 +19,8 @@ SOURCES += src/Main.cpp \ src/BookmarksView.cpp \ src/flickcharm.cpp \ src/ZoomStrip.cpp \ - src/ControlStrip.cpp + src/ControlStrip.cpp \ + src/webview.cpp RESOURCES += src/anomaly.qrc symbian { diff --git a/demos/embedded/anomaly/src/BrowserView.cpp b/demos/embedded/anomaly/src/BrowserView.cpp index ab52e81..0945b89 100644 --- a/demos/embedded/anomaly/src/BrowserView.cpp +++ b/demos/embedded/anomaly/src/BrowserView.cpp @@ -48,6 +48,7 @@ #include "ControlStrip.h" #include "TitleBar.h" #include "flickcharm.h" +#include "webview.h" #include "ZoomStrip.h" #if defined (Q_OS_SYMBIAN) @@ -62,7 +63,7 @@ BrowserView::BrowserView(QWidget *parent) , m_currentZoom(100) { m_titleBar = new TitleBar(this); - m_webView = new QWebView(this); + m_webView = new WebView(this); m_zoomStrip = new ZoomStrip(this); m_controlStrip = new ControlStrip(this); @@ -95,7 +96,7 @@ void BrowserView::initialize() connect(m_webView, SIGNAL(loadFinished(bool)), SLOT(finish(bool))); connect(m_webView, SIGNAL(urlChanged(QUrl)), SLOT(updateTitleBar())); - m_webView->setHtml("Will try to load page soon!"); + m_webView->setHtml("about:blank"); m_webView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_webView->setFocus(); #ifdef Q_OS_SYMBIAN diff --git a/demos/embedded/anomaly/src/BrowserView.h b/demos/embedded/anomaly/src/BrowserView.h index fdc126d..5ab1dd7 100644 --- a/demos/embedded/anomaly/src/BrowserView.h +++ b/demos/embedded/anomaly/src/BrowserView.h @@ -49,6 +49,7 @@ class QUrl; class QWebView; class TitleBar; class ControlStrip; +class WebView; class ZoomStrip; class BrowserView : public QWidget @@ -81,7 +82,7 @@ protected: private: TitleBar *m_titleBar; - QWebView *m_webView; + WebView *m_webView; ZoomStrip *m_zoomStrip; ControlStrip *m_controlStrip; int m_progress; @@ -90,3 +91,4 @@ private: }; #endif // BROWSERVIEW_H + diff --git a/demos/embedded/anomaly/src/webview.cpp b/demos/embedded/anomaly/src/webview.cpp new file mode 100644 index 0000000..d55c68e --- /dev/null +++ b/demos/embedded/anomaly/src/webview.cpp @@ -0,0 +1,37 @@ +#include "webview.h" + +#include + +WebView::WebView(QWidget *parent) + : QWebView(parent) + , inLoading(false) +{ + connect(this, SIGNAL(loadStarted()), this, SLOT(newPageLoading())); + connect(this, SIGNAL(loadFinished(bool)), this, SLOT(pageLoaded(bool))); +} + +void WebView::paintEvent(QPaintEvent *event) +{ + if (inLoading && loadingTime.elapsed() < 750) { + QPainter painter(this); + painter.setBrush(Qt::white); + painter.setPen(Qt::NoPen); + foreach (const QRect &rect, event->region().rects()) { + painter.drawRect(rect); + } + } else { + QWebView::paintEvent(event); + } +} + +void WebView::newPageLoading() +{ + inLoading = true; + loadingTime.start(); +} + +void WebView::pageLoaded(bool) +{ + inLoading = false; + update(); +} diff --git a/demos/embedded/anomaly/src/webview.h b/demos/embedded/anomaly/src/webview.h new file mode 100644 index 0000000..a7426c6 --- /dev/null +++ b/demos/embedded/anomaly/src/webview.h @@ -0,0 +1,25 @@ +#ifndef WEBVIEW_H +#define WEBVIEW_H + +#include +#include + +class WebView : public QWebView +{ + Q_OBJECT +public: + WebView(QWidget *parent = 0); + +protected: + void paintEvent(QPaintEvent *event); + +private slots: + void newPageLoading(); + void pageLoaded(bool ok); + +private: + QTime loadingTime; + bool inLoading; +}; + +#endif // WEBVIEW_H -- cgit v0.12 From 74a3dc292d3e48e74836fb953fe793b65e652c54 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Mon, 18 Jan 2010 16:13:19 +0100 Subject: Change the prefered content size of the anomaly browser Having the prefered content size equals to the screen size gives some bad layout on devices. --- demos/embedded/anomaly/src/webview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/demos/embedded/anomaly/src/webview.cpp b/demos/embedded/anomaly/src/webview.cpp index d55c68e..ffcb6bc 100644 --- a/demos/embedded/anomaly/src/webview.cpp +++ b/demos/embedded/anomaly/src/webview.cpp @@ -1,6 +1,7 @@ #include "webview.h" #include +#include WebView::WebView(QWidget *parent) : QWebView(parent) @@ -8,6 +9,7 @@ WebView::WebView(QWidget *parent) { connect(this, SIGNAL(loadStarted()), this, SLOT(newPageLoading())); connect(this, SIGNAL(loadFinished(bool)), this, SLOT(pageLoaded(bool))); + page()->setPreferredContentsSize(QSize(1024, 768)); } void WebView::paintEvent(QPaintEvent *event) -- cgit v0.12 From 102f415e39772086e9066f2e9954c0c22725a23e Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 18 Jan 2010 16:01:14 +0100 Subject: Fix QSslCertificate issues Thank you Matthew Cattell for the fix! Task-number: QTBUG-6466 Reviewed-by: joao --- src/network/ssl/qsslcertificate.cpp | 14 ++++++++++++-- tests/auto/qsslcertificate/tst_qsslcertificate.cpp | 13 +++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index dd50c38..8993e72 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -304,6 +304,7 @@ static QString _q_SubjectInfoToString(QSslCertificate::SubjectInfo info) */ QString QSslCertificate::issuerInfo(SubjectInfo info) const { + // lazy init if (d->issuerInfo.isEmpty() && d->x509) d->issuerInfo = _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(d->x509), 0, 0)); @@ -320,7 +321,11 @@ QString QSslCertificate::issuerInfo(SubjectInfo info) const */ QString QSslCertificate::issuerInfo(const QByteArray &tag) const { - // ### Use a QByteArray for the keys in the map + // lazy init + if (d->issuerInfo.isEmpty() && d->x509) + d->issuerInfo = + _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(d->x509), 0, 0)); + return d->issuerInfo.value(QString::fromLatin1(tag)); } @@ -335,6 +340,7 @@ QString QSslCertificate::issuerInfo(const QByteArray &tag) const */ QString QSslCertificate::subjectInfo(SubjectInfo info) const { + // lazy init if (d->subjectInfo.isEmpty() && d->x509) d->subjectInfo = _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(d->x509), 0, 0)); @@ -350,7 +356,11 @@ QString QSslCertificate::subjectInfo(SubjectInfo info) const */ QString QSslCertificate::subjectInfo(const QByteArray &tag) const { - // ### Use a QByteArray for the keys in the map + // lazy init + if (d->subjectInfo.isEmpty() && d->x509) + d->subjectInfo = + _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(d->x509), 0, 0)); + return d->subjectInfo.value(QString::fromLatin1(tag)); } diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp index 892d745..44f8522 100644 --- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp @@ -105,6 +105,7 @@ private slots: void fromPath_data(); void fromPath(); void certInfo(); + void certInfoQByteArray(); void task256066toPem(); void nulInCN(); void nulInSan(); @@ -697,6 +698,18 @@ void tst_QSslCertificate::certInfo() QCOMPARE(cert, QSslCertificate(QByteArray::fromHex(der), QSsl::Der)); } +void tst_QSslCertificate::certInfoQByteArray() +{ + QSslCertificate cert = QSslCertificate::fromPath("certificates/cert.pem", QSsl::Pem, + QRegExp::FixedString).first(); + QVERIFY(!cert.isNull()); + + // in this test, check the bytearray variants before the enum variants to see if + // we fixed a bug we had with lazy initialization of the values. + QCOMPARE(cert.issuerInfo("CN"), QString("Test CA (1024 bit)")); + QCOMPARE(cert.subjectInfo("CN"), QString("name/with/slashes")); +} + void tst_QSslCertificate::task256066toPem() { // a certificate whose PEM encoding's length is a multiple of 64 -- cgit v0.12 From b5d3b999fa9c52246c8d4e4c1389df105d96cced Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 18 Jan 2010 14:57:21 +0100 Subject: Enhance QFileNetworkReply It is now considered as finished immediatly after creation to avoid an event loop spin. Had to change the auto tests a bit to account for the new behaviour. Reviewed-by: Peter Hartmann --- src/network/access/qfilenetworkreply.cpp | 94 +++++++++++--------------- src/network/access/qfilenetworkreply_p.h | 10 +-- src/network/access/qnetworkaccessmanager.cpp | 4 +- src/network/access/qnetworkreply.cpp | 5 +- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 21 ++++-- 5 files changed, 64 insertions(+), 70 deletions(-) diff --git a/src/network/access/qfilenetworkreply.cpp b/src/network/access/qfilenetworkreply.cpp index 44dd9e7..8c5065c 100644 --- a/src/network/access/qfilenetworkreply.cpp +++ b/src/network/access/qfilenetworkreply.cpp @@ -44,35 +44,32 @@ #include "QtCore/qdatetime.h" #include #include +#include QT_BEGIN_NAMESPACE QFileNetworkReplyPrivate::QFileNetworkReplyPrivate() - : QNetworkReplyPrivate(), realFileSize(0), finished(false) + : QNetworkReplyPrivate(), realFileSize(0) { } -QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req) +QFileNetworkReply::~QFileNetworkReply() +{ +} + +QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op) : QNetworkReply(*new QFileNetworkReplyPrivate(), parent) { setRequest(req); setUrl(req.url()); - setOperation(QNetworkAccessManager::GetOperation); - QMetaObject::invokeMethod(this, "_q_startOperation", Qt::QueuedConnection); + setOperation(op); QNetworkReply::open(QIODevice::ReadOnly); -} -QFileNetworkReply::~QFileNetworkReply() -{ -} + qRegisterMetaType("QNetworkReply::NetworkError"); -// This code is mostly inspired by QNetworkAccessFileBackend -// We also use its translation context for error messages -void QFileNetworkReplyPrivate::_q_startOperation() -{ - Q_Q(QFileNetworkReply); + QFileNetworkReplyPrivate *d = (QFileNetworkReplyPrivate*) d_func(); - QUrl url = q->url(); + QUrl url = req.url(); if (url.host() == QLatin1String("localhost")) url.setHost(QString()); @@ -81,81 +78,75 @@ void QFileNetworkReplyPrivate::_q_startOperation() if (!url.host().isEmpty()) { // we handle only local files QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString()); - q->setError(QNetworkReply::ProtocolInvalidOperationError, msg); - emit q->error(QNetworkReply::ProtocolInvalidOperationError); - doFinished(); + setError(QNetworkReply::ProtocolInvalidOperationError, msg); + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolInvalidOperationError)); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); return; } #endif if (url.path().isEmpty()) url.setPath(QLatin1String("/")); - q->setUrl(url); + setUrl(url); QString fileName = url.toLocalFile(); if (fileName.isEmpty()) { fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); } - realFile.setFileName(fileName); + d->realFile.setFileName(fileName); - QFileInfo fi(realFile); + QFileInfo fi(d->realFile); if (fi.isDir()) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString()); - q->setError(QNetworkReply::ContentOperationNotPermittedError, msg); - emit q->error(QNetworkReply::ContentOperationNotPermittedError); - doFinished(); + setError(QNetworkReply::ContentOperationNotPermittedError, msg); + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentOperationNotPermittedError)); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); return; } - bool opened = realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered); + bool opened = d->realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered); // could we open the file? if (!opened) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2") - .arg(realFile.fileName(), realFile.errorString()); + .arg(d->realFile.fileName(), d->realFile.errorString()); - if (realFile.exists()) { - q->setError(QNetworkReply::ContentAccessDenied, msg); - emit q->error(QNetworkReply::ContentAccessDenied); + if (d->realFile.exists()) { + setError(QNetworkReply::ContentAccessDenied, msg); + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentAccessDenied)); } else { - q->setError(QNetworkReply::ContentNotFoundError, msg); - emit q->error(QNetworkReply::ContentNotFoundError); + setError(QNetworkReply::ContentNotFoundError, msg); + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentNotFoundError)); } - doFinished(); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); return; } - realFileSize = fi.size(); - q->setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified()); - q->setHeader(QNetworkRequest::ContentLengthHeader, realFileSize); + d->realFileSize = fi.size(); + setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified()); + setHeader(QNetworkRequest::ContentLengthHeader, d->realFileSize); - emit q->metaDataChanged(); - emit q->downloadProgress(realFileSize, realFileSize); - emit q->readyRead(); - doFinished(); + QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection, + Q_ARG(qint64, d->realFileSize), Q_ARG(qint64, d->realFileSize)); + QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); } bool QFileNetworkReplyPrivate::isFinished() const { - return finished; -} - -void QFileNetworkReplyPrivate::doFinished() -{ - Q_Q(QFileNetworkReply); - finished = true; - emit q->finished(); + return true; } - void QFileNetworkReply::close() { Q_D(QFileNetworkReply); QNetworkReply::close(); d->realFile.close(); - - if (!d->finished) - d->doFinished(); } void QFileNetworkReply::abort() @@ -163,9 +154,6 @@ void QFileNetworkReply::abort() Q_D(QFileNetworkReply); QNetworkReply::close(); d->realFile.close(); - - if (!d->finished) - d->doFinished(); } qint64 QFileNetworkReply::bytesAvailable() const diff --git a/src/network/access/qfilenetworkreply_p.h b/src/network/access/qfilenetworkreply_p.h index 6f10672..125fa2e 100644 --- a/src/network/access/qfilenetworkreply_p.h +++ b/src/network/access/qfilenetworkreply_p.h @@ -66,7 +66,7 @@ class QFileNetworkReply: public QNetworkReply { Q_OBJECT public: - QFileNetworkReply(QObject *parent, const QNetworkRequest &req); + QFileNetworkReply(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op); ~QFileNetworkReply(); virtual void abort(); @@ -76,12 +76,9 @@ public: virtual bool isSequential () const; qint64 size() const; - virtual qint64 readData(char *data, qint64 maxlen); Q_DECLARE_PRIVATE(QFileNetworkReply) - Q_PRIVATE_SLOT(d_func(), void _q_startOperation()) - }; class QFileNetworkReplyPrivate: public QNetworkReplyPrivate @@ -92,12 +89,7 @@ public: QFile realFile; qint64 realFileSize; - void _q_startOperation(); - virtual bool isFinished() const; - void doFinished(); - bool finished; - Q_DECLARE_PUBLIC(QFileNetworkReply) }; diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index d27fbe7..e16aedc 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -687,10 +687,10 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera // Also if the scheme is empty we consider it a file. // The QNetworkAccessFileBackend will right now only be used // for PUT or qrc:// - if (op == QNetworkAccessManager::GetOperation + if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) && (req.url().scheme() == QLatin1String("file") || req.url().scheme().isEmpty())) { - return new QFileNetworkReply(this, req); + return new QFileNetworkReply(this, req, op); } QNetworkRequest request = req; diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index 49a287f..0a8ea5d 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -239,7 +239,10 @@ QNetworkReplyPrivate::QNetworkReplyPrivate() \note Do not delete the object in the slot connected to this signal. Use deleteLater(). - \sa QNetworkAccessManager::finished() + You can also use isFinished() to check if a QNetworkReply + has finished even before you receive the finished() signal. + + \sa QNetworkAccessManager::finished(), isFinished() */ /*! diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 33753f1..3bf06d7 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -838,13 +838,20 @@ void tst_QNetworkReply::stateChecking() QVERIFY(reply->isOpen()); QVERIFY(reply->isReadable()); QVERIFY(!reply->isWritable()); - QCOMPARE(reply->errorString(), QString("Unknown error")); + + // both behaviours are OK since we might change underlying behaviour again + if (!reply->isFinished()) + QCOMPARE(reply->errorString(), QString("Unknown error")); + else + QVERIFY(!reply->errorString().isEmpty()); + QCOMPARE(reply->manager(), &manager); QCOMPARE(reply->request(), req); QCOMPARE(int(reply->operation()), int(QNetworkAccessManager::GetOperation)); - QCOMPARE(reply->error(), QNetworkReply::NoError); - QCOMPARE(reply->isFinished(), false); + // error and not error are OK since we might change underlying behaviour again + if (!reply->isFinished()) + QCOMPARE(reply->error(), QNetworkReply::NoError); QCOMPARE(reply->url(), url); reply->abort(); @@ -1151,7 +1158,8 @@ void tst_QNetworkReply::getErrors() QNetworkReplyPtr reply = manager.get(request); reply->setParent(this); // we have expect-fails - QCOMPARE(reply->error(), QNetworkReply::NoError); + if (!reply->isFinished()) + QCOMPARE(reply->error(), QNetworkReply::NoError); // now run the request: connect(reply, SIGNAL(finished()), @@ -1512,6 +1520,7 @@ void tst_QNetworkReply::ioGetFromFile() QNetworkRequest request(QUrl::fromLocalFile(file.fileName())); QNetworkReplyPtr reply = manager.get(request); + QVERIFY(reply->isFinished()); // a file should immediatly be done DataReader reader(reply); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -3170,7 +3179,9 @@ void tst_QNetworkReply::ioPostToHttpEmptyUploadProgress() void tst_QNetworkReply::lastModifiedHeaderForFile() { - QFileInfo fileInfo(SRCDIR "./bigfile"); + QFileInfo fileInfo(SRCDIR "/bigfile"); + QVERIFY(fileInfo.exists()); + QUrl url = QUrl::fromLocalFile(fileInfo.filePath()); QNetworkRequest request(url); -- cgit v0.12 From 330e852641121c0dddf2e9ac7dc6a7bafb5432dd Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 18 Jan 2010 15:46:29 +0100 Subject: Extend qfile_vs_qnetworkaccessmanager benchmark We need a third one to benchmark the without-event-loop use case that we now provide. Reviewed-by: TrustMe --- .../qfile_vs_qnetworkaccessmanager/main.cpp | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/benchmarks/qfile_vs_qnetworkaccessmanager/main.cpp b/tests/benchmarks/qfile_vs_qnetworkaccessmanager/main.cpp index 907ffb7..23e07db 100644 --- a/tests/benchmarks/qfile_vs_qnetworkaccessmanager/main.cpp +++ b/tests/benchmarks/qfile_vs_qnetworkaccessmanager/main.cpp @@ -55,11 +55,13 @@ class qfile_vs_qnetworkaccessmanager : public QObject // but.. this is a manual test anyway, so :) protected: void qnamFileRead_iteration(QNetworkAccessManager &manager, QNetworkRequest &request); + void qnamImmediateFileRead_iteration(QNetworkAccessManager &manager, QNetworkRequest &request); void qfileFileRead_iteration(); static const int iterations = 10; private slots: void qnamFileRead(); + void qnamImmediateFileRead(); void qfileFileRead(); void initTestCase(); @@ -124,6 +126,39 @@ void qfile_vs_qnetworkaccessmanager::qnamFileRead() qDebug() << "Speed:" << (qreal(size*iterations) / 1024.0) / (qreal(elapsed) / 1000.0) << "KB/sec"; } +void qfile_vs_qnetworkaccessmanager::qnamImmediateFileRead_iteration(QNetworkAccessManager &manager, QNetworkRequest &request) +{ + QNetworkReply* reply = manager.get(request); + QVERIFY(reply->isFinished()); // should be like that! + QByteArray qba = reply->readAll(); + delete reply; +} + +void qfile_vs_qnetworkaccessmanager::qnamImmediateFileRead() +{ + QNetworkAccessManager manager; + QTime t; + QNetworkRequest request(QUrl(testFile.fileName())); + + // do 3 dry runs for cache warmup + qnamImmediateFileRead_iteration(manager, request); + qnamImmediateFileRead_iteration(manager, request); + qnamImmediateFileRead_iteration(manager, request); + + t.start(); + // 10 real runs + QBENCHMARK_ONCE { + for (int i = 0; i < iterations; i++) { + qnamImmediateFileRead_iteration(manager, request); + } + } + + qint64 elapsed = t.elapsed(); + qDebug() << endl << "Finished!"; + qDebug() << "Bytes:" << size; + qDebug() << "Speed:" << (qreal(size*iterations) / 1024.0) / (qreal(elapsed) / 1000.0) << "KB/sec"; +} + void qfile_vs_qnetworkaccessmanager::qfileFileRead_iteration() { testFile.reset(); -- cgit v0.12 From ef14a38247f2a8b8a6094e7edeba0aef6e9f9c80 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 18 Jan 2010 16:52:34 +0100 Subject: tst_qnetworkreply: There were 2 unneeded QSignalSpy Was a cut n paste error probably. Reviewed-by: TrustMe --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 3bf06d7..eec4797 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -3186,7 +3186,6 @@ void tst_QNetworkReply::lastModifiedHeaderForFile() QNetworkRequest request(url); QNetworkReplyPtr reply = manager.head(request); - QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -3202,7 +3201,6 @@ void tst_QNetworkReply::lastModifiedHeaderForHttp() QNetworkRequest request(url); QNetworkReplyPtr reply = manager.head(request); - QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); -- cgit v0.12 From 3214e477ccc3eae5c61b357696095f1f460fafbb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 18 Jan 2010 20:01:00 +0100 Subject: Add proper license headers to new files. Reviewed-by: Trust Me --- demos/embedded/anomaly/src/webview.cpp | 41 ++++++++++++++++++++++++++++++++++ demos/embedded/anomaly/src/webview.h | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/demos/embedded/anomaly/src/webview.cpp b/demos/embedded/anomaly/src/webview.cpp index ffcb6bc..5cb913b 100644 --- a/demos/embedded/anomaly/src/webview.cpp +++ b/demos/embedded/anomaly/src/webview.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demos of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "webview.h" #include diff --git a/demos/embedded/anomaly/src/webview.h b/demos/embedded/anomaly/src/webview.h index a7426c6..ecd9f5a 100644 --- a/demos/embedded/anomaly/src/webview.h +++ b/demos/embedded/anomaly/src/webview.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demos of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef WEBVIEW_H #define WEBVIEW_H -- cgit v0.12