Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmltypeloaderdata.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
6
7#include <private/qqmldirdata_p.h>
8#include <private/qqmlprofiler_p.h>
9#include <private/qqmlscriptblob_p.h>
10#include <private/qqmltypedata_p.h>
11
12#include <QtCore/qdirlisting.h>
13#include <QtCore/qdir.h>
14
16
18{
19 return QDirListing::IteratorFlag::CaseSensitive | QDirListing::IteratorFlag::IncludeHidden;
20}
21
23static FileSetPopulateResult populateFileSet(QCache<QString, bool> *fileSet, const QString &path,
24 const QString &file)
25{
26 const QDirListing listing(path, dirListingFlags());
27 bool seen = false;
28 for (const auto &entry : listing) {
29 const QString next = entry.fileName();
30 if (next == file)
31 seen = true;
32 fileSet->insert(next, new bool(true));
33 if (fileSet->totalCost() >= fileSet->maxCost())
34 break;
35 }
36
37 if (seen)
39 if (fileSet->totalCost() < fileSet->maxCost())
42}
43
44bool QQmlTypeLoaderSharedData::ImportDirCache::fileExists(const QString &path, const QString &file)
45{
46 QCache<QString, bool> *fileSet = content.object(path);
47 if (fileSet) {
48 if (const bool *exists = fileSet->object(file))
49 return *exists;
50
51 // If the cache isn't full, we know that we've scanned the whole directory.
52 // The file not being in the cache then means it doesn't exist.
53 if (fileSet->totalCost() < fileSet->maxCost())
54 return false;
55
56 } else if (content.contains(path)) {
57 // explicit nullptr in cache
58 return false;
59 }
60
61 const QDir dir(path);
62
63 if (!fileSet) {
64 // First try to cache the whole directory, but only up to the maxCost of the cache.
65
66 fileSet = dir.exists() ? new QCache<QString, bool> : nullptr;
67 const bool inserted = content.insert(path, fileSet);
68 Q_ASSERT(inserted);
69 if (!fileSet)
70 return false;
71
72 switch (populateFileSet(fileSet, dir.path(), file)) {
74 return false;
76 return true;
78 break;
79 }
80
81 // Cache overflow. Look up files individually
82 } else {
83 // If the directory was completely cached, we'd have returned early above.
84 Q_ASSERT(fileSet->totalCost() == fileSet->maxCost());
85 }
86
87 const QDirListing singleFile(dir.path(), { file }, dirListingFlags());
88 const bool exists = singleFile.begin() != singleFile.end();
89 fileSet->insert(file, new bool(exists));
90 Q_ASSERT(fileSet->totalCost() == fileSet->maxCost());
91 return exists;
92}
93
95{
96 if (!content.contains(dirPath)) {
97 if (QDir(dirPath).exists()) {
98 QCache<QString, bool> *files = new QCache<QString, bool>;
99 populateFileSet(files, dirPath, QString());
100 content.insert(dirPath, files);
101 return true;
102 }
103
104 content.insert(dirPath, nullptr);
105 return false;
106 }
107
108 return content.object(dirPath) != nullptr;
109}
110
111QQmlTypeLoaderLockedData::QQmlTypeLoaderLockedData(QV4::ExecutionEngine *engine) : m_engine(engine)
112{
113}
114
115QT_END_NAMESPACE
bool fileExists(const QString &path, const QString &file)
bool directoryExists(const QString &dirPath)
Combined button and popup list for selecting options.
FileSetPopulateResult
static FileSetPopulateResult populateFileSet(QCache< QString, bool > *fileSet, const QString &path, const QString &file)
static QT_BEGIN_NAMESPACE constexpr QDirListing::IteratorFlags dirListingFlags()