aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_p.h2
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_unix.cpp6
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_win.cpp3
-rw-r--r--src/qml/compiler/qv4compileddata.cpp26
-rw-r--r--tests/auto/qml/qmldiskcache/qmldiskcache.pro2
-rw-r--r--tests/auto/qml/qmldiskcache/test.qml4
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp28
7 files changed, 58 insertions, 13 deletions
diff --git a/src/qml/compiler/qv4compilationunitmapper_p.h b/src/qml/compiler/qv4compilationunitmapper_p.h
index 69007f4618..5b6939f1cf 100644
--- a/src/qml/compiler/qv4compilationunitmapper_p.h
+++ b/src/qml/compiler/qv4compilationunitmapper_p.h
@@ -68,7 +68,7 @@ public:
CompilationUnitMapper();
~CompilationUnitMapper();
- CompiledData::Unit *open(const QString &sourcePath, QString *errorString);
+ CompiledData::Unit *open(const QString &cacheFilePath, const QString &sourcePath, QString *errorString);
void close();
private:
diff --git a/src/qml/compiler/qv4compilationunitmapper_unix.cpp b/src/qml/compiler/qv4compilationunitmapper_unix.cpp
index 7119acc80e..1aa3e05f5f 100644
--- a/src/qml/compiler/qv4compilationunitmapper_unix.cpp
+++ b/src/qml/compiler/qv4compilationunitmapper_unix.cpp
@@ -50,13 +50,11 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-CompiledData::Unit *CompilationUnitMapper::open(const QString &sourcePath, QString *errorString)
+CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QString &sourcePath, QString *errorString)
{
close();
- QByteArray cacheFileName = QFile::encodeName(sourcePath);
- cacheFileName.append('c');
- int fd = qt_safe_open(cacheFileName.constData(), O_RDONLY);
+ int fd = qt_safe_open(QFile::encodeName(cacheFileName).constData(), O_RDONLY);
if (fd == -1) {
*errorString = qt_error_string(errno);
return nullptr;
diff --git a/src/qml/compiler/qv4compilationunitmapper_win.cpp b/src/qml/compiler/qv4compilationunitmapper_win.cpp
index d58c46c090..7e62cbfe8b 100644
--- a/src/qml/compiler/qv4compilationunitmapper_win.cpp
+++ b/src/qml/compiler/qv4compilationunitmapper_win.cpp
@@ -49,13 +49,12 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-CompiledData::Unit *CompilationUnitMapper::open(const QString &sourcePath, QString *errorString)
+CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, const QString &sourcePath, QString *errorString)
{
close();
// ### TODO: fix up file encoding/normalization/unc handling once QFileSystemEntry
// is exported from QtCore.
- const QString cacheFileName = sourcePath + QLatin1Char('c');
HANDLE handle =
#if defined(Q_OS_WINRT)
CreateFile2(reinterpret_cast<const wchar_t*>(cacheFileName.constData()),
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index cc1f8ae261..35f61b4f69 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -56,6 +56,8 @@
#include <QFile>
#include <QFileInfo>
#include <QScopedValueRollback>
+#include <QStandardPaths>
+#include <QDir>
#endif
#include <private/qqmlirbuilder_p.h>
#include <QCoreApplication>
@@ -321,6 +323,19 @@ bool CompilationUnit::verifyChecksum(QQmlEngine *engine,
sizeof(data->dependencyMD5Checksum)) == 0;
}
+static QString cacheFilePath(const QUrl &url)
+{
+ const QString localSourcePath = QQmlFile::urlToLocalFileOrQrc(url);
+ const QString localCachePath = localSourcePath + QLatin1Char('c');
+ if (QFileInfo(QFileInfo(localSourcePath).dir().absolutePath()).isWritable())
+ return localCachePath;
+ QCryptographicHash fileNameHash(QCryptographicHash::Sha1);
+ fileNameHash.addData(localSourcePath.toUtf8());
+ QString directory = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String("/qmlcache/");
+ QDir::root().mkpath(directory);
+ return directory + QString::fromUtf8(fileNameHash.result().toHex()) + QLatin1Char('.') + QFileInfo(localCachePath).completeSuffix();
+}
+
bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString)
{
errorString->clear();
@@ -330,13 +345,13 @@ bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString)
return false;
}
- if (!unitUrl.isLocalFile()) {
+ if (!QQmlFile::isLocalFile(unitUrl)) {
*errorString = QStringLiteral("File has to be a local file.");
return false;
}
// Foo.qml -> Foo.qmlc
- QSaveFile cacheFile(unitUrl.toLocalFile() + QLatin1Char('c'));
+ QSaveFile cacheFile(cacheFilePath(unitUrl));
if (!cacheFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
*errorString = cacheFile.errorString();
return false;
@@ -371,7 +386,7 @@ bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString)
bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory, QString *errorString)
{
- if (!url.isLocalFile()) {
+ if (!QQmlFile::isLocalFile(url)) {
*errorString = QStringLiteral("File has to be a local file.");
return false;
}
@@ -379,10 +394,9 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory
const QString sourcePath = url.toLocalFile();
QScopedPointer<CompilationUnitMapper> cacheFile(new CompilationUnitMapper());
- CompiledData::Unit *mappedUnit = cacheFile->open(sourcePath, errorString);
- if (!mappedUnit) {
+ CompiledData::Unit *mappedUnit = cacheFile->open(cacheFilePath(url), sourcePath, errorString);
+ if (!mappedUnit)
return false;
- }
const Unit * const oldDataPtr = (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) ? data : nullptr;
QScopedValueRollback<const Unit *> dataPtrChange(data, mappedUnit);
diff --git a/tests/auto/qml/qmldiskcache/qmldiskcache.pro b/tests/auto/qml/qmldiskcache/qmldiskcache.pro
index f2d1a04780..f98a157b6a 100644
--- a/tests/auto/qml/qmldiskcache/qmldiskcache.pro
+++ b/tests/auto/qml/qmldiskcache/qmldiskcache.pro
@@ -4,4 +4,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qmldiskcache.cpp
+RESOURCES += test.qml
+
QT += core-private qml-private testlib
diff --git a/tests/auto/qml/qmldiskcache/test.qml b/tests/auto/qml/qmldiskcache/test.qml
new file mode 100644
index 0000000000..d632422616
--- /dev/null
+++ b/tests/auto/qml/qmldiskcache/test.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ property int value: 20
+}
diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
index dd23dfca07..8ccf4714ba 100644
--- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
+++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
@@ -38,6 +38,9 @@
#include <QQmlEngine>
#include <QQmlFileSelector>
#include <QThread>
+#include <QCryptographicHash>
+#include <QStandardPaths>
+#include <QDirIterator>
class tst_qmldiskcache: public QObject
{
@@ -52,6 +55,7 @@ private slots:
void recompileAfterChange();
void fileSelectors();
void localAliases();
+ void cacheResources();
};
// A wrapper around QQmlComponent to ensure the temporary reference counts
@@ -529,6 +533,30 @@ void tst_qmldiskcache::localAliases()
}
}
+void tst_qmldiskcache::cacheResources()
+{
+ const QString cacheDirectory = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
+ QVERIFY(QDir::root().mkpath(cacheDirectory));
+
+ const QString qmlCacheDirectory = cacheDirectory + QLatin1String("/qmlcache/");
+ QVERIFY(QDir(qmlCacheDirectory).removeRecursively());
+ QVERIFY(QDir::root().mkpath(qmlCacheDirectory));
+ QVERIFY(QDir(qmlCacheDirectory).entryList(QDir::NoDotAndDotDot).isEmpty());
+
+
+ QQmlEngine engine;
+
+ {
+ CleanlyLoadingComponent component(&engine, QUrl("qrc:/test.qml"));
+ qDebug() << component.errorString();
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("value").toInt(), 20);
+ }
+
+ QCOMPARE(QDir(qmlCacheDirectory).entryList(QDir::NoDotAndDotDot | QDir::Files).count(), 1);
+}
+
QTEST_MAIN(tst_qmldiskcache)
#include "tst_qmldiskcache.moc"