diff options
Diffstat (limited to 'src/corelib/io/qdir.cpp')
-rw-r--r-- | src/corelib/io/qdir.cpp | 110 |
1 files changed, 58 insertions, 52 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 92e69baee9..a038f125cb 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -57,9 +57,8 @@ #include "qfilesystemengine_p.h" #include <qstringbuilder.h> -#ifdef QT_BUILD_CORE_LIB -# include "qresource.h" -# include "private/qcoreglobaldata_p.h" +#ifndef QT_BOOTSTRAPPED +# include "qreadwritelock.h" #endif #include <algorithm> @@ -91,13 +90,13 @@ enum { }; // Return the length of the root part of an absolute path, for use by cleanPath(), cd(). -static int rootLength(const QString &name, bool allowUncPaths) +static qsizetype rootLength(QStringView name, bool allowUncPaths) { - const int len = name.length(); + const qsizetype len = name.size(); // starts with double slash if (allowUncPaths && name.startsWith(QLatin1String("//"))) { // Server name '//server/path' is part of the prefix. - const int nextSlash = name.indexOf(QLatin1Char('/'), 2); + const qsizetype nextSlash = name.indexOf(u'/', 2); return nextSlash >= 0 ? nextSlash + 1 : len; } #if defined(Q_OS_WIN) @@ -121,16 +120,8 @@ QDirPrivate::QDirPrivate(const QString &path, const QStringList &nameFilters_, Q { setPath(path.isEmpty() ? QString::fromLatin1(".") : path); - bool empty = nameFilters.isEmpty(); - if (!empty) { - empty = true; - for (int i = 0; i < nameFilters.size(); ++i) { - if (!nameFilters.at(i).isEmpty()) { - empty = false; - break; - } - } - } + auto isEmpty = [](const auto &e) { return e.isEmpty(); }; + const bool empty = std::all_of(nameFilters.cbegin(), nameFilters.cend(), isEmpty); if (empty) nameFilters = QStringList(QString::fromLatin1("*")); } @@ -166,7 +157,7 @@ bool QDirPrivate::exists() const inline QChar QDirPrivate::getFilterSepChar(const QString &nameFilter) { QChar sep(QLatin1Char(';')); - int i = nameFilter.indexOf(sep, 0); + qsizetype i = nameFilter.indexOf(sep, 0); if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1) sep = QChar(QLatin1Char(' ')); return sep; @@ -320,31 +311,31 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt return r < 0; } -inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, +inline void QDirPrivate::sortFileList(QDir::SortFlags sort, const QFileInfoList &l, QStringList *names, QFileInfoList *infos) { // names and infos are always empty lists or 0 here - int n = l.size(); + qsizetype n = l.size(); if (n > 0) { if (n == 1 || (sort & QDir::SortByMask) == QDir::Unsorted) { if (infos) *infos = l; if (names) { - for (int i = 0; i < n; ++i) - names->append(l.at(i).fileName()); + for (const QFileInfo &fi : l) + names->append(fi.fileName()); } } else { QScopedArrayPointer<QDirSortItem> si(new QDirSortItem[n]); - for (int i = 0; i < n; ++i) + for (qsizetype i = 0; i < n; ++i) si[i].item = l.at(i); std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort)); // put them back in the list(s) if (infos) { - for (int i = 0; i < n; ++i) + for (qsizetype i = 0; i < n; ++i) infos->append(si[i].item); } if (names) { - for (int i = 0; i < n; ++i) + for (qsizetype i = 0; i < n; ++i) names->append(si[i].item.fileName()); } } @@ -713,23 +704,23 @@ QString QDir::dirName() const #ifdef Q_OS_WIN -static int drivePrefixLength(const QString &path) +static qsizetype drivePrefixLength(QStringView path) { // Used to extract path's drive for use as prefix for an "absolute except for drive" path - const int size = path.length(); - int drive = 2; // length of drive prefix + const qsizetype size = path.size(); + qsizetype drive = 2; // length of drive prefix if (size > 1 && path.at(1).unicode() == ':') { if (Q_UNLIKELY(!path.at(0).isLetter())) return 0; } else if (path.startsWith(QLatin1String("//"))) { // UNC path; use its //server/share part as "drive" - it's as sane a // thing as we can do. - for (int i = 2; i-- > 0; ) { // Scan two "path fragments": + for (int i = 0 ; i < 2 ; ++i) { // Scan two "path fragments": while (drive < size && path.at(drive).unicode() == '/') drive++; if (drive >= size) { qWarning("Base directory starts with neither a drive nor a UNC share: %s", - qUtf8Printable(QDir::toNativeSeparators(path))); + qUtf8Printable(QDir::toNativeSeparators(path.toString()))); return 0; } while (drive < size && path.at(drive).unicode() != '/') @@ -779,7 +770,7 @@ QString QDir::filePath(const QString &fileName) const #ifdef Q_OS_WIN if (fileName.startsWith(QLatin1Char('/')) || fileName.startsWith(QLatin1Char('\\'))) { // Handle the "absolute except for drive" case (i.e. \blah not c:\blah): - const int drive = drivePrefixLength(ret); + const qsizetype drive = drivePrefixLength(ret); return drive > 0 ? QStringView{ret}.left(drive) % fileName : fileName; } #endif // Q_OS_WIN @@ -811,7 +802,7 @@ QString QDir::absoluteFilePath(const QString &fileName) const // Handle the "absolute except for drive" case (i.e. \blah not c:\blah): if (fileName.startsWith(QLatin1Char('/')) || fileName.startsWith(QLatin1Char('\\'))) { // Combine absoluteDirPath's drive with fileName - const int drive = drivePrefixLength(absoluteDirPath); + const qsizetype drive = drivePrefixLength(absoluteDirPath); if (Q_LIKELY(drive)) return QStringView{absoluteDirPath}.left(drive) % fileName; @@ -920,7 +911,7 @@ QString QDir::relativeFilePath(const QString &fileName) const QString QDir::toNativeSeparators(const QString &pathName) { #if defined(Q_OS_WIN) - int i = pathName.indexOf(QLatin1Char('/')); + qsizetype i = pathName.indexOf(u'/'); if (i != -1) { QString n(pathName); @@ -1065,7 +1056,17 @@ void QDir::setNameFilters(const QStringList &nameFilters) d->nameFilters = nameFilters; } -#ifdef QT_BUILD_CORE_LIB +#ifndef QT_BOOTSTRAPPED + +namespace { +struct DirSearchPaths { + mutable QReadWriteLock mutex; + QHash<QString, QStringList> paths; +}; +} + +Q_GLOBAL_STATIC(DirSearchPaths, dirSearchPaths) + /*! \since 4.3 @@ -1093,19 +1094,19 @@ void QDir::setSearchPaths(const QString &prefix, const QStringList &searchPaths) return; } - for (int i = 0; i < prefix.count(); ++i) { - if (!prefix.at(i).isLetterOrNumber()) { + for (QChar ch : prefix) { + if (!ch.isLetterOrNumber()) { qWarning("QDir::setSearchPaths: Prefix can only contain letters or numbers"); return; } } - QWriteLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock); - QMap<QString, QStringList> &paths = QCoreGlobalData::instance()->dirSearchPaths; + DirSearchPaths &conf = *dirSearchPaths; + const QWriteLocker lock(&conf.mutex); if (searchPaths.isEmpty()) { - paths.remove(prefix); + conf.paths.remove(prefix); } else { - paths.insert(prefix, searchPaths); + conf.paths.insert(prefix, searchPaths); } } @@ -1121,8 +1122,9 @@ void QDir::addSearchPath(const QString &prefix, const QString &path) if (path.isEmpty()) return; - QWriteLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock); - QCoreGlobalData::instance()->dirSearchPaths[prefix] += path; + DirSearchPaths &conf = *dirSearchPaths; + const QWriteLocker lock(&conf.mutex); + conf.paths[prefix] += path; } /*! @@ -1134,11 +1136,15 @@ void QDir::addSearchPath(const QString &prefix, const QString &path) */ QStringList QDir::searchPaths(const QString &prefix) { - QReadLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock); - return QCoreGlobalData::instance()->dirSearchPaths.value(prefix); + if (!dirSearchPaths.exists()) + return QStringList(); + + const DirSearchPaths &conf = *dirSearchPaths; + const QReadLocker lock(&conf.mutex); + return conf.paths.value(prefix); } -#endif // QT_BUILD_CORE_LIB +#endif // QT_BOOTSTRAPPED /*! Returns the value set by setFilter() @@ -2136,7 +2142,7 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza { const bool allowUncPaths = flags.testAnyFlag(QDirPrivate::AllowUncPaths); const bool isRemote = flags.testAnyFlag(QDirPrivate::RemotePath); - const int len = name.length(); + const qsizetype len = name.size(); if (ok) *ok = false; @@ -2144,15 +2150,15 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza if (len == 0) return name; - int i = len - 1; + qsizetype i = len - 1; QVarLengthArray<char16_t> outVector(len); - int used = len; + qsizetype used = len; char16_t *out = outVector.data(); const ushort *p = name.utf16(); const ushort *prefix = p; - int up = 0; + qsizetype up = 0; - const int prefixLength = rootLength(name, allowUncPaths); + const qsizetype prefixLength = rootLength(name, allowUncPaths); p += prefixLength; i -= prefixLength; @@ -2163,10 +2169,10 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza --i; } - auto isDot = [](const ushort *p, int i) { + auto isDot = [](const ushort *p, qsizetype i) { return i > 1 && p[i - 1] == '.' && p[i - 2] == '/'; }; - auto isDotDot = [](const ushort *p, int i) { + auto isDotDot = [](const ushort *p, qsizetype i) { return i > 2 && p[i - 1] == '.' && p[i - 2] == '.' && p[i - 3] == '/'; }; @@ -2269,7 +2275,7 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza // string only consists of a prefix followed by one or more slashes. Just skip the slash. ++used; } - for (int i = prefixLength - 1; i >= 0; --i) + for (qsizetype i = prefixLength - 1; i >= 0; --i) out[--used] = prefix[i]; } else { if (isEmpty) { |