27 *errorString = QStringLiteral(
"Magic bytes in the header do not match");
32 *errorString = QString::fromUtf8(
"V4 data structure version mismatch. Found %1 expected %2")
37 if (sourceTimeStamp) {
40 if (!expectedSourceTimeStamp.isValid())
41 expectedSourceTimeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified();
43 if (expectedSourceTimeStamp.isValid()
44 && expectedSourceTimeStamp.toMSecsSinceEpoch() != sourceTimeStamp) {
45 *errorString = QStringLiteral(
"QML source file has a different time stamp than cached file.");
59 QCryptographicHash *hash, QHash<quintptr, QByteArray> *checksums)
const
61 std::vector<
int> keys (size());
63 for (
auto it = constBegin(), end = constEnd(); it != end; ++it) {
67 std::sort(keys.begin(), keys.end());
69 if (!
this->operator[](key)->addToHash(hash, checksums))
103 static const QByteArray envCachePath = qgetenv(
"QML_DISK_CACHE_PATH");
105 const QString localSourcePath = QQmlFile::urlToLocalFileOrQrc(url);
106 const QString cacheFileSuffix
107 = QFileInfo(localSourcePath + QLatin1Char(
'c')).completeSuffix();
108 QCryptographicHash fileNameHash(QCryptographicHash::Sha1);
109 fileNameHash.addData(localSourcePath.toUtf8());
110 QString directory = envCachePath.isEmpty()
111 ? QStandardPaths::writableLocation(QStandardPaths::CacheLocation)
112 + QLatin1String(
"/qmlcache/")
113 : QString::fromLocal8Bit(envCachePath) + QLatin1String(
"/");
114 QDir::root().mkpath(directory);
115 return directory + QString::fromUtf8(fileNameHash.result().toHex())
116 + QLatin1Char(
'.') + cacheFileSuffix;
120 const QUrl &url,
const QDateTime &sourceTimeStamp, QString *errorString)
122 if (!QQmlFile::isLocalFile(url)) {
123 *errorString = QStringLiteral(
"File has to be a local file.");
127 const QString sourcePath = QQmlFile::urlToLocalFileOrQrc(url);
128 auto cacheFile = std::make_unique<CompilationUnitMapper>();
130 const QStringList cachePaths = { sourcePath + QLatin1Char(
'c'), localCacheFilePath(url) };
131 for (
const QString &cachePath : cachePaths) {
132 Unit *mappedUnit = cacheFile->get(cachePath, sourceTimeStamp, errorString);
136 const Unit *oldData = unitData();
137 const Unit *
const oldDataPtr
138 = (oldData && !(oldData->flags & Unit::StaticData))
142 auto dataPtrRevert = qScopeGuard([
this, oldData](){
143 setUnitData(oldData);
145 setUnitData(mappedUnit);
147 if (mappedUnit->sourceFileIndex != 0) {
148 if (mappedUnit->sourceFileIndex >=
149 mappedUnit->stringTableSize + dynamicStrings.size()) {
150 *errorString = QStringLiteral(
"QML source file index is invalid.");
154 QQmlFile::urlToLocalFileOrQrc(stringAt(mappedUnit->sourceFileIndex))) {
155 *errorString = QStringLiteral(
"QML source file has moved to a different location.");
160 dataPtrRevert.dismiss();
161 free(
const_cast<Unit*>(oldDataPtr));
162 backingFile = std::move(cacheFile);
172 *errorString = QStringLiteral(
"Missing time stamp for source file");
176 if (!QQmlFile::isLocalFile(unitUrl)) {
177 *errorString = QStringLiteral(
"File has to be a local file.");
181 return SaveableUnitPointer(
unitData()).saveToDisk<
char>(
182 [&unitUrl, errorString](
const char *data, quint32 size) {
183 const QString cachePath = localCacheFilePath(unitUrl);
184 if (SaveableUnitPointer::writeDataToFile(
185 cachePath, data, size, errorString)) {
186 CompilationUnitMapper::invalidate(cachePath);
216 if (propertyCaches.needsVMEMetaObject(0)) {
218 if (type.isValid()) {
221 qmlType = QQmlMetaType::findCompositeType(
222 url(),
this, (unitData()->flags & CompiledData::Unit::IsSingleton)
223 ? QQmlMetaType::Singleton
224 : QQmlMetaType::NonSingleton);
227 QQmlMetaType::registerInternalCompositeType(
this);
230 auto *typeRef =
resolvedTypes.value(obj->inheritedTypeNameIndex);
232 qmlType = typeRef->type();
238 if (!dependencyHasher) {
239 for (size_t i = 0; i <
sizeof(data->dependencyMD5Checksum); ++i) {
240 if (data->dependencyMD5Checksum[i] != 0)
245 const QByteArray checksum = dependencyHasher();
246 return checksum.size() ==
sizeof(data->dependencyMD5Checksum)
247 && memcmp(data->dependencyMD5Checksum, checksum.constData(),
248 sizeof(data->dependencyMD5Checksum)) == 0;