Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmljsresourcefilemapper.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5
6#include <QFileInfo>
7#include <QDir>
8#include <QXmlStreamReader>
9
11
19
28
37
47
49{
50 for (const QString &fileName: resourceFiles) {
52 if (!f.open(QIODevice::ReadOnly))
53 continue;
54 populateFromQrcFile(f);
55 }
56}
57
59{
60 return qrcPathToFileSystemPath.isEmpty();
61}
62
63bool QQmlJSResourceFileMapper::isFile(const QString &resourcePath) const
64{
65 for (const auto &entry : qrcPathToFileSystemPath) {
66 if (entry.resourcePath == resourcePath)
67 return true;
68 }
69 return false;
70}
71
72static bool hasSuffix(const QString &qrcPath, const QStringList &suffixes)
73{
74 if (suffixes.isEmpty())
75 return true;
76 const QString suffix = QFileInfo(qrcPath).suffix();
77 return suffixes.contains(suffix);
78}
79
80template<typename HandleMatch>
81void doFilter(const QList<QQmlJSResourceFileMapper::Entry> &qrcPathToFileSystemPath,
83 const HandleMatch &handler)
84{
86 const QString terminatedDirectory = filter.path.endsWith(u'/')
87 ? filter.path : (filter.path + u'/');
88
89 for (auto it = qrcPathToFileSystemPath.constBegin(),
90 end = qrcPathToFileSystemPath.constEnd(); it != end; ++it) {
91
92 const QString candidate = (filter.flags & QQmlJSResourceFileMapper::Resource)
93 ? it->resourcePath
94 : it->filePath;
95
96 if (!filter.path.isEmpty() && !candidate.startsWith(terminatedDirectory))
97 continue;
98
99 if (!hasSuffix(candidate, filter.suffixes))
100 continue;
101
103 // Crude. But shall we really allow slashes in QRC file names?
104 || !candidate.mid(terminatedDirectory.size()).contains(u'/')) {
105 if (handler(*it))
106 return;
107 }
108 }
109 return;
110 }
111
112 if (!hasSuffix(filter.path, filter.suffixes))
113 return;
114
115 for (auto it = qrcPathToFileSystemPath.constBegin(),
116 end = qrcPathToFileSystemPath.constEnd(); it != end; ++it) {
118 if (it->resourcePath == filter.path && handler(*it))
119 return;
120 } else if (it->filePath == filter.path && handler(*it)) {
121 return;
122 }
123 }
124}
125
126QList<QQmlJSResourceFileMapper::Entry> QQmlJSResourceFileMapper::filter(
128{
129 QList<Entry> result;
130 doFilter(qrcPathToFileSystemPath, filter, [&](const Entry &entry) {
131 result.append(entry);
132 return false;
133 });
134 return result;
135}
136
139{
141 doFilter(qrcPathToFileSystemPath, filter, [&](const Entry &entry) {
142 result.append(entry.filePath);
143 return false;
144 });
145 return result;
146}
147
150{
152 doFilter(qrcPathToFileSystemPath, filter, [&](const Entry &entry) {
153 result.append(entry.resourcePath);
154 return false;
155 });
156 return result;
157}
158
161{
163 doFilter(qrcPathToFileSystemPath, filter, [&](const Entry &entry) {
164 result = entry;
165 return true;
166 });
167 return result;
168}
169
170void QQmlJSResourceFileMapper::populateFromQrcFile(QFile &file)
171{
172 enum State {
173 InitialState,
174 InRCC,
175 InResource,
176 InFile
177 };
178 State state = InitialState;
179
180 QDir qrcDir = QFileInfo(file).absoluteDir();
181
182 QString prefix;
183 QString currentFileName;
184 QXmlStreamAttributes currentFileAttributes;
185
186 QXmlStreamReader reader(&file);
187 while (!reader.atEnd()) {
188 switch (reader.readNext()) {
189 case QXmlStreamReader::StartElement:
190 if (reader.name() == QStringLiteral("RCC")) {
191 if (state != InitialState)
192 return;
193 state = InRCC;
194 continue;
195 } else if (reader.name() == QStringLiteral("qresource")) {
196 if (state != InRCC)
197 return;
198 state = InResource;
199 QXmlStreamAttributes attributes = reader.attributes();
200 if (attributes.hasAttribute(QStringLiteral("prefix")))
201 prefix = attributes.value(QStringLiteral("prefix")).toString();
202 if (!prefix.startsWith(QLatin1Char('/')))
203 prefix.prepend(QLatin1Char('/'));
204 if (!prefix.endsWith(QLatin1Char('/')))
205 prefix.append(QLatin1Char('/'));
206 continue;
207 } else if (reader.name() == QStringLiteral("file")) {
208 if (state != InResource)
209 return;
210 state = InFile;
211 currentFileAttributes = reader.attributes();
212 continue;
213 }
214 return;
215
216 case QXmlStreamReader::EndElement:
217 if (reader.name() == QStringLiteral("file")) {
218 if (state != InFile)
219 return;
220 state = InResource;
221 continue;
222 } else if (reader.name() == QStringLiteral("qresource")) {
223 if (state != InResource)
224 return;
225 state = InRCC;
226 continue;
227 } else if (reader.name() == QStringLiteral("RCC")) {
228 if (state != InRCC)
229 return;
230 state = InitialState;
231 continue;
232 }
233 return;
234
235 case QXmlStreamReader::Characters: {
236 if (reader.isWhitespace())
237 break;
238 if (state != InFile)
239 return;
240 currentFileName = reader.text().toString();
241 if (currentFileName.isEmpty())
242 continue;
243
244 const QString fsPath = QDir::cleanPath(qrcDir.absoluteFilePath(currentFileName));
245
246 if (currentFileAttributes.hasAttribute(QStringLiteral("alias")))
247 currentFileName = currentFileAttributes.value(QStringLiteral("alias")).toString();
248
249 currentFileName = QDir::cleanPath(currentFileName);
250 while (currentFileName.startsWith(QLatin1String("../")))
251 currentFileName.remove(0, 3);
252
253 const QString qrcPath = prefix + currentFileName;
254 if (QFile::exists(fsPath))
255 qrcPathToFileSystemPath.append({qrcPath, fsPath});
256 continue;
257 }
258
259 default: break;
260 }
261 }
262}
263
\inmodule QtCore
Definition qdir.h:20
static QString cleanPath(const QString &path)
Returns path with directory separators normalized (that is, platform-native separators converted to "...
Definition qdir.cpp:2398
QString suffix() const
Returns the suffix (extension) of the file.
QString canonicalFilePath() const
Returns the file system entry's canonical path, including the entry's name, that is,...
QDir absoluteDir() const
Returns a QDir object representing the absolute path of the parent directory of the file system entry...
\inmodule QtCore
Definition qfile.h:93
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qfile.cpp:351
QString text(const QString &key) const
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5455
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition qstring.cpp:5506
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.h:1369
QString & append(QChar c)
Definition qstring.cpp:3252
QString & remove(qsizetype i, qsizetype len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition qstring.cpp:3466
QString & prepend(QChar c)
Definition qstring.h:478
QSet< QString >::iterator it
else opt state
[0]
Combined button and popup list for selecting options.
QImageReader reader("image.png")
[1]
QList< QString > QStringList
Constructs a string list that contains the given string, str.
GLuint GLuint end
GLfloat GLfloat f
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLuint entry
GLuint64EXT * result
[6]
static bool hasSuffix(const QString &qrcPath, const QStringList &suffixes)
void doFilter(const QList< QQmlJSResourceFileMapper::Entry > &qrcPathToFileSystemPath, const QQmlJSResourceFileMapper::Filter &filter, const HandleMatch &handler)
#define QStringLiteral(str)
QFile file
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
Entry entry(const Filter &filter) const
static Filter resourceFileFilter(const QString &file)
static Filter resourceQmlDirectoryFilter(const QString &directory)
bool isFile(const QString &resourcePath) const
QList< Entry > filter(const Filter &filter) const
QStringList filePaths(const Filter &filter) const
static Filter localFileFilter(const QString &file)
QQmlJSResourceFileMapper(const QStringList &resourceFiles)
QStringList resourcePaths(const Filter &filter) const