From b7fa0c137c2ef567b286d83435aba843e33280b7 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Fri, 23 Apr 2010 15:58:37 +0200 Subject: QNAM HTTP: Avoid one copy Even if we have implicit sharing in QByteArray it makes sense. Reviewed-by: joao --- src/network/access/qnetworkaccesshttpbackend.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index af971a7..ba26dad 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -680,8 +680,7 @@ void QNetworkAccessHttpBackend::readFromHttp() QByteDataBuffer list; while (httpReply->bytesAvailable() != 0 && nextDownstreamBlockSize() != 0 && nextDownstreamBlockSize() > list.byteAmount()) { - QByteArray data = httpReply->readAny(); - list.append(data); + list.append(httpReply->readAny()); } if (!list.isEmpty()) -- cgit v0.12 From ed692616c6a358ccfbdb10b716d6d5829a92f7bb Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 7 Apr 2010 14:17:53 +0200 Subject: QNAM HTTP: Divide QNetworkReplyImplPrivate::appendDownstreamData The goal is to easier add an overload for (const &QByteArray). Reviewed-by: Peter Hartmann --- src/network/access/qnetworkreplyimpl.cpp | 73 +++++++++++++++++++++----------- src/network/access/qnetworkreplyimpl_p.h | 5 +++ 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 320b1ac..4f35358 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -403,6 +403,37 @@ qint64 QNetworkReplyImplPrivate::nextDownstreamBlockSize() const return qMax(0, readBufferMaxSize - readBuffer.byteAmount()); } +void QNetworkReplyImplPrivate::initCacheSaveDevice() +{ + Q_Q(QNetworkReplyImpl); + + // save the meta data + QNetworkCacheMetaData metaData; + metaData.setUrl(url); + metaData = backend->fetchCacheMetaData(metaData); + + // save the redirect request also in the cache + QVariant redirectionTarget = q->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirectionTarget.isValid()) { + QNetworkCacheMetaData::AttributesMap attributes = metaData.attributes(); + attributes.insert(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget); + metaData.setAttributes(attributes); + } + + cacheSaveDevice = networkCache()->prepare(metaData); + + if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) { + if (cacheSaveDevice && !cacheSaveDevice->isOpen()) + qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- " + "class %s probably needs to be fixed", + networkCache()->metaObject()->className()); + + networkCache()->remove(url); + cacheSaveDevice = 0; + cacheEnabled = false; + } +} + // we received downstream data and send this to the cache // and to our readBuffer (which in turn gets read by the user of QNetworkReply) void QNetworkReplyImplPrivate::appendDownstreamData(QByteDataBuffer &data) @@ -412,31 +443,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QByteDataBuffer &data) return; if (cacheEnabled && !cacheSaveDevice) { - // save the meta data - QNetworkCacheMetaData metaData; - metaData.setUrl(url); - metaData = backend->fetchCacheMetaData(metaData); - - // save the redirect request also in the cache - QVariant redirectionTarget = q->attribute(QNetworkRequest::RedirectionTargetAttribute); - if (redirectionTarget.isValid()) { - QNetworkCacheMetaData::AttributesMap attributes = metaData.attributes(); - attributes.insert(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget); - metaData.setAttributes(attributes); - } - - cacheSaveDevice = networkCache()->prepare(metaData); - - if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) { - if (cacheSaveDevice && !cacheSaveDevice->isOpen()) - qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- " - "class %s probably needs to be fixed", - networkCache()->metaObject()->className()); - - networkCache()->remove(url); - cacheSaveDevice = 0; - cacheEnabled = false; - } + initCacheSaveDevice(); } qint64 bytesWritten = 0; @@ -454,6 +461,13 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QByteDataBuffer &data) bytesDownloaded += bytesWritten; lastBytesDownloaded = bytesDownloaded; + appendDownstreamDataSignalEmissions(); +} + +void QNetworkReplyImplPrivate::appendDownstreamDataSignalEmissions() +{ + Q_Q(QNetworkReplyImpl); + QPointer qq = q; QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); @@ -495,6 +509,15 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data) _q_copyReadyRead(); } +void QNetworkReplyImplPrivate::appendDownstreamData(const QByteArray &data) +{ + // TODO implement + + // TODO call + + qFatal("QNetworkReplyImplPrivate::appendDownstreamData not implemented"); +} + void QNetworkReplyImplPrivate::finished() { Q_Q(QNetworkReplyImpl); diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index 168e5cf..a7a568a 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -145,8 +145,13 @@ public: void consume(qint64 count); void emitUploadProgress(qint64 bytesSent, qint64 bytesTotal); qint64 nextDownstreamBlockSize() const; + + void initCacheSaveDevice(); + void appendDownstreamDataSignalEmissions(); void appendDownstreamData(QByteDataBuffer &data); void appendDownstreamData(QIODevice *data); + void appendDownstreamData(const QByteArray &data); + void finished(); void error(QNetworkReply::NetworkError code, const QString &errorString); void metaDataChanged(); -- cgit v0.12 From 2e95891d29cb115dfadd57076e215030cd255489 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 7 Apr 2010 14:09:20 +0200 Subject: QNAM: Use a reference in appendDownstreamData --- src/corelib/tools/qbytedata_p.h | 2 +- src/network/access/qnetworkreplyimpl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qbytedata_p.h b/src/corelib/tools/qbytedata_p.h index 9aad6a9..17a3a60 100644 --- a/src/corelib/tools/qbytedata_p.h +++ b/src/corelib/tools/qbytedata_p.h @@ -84,7 +84,7 @@ public: } - inline void append(QByteArray& bd) + inline void append(const QByteArray& bd) { if (bd.isEmpty()) return; diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 4f35358..0f5bdd0 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -448,7 +448,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QByteDataBuffer &data) qint64 bytesWritten = 0; for (int i = 0; i < data.bufferCount(); i++) { - QByteArray item = data[i]; + QByteArray const &item = data[i]; if (cacheSaveDevice) cacheSaveDevice->write(item.constData(), item.size()); -- cgit v0.12 From c3067851071ae9480688e0d746dd6b03bd113823 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 26 Apr 2010 17:05:46 +0200 Subject: QNAM HTTP: Fix invoking a method when being destructed right now (2) Task-number: QTBUG-10171 Reviewed-by: Olivier Goffart --- src/network/access/qhttpnetworkconnectionchannel.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index f1c51bc..22dd5cb 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -317,6 +317,13 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() return; } + // only run when the QHttpNetworkConnection is not currently being destructed, e.g. + // this function is called from _q_disconnected which is called because + // of ~QHttpNetworkConnectionPrivate + if (!qobject_cast(connection)) { + return; + } + qint64 bytes = 0; QAbstractSocket::SocketState socketState = socket->state(); -- cgit v0.12 From 5b086892cec1cbcd9fe7f0abca5293519ecc4633 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 16 Mar 2010 14:01:17 +0100 Subject: QXmlSchema internals: fix crash with anonymous types The crash occurred when an anonymous type was created that was a list type. In that case, we did not set the item type, which is used later at XsdSchemaChecker::checkSimpleDerivationRestrictions(), which would lead to a crash. Additionally, in the xmlpatternsvalidator test, check the exit status of the process after it has finished, to detect crashes. Reviewed-by: Tobias Koenig Reviewed-by: Frans Englich Task-number: QTBUG-8920 --- src/xmlpatterns/schema/qxsdschemaresolver.cpp | 9 +++++++- .../complex-type-including-anonymous-type.xsd | 24 ++++++++++++++++++++++ .../tst_xmlpatternsvalidator.cpp | 13 ++++++++---- 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 tests/auto/xmlpatternsvalidator/files/complex-type-including-anonymous-type.xsd diff --git a/src/xmlpatterns/schema/qxsdschemaresolver.cpp b/src/xmlpatterns/schema/qxsdschemaresolver.cpp index 34eb12c..f3d1ed0 100644 --- a/src/xmlpatterns/schema/qxsdschemaresolver.cpp +++ b/src/xmlpatterns/schema/qxsdschemaresolver.cpp @@ -632,7 +632,14 @@ void XsdSchemaResolver::resolveSimpleContentComplexTypes(const XsdComplexType::P } else { // 1.2 const XsdSimpleType::Ptr anonType(new XsdSimpleType()); - anonType->setCategory(complexBaseType->contentType()->simpleType()->category()); + XsdSimpleType::TypeCategory baseCategory = complexBaseType->contentType()->simpleType()->category(); + anonType->setCategory(baseCategory); + + if (baseCategory == XsdSimpleType::SimpleTypeList) { + const XsdSimpleType::Ptr baseSimpleType = complexBaseType->contentType()->simpleType(); + anonType->setItemType(baseSimpleType->itemType()); + } + anonType->setDerivationMethod(XsdSimpleType::DerivationRestriction); anonType->setWxsSuperType(complexBaseType->contentType()->simpleType()); anonType->setFacets(complexTypeFacets(complexType)); diff --git a/tests/auto/xmlpatternsvalidator/files/complex-type-including-anonymous-type.xsd b/tests/auto/xmlpatternsvalidator/files/complex-type-including-anonymous-type.xsd new file mode 100644 index 0000000..da765b4 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/complex-type-including-anonymous-type.xsd @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp b/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp index 7aab47f..3517b5a 100644 --- a/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp +++ b/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp @@ -111,8 +111,8 @@ void tst_XmlPatternsValidator::xsdSupport() process.start(m_command, arguments); - QCOMPARE(process.exitStatus(), QProcess::NormalExit); QVERIFY(process.waitForFinished()); + QCOMPARE(process.exitStatus(), QProcess::NormalExit); if(process.exitCode() != expectedExitCode) QTextStream(stderr) << "foo:" << process.readAllStandardError(); @@ -197,20 +197,25 @@ void tst_XmlPatternsValidator::xsdSupport_data() const << (QStringList() << QLatin1String("files/instance.xml")) << QString(); - QTest::newRow("A schema with an indirectly included type") + QTest::newRow("QTBUG-8394 A schema with an indirectly included type") << 0 << (QStringList() << QLatin1String("files/indirect-include-a.xsd")) << QString(); - QTest::newRow("A schema with an indirectly imported type") + QTest::newRow("QTBUG-8394 A schema with an indirectly imported type") << 0 << (QStringList() << QLatin1String("files/indirect-import-a.xsd")) << QString(); - QTest::newRow("A schema with an indirectly redefined type") + QTest::newRow("QTBUG-8394 A schema with an indirectly redefined type") << 0 << (QStringList() << QLatin1String("files/indirect-redefine-a.xsd")) << QString(); + + QTest::newRow("QTBUG-8920 A schema with a complex type that indirectly includes an anonymous type") + << 0 + << (QStringList() << QLatin1String("files/complex-type-including-anonymous-type.xsd")) + << QString(); } QTEST_MAIN(tst_XmlPatternsValidator) -- cgit v0.12