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
qfilesystemengine.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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
5#include <QtCore/qdir.h>
6#include <QtCore/qset.h>
7#include <QtCore/qstringbuilder.h>
8#include <QtCore/private/qabstractfileengine_p.h>
9#ifdef QT_BUILD_CORE_LIB
10#include <QtCore/private/qresource_p.h>
11#endif
12#include <QtCore/private/qduplicatetracker_p.h>
13
15
22QString QFileSystemEngine::slowCanonicalized(const QString &path)
23{
24 if (path.isEmpty())
25 return path;
26
27 QFileInfo fi;
28 const QChar slash(u'/');
29 QString tmpPath = path;
30 qsizetype separatorPos = 0;
31 QSet<QString> nonSymlinks;
32 QDuplicateTracker<QString> known;
33
34 (void)known.hasSeen(path);
35 do {
36#ifdef Q_OS_WIN
37 if (separatorPos == 0) {
38 if (tmpPath.size() >= 2 && tmpPath.at(0) == slash && tmpPath.at(1) == slash) {
39 // UNC, skip past the first two elements
40 separatorPos = tmpPath.indexOf(slash, 2);
41 } else if (tmpPath.size() >= 3 && tmpPath.at(1) == u':' && tmpPath.at(2) == slash) {
42 // volume root, skip since it can not be a symlink
43 separatorPos = 2;
44 }
45 }
46 if (separatorPos != -1)
47#endif
48 separatorPos = tmpPath.indexOf(slash, separatorPos + 1);
49 QString prefix = separatorPos == -1 ? tmpPath : tmpPath.left(separatorPos);
50 if (!nonSymlinks.contains(prefix)) {
51 fi.setFile(prefix);
52 if (fi.isSymLink()) {
53 QString target = fi.symLinkTarget();
54 if (separatorPos != -1) {
55 if (fi.isDir() && !target.endsWith(slash))
56 target.append(slash);
57 target.append(QStringView{tmpPath}.mid(separatorPos));
58 }
59 tmpPath = QDir::cleanPath(target);
60 separatorPos = 0;
61
62 if (known.hasSeen(tmpPath))
63 return QString();
64 } else {
65 nonSymlinks.insert(prefix);
66 }
67 }
68 } while (separatorPos != -1);
69
70 return QDir::cleanPath(tmpPath);
71}
72
73static inline bool _q_checkEntry(QFileSystemEntry &entry, QFileSystemMetaData &data, bool resolvingEntry)
74{
75 if (resolvingEntry) {
77 || !data.exists()) {
78 data.clear();
79 return false;
80 }
81 }
82
83 return true;
84}
85
86static inline bool _q_checkEntry(std::unique_ptr<QAbstractFileEngine> &engine, bool resolvingEntry)
87{
88 if (resolvingEntry) {
90 engine.reset();
91 return false;
92 }
93 }
94
95 return true;
96}
97
99 std::unique_ptr<QAbstractFileEngine> &engine,
100 bool resolvingEntry = false)
101{
102 QString const &filePath = entry.filePath();
104 return _q_checkEntry(engine, resolvingEntry);
105
106#if defined(QT_BUILD_CORE_LIB)
107 for (qsizetype prefixSeparator = 0; prefixSeparator < filePath.size(); ++prefixSeparator) {
108 QChar const ch = filePath[prefixSeparator];
109 if (ch == u'/')
110 break;
111
112 if (ch == u':') {
113 if (prefixSeparator == 0) {
114 engine = std::make_unique<QResourceFileEngine>(filePath);
115 return _q_checkEntry(engine, resolvingEntry);
116 }
117
118 if (prefixSeparator == 1)
119 break;
120
121 const QStringList &paths = QDir::searchPaths(filePath.left(prefixSeparator));
122 for (int i = 0; i < paths.size(); i++) {
124 paths.at(i) % u'/' % QStringView{filePath}.mid(prefixSeparator + 1)));
125 // Recurse!
127 return true;
128 }
129
130 // entry may have been clobbered at this point.
131 return false;
132 }
133
134 // There's no need to fully validate the prefix here. Consulting the
135 // unicode tables could be expensive and validation is already
136 // performed in QDir::setSearchPaths.
137 //
138 // if (!ch.isLetterOrNumber())
139 // break;
140 }
141#endif // defined(QT_BUILD_CORE_LIB)
142
143 return _q_checkEntry(entry, data, resolvingEntry);
144}
145
156std::unique_ptr<QAbstractFileEngine>
158{
160 std::unique_ptr<QAbstractFileEngine> engine;
161
163 // Reset entry to resolved copy.
164 entry = copy;
165 else
166 data.clear();
167
168 return engine;
169}
170
171//static
173{
174#if defined(Q_OS_WIN)
175 Q_UNUSED(metaData);
176 return QFileSystemEngine::owner(entry, QAbstractFileEngine::OwnerUser);
177#else //(Q_OS_UNIX)
180 if (!metaData.exists())
181 return QString();
182 return resolveUserName(metaData.userId());
183#endif
184}
185
186//static
188{
189#if defined(Q_OS_WIN)
190 Q_UNUSED(metaData);
191 return QFileSystemEngine::owner(entry, QAbstractFileEngine::OwnerGroup);
192#else //(Q_OS_UNIX)
195 if (!metaData.exists())
196 return QString();
197 return resolveGroupName(metaData.groupId());
198#endif
199}
200
201//static
204{
205#if defined(Q_OS_WIN)
206 return junctionTarget(link, data);
207#else
208 Q_UNUSED(link);
209 Q_UNUSED(data);
210 return {};
211#endif
212}
213
\inmodule QtCore
static QStringList searchPaths(const QString &prefix)
Definition qdir.cpp:1156
static QString cleanPath(const QString &path)
Returns path with directory separators normalized (that is, platform-native separators converted to "...
Definition qdir.cpp:2398
static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what)
static std::unique_ptr< QAbstractFileEngine > createLegacyEngine(QFileSystemEntry &entry, QFileSystemMetaData &data)
static QFileSystemEntry getJunctionTarget(const QFileSystemEntry &link, QFileSystemMetaData &data)
static QString resolveUserName(const QFileSystemEntry &entry, QFileSystemMetaData &data)
static QString resolveGroupName(const QFileSystemEntry &entry, QFileSystemMetaData &data)
bool hasFlags(MetaDataFlags flags) const
uint userId() const
uint groupId() const
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString left(qsizetype n) const &
Definition qstring.h:363
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
QString & append(QChar c)
Definition qstring.cpp:3252
Combined button and popup list for selecting options.
std::unique_ptr< QAbstractFileEngine > qt_custom_file_engine_handler_create(const QString &path)
static jboolean copy(JNIEnv *, jobject)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
static bool _q_createLegacyEngine_recursive(QFileSystemEntry &entry, QFileSystemMetaData &data, std::unique_ptr< QAbstractFileEngine > &engine, bool resolvingEntry=false)
static bool _q_checkEntry(QFileSystemEntry &entry, QFileSystemMetaData &data, bool resolvingEntry)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei const GLuint * paths
GLenum target
GLuint entry
GLsizei const GLchar *const * path
#define Q_UNUSED(x)
ptrdiff_t qsizetype
Definition qtypes.h:165
QJSEngine engine
[0]