summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qdir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qdir.cpp')
-rw-r--r--src/corelib/io/qdir.cpp399
1 files changed, 233 insertions, 166 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index b54ae214b0..05947f3380 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -9,7 +9,7 @@
#ifndef QT_NO_DEBUG_STREAM
#include "qdebug.h"
#endif
-#include "qdiriterator.h"
+#include "qdirlisting.h"
#include "qdatetime.h"
#include "qstring.h"
#if QT_CONFIG(regularexpression)
@@ -22,7 +22,9 @@
#include <qstringbuilder.h>
#ifndef QT_BOOTSTRAPPED
-# include "qreadwritelock.h"
+# include <qcollator.h>
+# include "qreadwritelock.h"
+# include "qmutex.h"
#endif
#include <algorithm>
@@ -77,12 +79,9 @@ static qsizetype rootLength(QStringView name, bool allowUncPaths)
}
//************* QDirPrivate
-QDirPrivate::QDirPrivate(const QString &path, const QStringList &nameFilters_, QDir::SortFlags sort_, QDir::Filters filters_)
- : QSharedData()
- , fileListsInitialized(false)
- , nameFilters(nameFilters_)
- , sort(sort_)
- , filters(filters_)
+QDirPrivate::QDirPrivate(const QString &path, const QStringList &nameFilters_,
+ QDir::SortFlags sort_, QDir::Filters filters_)
+ : QSharedData(), nameFilters(nameFilters_), sort(sort_), filters(filters_)
{
setPath(path.isEmpty() ? QString::fromLatin1(".") : path);
@@ -93,22 +92,31 @@ QDirPrivate::QDirPrivate(const QString &path, const QStringList &nameFilters_, Q
}
QDirPrivate::QDirPrivate(const QDirPrivate &copy)
- : QSharedData(copy)
- , fileListsInitialized(false)
- , nameFilters(copy.nameFilters)
- , sort(copy.sort)
- , filters(copy.filters)
- , dirEntry(copy.dirEntry)
- , metaData(copy.metaData)
-{
+ : QSharedData(copy),
+ // mutex is not copied
+ nameFilters(copy.nameFilters),
+ sort(copy.sort),
+ filters(copy.filters),
+ // fileEngine is not copied
+ dirEntry(copy.dirEntry)
+{
+ QMutexLocker locker(&copy.fileCache.mutex);
+ fileCache.fileListsInitialized = copy.fileCache.fileListsInitialized.load();
+ fileCache.files = copy.fileCache.files;
+ fileCache.fileInfos = copy.fileCache.fileInfos;
+ fileCache.absoluteDirEntry = copy.fileCache.absoluteDirEntry;
+ fileCache.metaData = copy.fileCache.metaData;
}
bool QDirPrivate::exists() const
{
if (!fileEngine) {
- QFileSystemEngine::fillMetaData(dirEntry, metaData,
- QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); // always stat
- return metaData.exists() && metaData.isDirectory();
+ QMutexLocker locker(&fileCache.mutex);
+ QFileSystemEngine::fillMetaData(
+ dirEntry, fileCache.metaData,
+ QFileSystemMetaData::ExistsAttribute
+ | QFileSystemMetaData::DirectoryType); // always stat
+ return fileCache.metaData.exists() && fileCache.metaData.isDirectory();
}
const QAbstractFileEngine::FileFlags info =
fileEngine->fileFlags(QAbstractFileEngine::DirectoryType
@@ -151,56 +159,89 @@ inline void QDirPrivate::setPath(const QString &path)
) {
p.truncate(p.size() - 1);
}
-
dirEntry = QFileSystemEntry(p, QFileSystemEntry::FromInternalPath());
- metaData.clear();
- initFileEngine();
- clearFileLists();
- absoluteDirEntry = QFileSystemEntry();
+ clearCache(IncludingMetaData);
+ fileCache.absoluteDirEntry = QFileSystemEntry();
}
-inline void QDirPrivate::clearFileLists()
+inline QString QDirPrivate::resolveAbsoluteEntry() const
{
- fileListsInitialized = false;
- files.clear();
- fileInfos.clear();
-}
+ QMutexLocker locker(&fileCache.mutex);
+ if (!fileCache.absoluteDirEntry.isEmpty())
+ return fileCache.absoluteDirEntry.filePath();
-inline void QDirPrivate::resolveAbsoluteEntry() const
-{
- if (!absoluteDirEntry.isEmpty() || dirEntry.isEmpty())
- return;
+ if (dirEntry.isEmpty())
+ return dirEntry.filePath();
QString absoluteName;
if (!fileEngine) {
if (!dirEntry.isRelative() && dirEntry.isClean()) {
- absoluteDirEntry = dirEntry;
- return;
+ fileCache.absoluteDirEntry = dirEntry;
+ return dirEntry.filePath();
}
absoluteName = QFileSystemEngine::absoluteName(dirEntry).filePath();
} else {
absoluteName = fileEngine->fileName(QAbstractFileEngine::AbsoluteName);
}
-
- absoluteDirEntry = QFileSystemEntry(QDir::cleanPath(absoluteName), QFileSystemEntry::FromInternalPath());
+ auto absoluteFileSystemEntry =
+ QFileSystemEntry(QDir::cleanPath(absoluteName), QFileSystemEntry::FromInternalPath());
+ fileCache.absoluteDirEntry = absoluteFileSystemEntry;
+ return absoluteFileSystemEntry.filePath();
}
/* For sorting */
struct QDirSortItem
{
+ QDirSortItem() = default;
+ QDirSortItem(const QFileInfo &fi, QDir::SortFlags sort)
+ : item(fi)
+ {
+ // A dir e.g. "dirA.bar" doesn't have actually have an extension/suffix, when
+ // sorting by type such "suffix" should be ignored but that would complicate
+ // the code and uses can change the behavior by setting DirsFirst/DirsLast
+ if (sort.testAnyFlag(QDir::Type))
+ suffix_cache = item.suffix();
+ }
+
mutable QString filename_cache;
- mutable QString suffix_cache;
+ QString suffix_cache;
QFileInfo item;
};
-
class QDirSortItemComparator
{
QDir::SortFlags qt_cmp_si_sort_flags;
+
+#ifndef QT_BOOTSTRAPPED
+ QCollator *collator = nullptr;
+#endif
public:
- QDirSortItemComparator(QDir::SortFlags flags) : qt_cmp_si_sort_flags(flags) {}
+#ifndef QT_BOOTSTRAPPED
+ QDirSortItemComparator(QDir::SortFlags flags, QCollator *coll = nullptr)
+ : qt_cmp_si_sort_flags(flags), collator(coll)
+ {
+ Q_ASSERT(!qt_cmp_si_sort_flags.testAnyFlag(QDir::LocaleAware) || collator);
+
+ if (collator && qt_cmp_si_sort_flags.testAnyFlag(QDir::IgnoreCase))
+ collator->setCaseSensitivity(Qt::CaseInsensitive);
+ }
+#else
+ QDirSortItemComparator(QDir::SortFlags flags)
+ : qt_cmp_si_sort_flags(flags)
+ {
+ }
+#endif
bool operator()(const QDirSortItem &, const QDirSortItem &) const;
+
+ int compareStrings(const QString &a, const QString &b, Qt::CaseSensitivity cs) const
+ {
+#ifndef QT_BOOTSTRAPPED
+ if (collator)
+ return collator->compare(a, b);
+#endif
+ return a.compare(b, cs);
+ }
};
bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortItem &n2) const
@@ -213,43 +254,25 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt
if ((qt_cmp_si_sort_flags & QDir::DirsLast) && (f1->item.isDir() != f2->item.isDir()))
return !f1->item.isDir();
+ const bool ic = qt_cmp_si_sort_flags.testAnyFlag(QDir::IgnoreCase);
+ const auto qtcase = ic ? Qt::CaseInsensitive : Qt::CaseSensitive;
+
qint64 r = 0;
int sortBy = ((qt_cmp_si_sort_flags & QDir::SortByMask)
| (qt_cmp_si_sort_flags & QDir::Type)).toInt();
switch (sortBy) {
case QDir::Time: {
- QDateTime firstModified = f1->item.lastModified();
- QDateTime secondModified = f2->item.lastModified();
-
- // QDateTime by default will do all sorts of conversions on these to
- // find timezones, which is incredibly expensive. As we aren't
- // presenting these to the user, we don't care (at all) about the
- // local timezone, so force them to UTC to avoid that conversion.
- firstModified.setTimeSpec(Qt::UTC);
- secondModified.setTimeSpec(Qt::UTC);
-
+ const QDateTime firstModified = f1->item.lastModified(QTimeZone::UTC);
+ const QDateTime secondModified = f2->item.lastModified(QTimeZone::UTC);
r = firstModified.msecsTo(secondModified);
break;
}
case QDir::Size:
r = f2->item.size() - f1->item.size();
break;
- case QDir::Type:
- {
- bool ic = qt_cmp_si_sort_flags.testAnyFlag(QDir::IgnoreCase);
-
- if (f1->suffix_cache.isNull())
- f1->suffix_cache = ic ? f1->item.suffix().toLower()
- : f1->item.suffix();
- if (f2->suffix_cache.isNull())
- f2->suffix_cache = ic ? f2->item.suffix().toLower()
- : f2->item.suffix();
-
- r = qt_cmp_si_sort_flags & QDir::LocaleAware
- ? f1->suffix_cache.localeAwareCompare(f2->suffix_cache)
- : f1->suffix_cache.compare(f2->suffix_cache);
- }
+ case QDir::Type:
+ r = compareStrings(f1->suffix_cache, f2->suffix_cache, qtcase);
break;
default:
;
@@ -257,18 +280,13 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt
if (r == 0 && sortBy != QDir::Unsorted) {
// Still not sorted - sort by name
- bool ic = qt_cmp_si_sort_flags.testAnyFlag(QDir::IgnoreCase);
if (f1->filename_cache.isNull())
- f1->filename_cache = ic ? f1->item.fileName().toLower()
- : f1->item.fileName();
+ f1->filename_cache = f1->item.fileName();
if (f2->filename_cache.isNull())
- f2->filename_cache = ic ? f2->item.fileName().toLower()
- : f2->item.fileName();
+ f2->filename_cache = f2->item.fileName();
- r = qt_cmp_si_sort_flags & QDir::LocaleAware
- ? f1->filename_cache.localeAwareCompare(f2->filename_cache)
- : f1->filename_cache.compare(f2->filename_cache);
+ r = compareStrings(f1->filename_cache, f2->filename_cache, qtcase);
}
if (qt_cmp_si_sort_flags & QDir::Reversed)
return r > 0;
@@ -278,48 +296,74 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt
inline void QDirPrivate::sortFileList(QDir::SortFlags sort, const QFileInfoList &l,
QStringList *names, QFileInfoList *infos)
{
- // names and infos are always empty lists or 0 here
- qsizetype n = l.size();
- if (n > 0) {
- if (n == 1 || (sort & QDir::SortByMask) == QDir::Unsorted) {
- if (infos)
- *infos = l;
- if (names) {
- for (const QFileInfo &fi : l)
- names->append(fi.fileName());
- }
+ Q_ASSERT(names || infos);
+ Q_ASSERT(!infos || infos->isEmpty());
+ Q_ASSERT(!names || names->isEmpty());
+
+ const qsizetype n = l.size();
+ if (n == 0)
+ return;
+
+ if (n == 1 || (sort & QDir::SortByMask) == QDir::Unsorted) {
+ if (infos)
+ *infos = l;
+
+ if (names) {
+ for (const QFileInfo &fi : l)
+ names->append(fi.fileName());
+ }
+ } else {
+ QVarLengthArray<QDirSortItem, 64> si;
+ si.reserve(n);
+ for (qsizetype i = 0; i < n; ++i)
+ si.emplace_back(l.at(i), sort);
+
+#ifndef QT_BOOTSTRAPPED
+ if (sort.testAnyFlag(QDir::LocaleAware)) {
+ QCollator coll;
+ std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort, &coll));
} else {
- QScopedArrayPointer<QDirSortItem> si(new QDirSortItem[n]);
- 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 (qsizetype i = 0; i < n; ++i)
- infos->append(si[i].item);
- }
+ }
+#else
+ std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort));
+#endif // QT_BOOTSTRAPPED
+
+ // put them back in the list(s)
+ for (qsizetype i = 0; i < n; ++i) {
+ auto &fileInfo = si[i].item;
+ if (infos)
+ infos->append(fileInfo);
if (names) {
- for (qsizetype i = 0; i < n; ++i)
- names->append(si[i].item.fileName());
+ const bool cached = !si[i].filename_cache.isNull();
+ names->append(cached ? si[i].filename_cache : fileInfo.fileName());
}
}
}
}
+
inline void QDirPrivate::initFileLists(const QDir &dir) const
{
- if (!fileListsInitialized) {
+ QMutexLocker locker(&fileCache.mutex);
+ if (!fileCache.fileListsInitialized) {
QFileInfoList l;
- QDirIterator it(dir);
- while (it.hasNext())
- l.append(it.nextFileInfo());
- sortFileList(sort, l, &files, &fileInfos);
- fileListsInitialized = true;
+ for (const auto &dirEntry : QDirListing(dir))
+ l.emplace_back(dirEntry.fileInfo());
+
+ sortFileList(sort, l, &fileCache.files, &fileCache.fileInfos);
+ fileCache.fileListsInitialized = true;
}
}
-inline void QDirPrivate::initFileEngine()
+inline void QDirPrivate::clearCache(MetaDataClearing mode)
{
- fileEngine.reset(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(dirEntry, metaData));
+ QMutexLocker locker(&fileCache.mutex);
+ if (mode == IncludingMetaData)
+ fileCache.metaData.clear();
+ fileCache.fileListsInitialized = false;
+ fileCache.files.clear();
+ fileCache.fileInfos.clear();
+ fileEngine = QFileSystemEngine::createLegacyEngine(dirEntry, fileCache.metaData);
}
/*!
@@ -331,6 +375,7 @@ inline void QDirPrivate::initFileEngine()
\ingroup shared
\reentrant
+ \compares equality
A QDir is used to manipulate path names, access information
regarding paths and files, and manipulate the underlying file
@@ -498,7 +543,12 @@ inline void QDirPrivate::initFileEngine()
\snippet qdir-listfiles/main.cpp 0
- \sa QFileInfo, QFile, QFileDialog, QCoreApplication::applicationDirPath(), {Find Files Example}
+ \section1 Platform Specific Issues
+
+ \include android-content-uri-limitations.qdocinc
+
+ \sa QFileInfo, QFile, QFileDialog, QCoreApplication::applicationDirPath(),
+ {Fetch More Example}
*/
/*!
@@ -617,8 +667,10 @@ QString QDir::path() const
QString QDir::absolutePath() const
{
Q_D(const QDir);
- d->resolveAbsoluteEntry();
- return d->absoluteDirEntry.filePath();
+ if (!d->fileEngine)
+ return d->resolveAbsoluteEntry();
+
+ return d->fileEngine->fileName(QAbstractFileEngine::AbsoluteName);
}
/*!
@@ -641,7 +693,9 @@ QString QDir::canonicalPath() const
{
Q_D(const QDir);
if (!d->fileEngine) {
- QFileSystemEntry answer = QFileSystemEngine::canonicalName(d->dirEntry, d->metaData);
+ QMutexLocker locker(&d->fileCache.mutex);
+ QFileSystemEntry answer =
+ QFileSystemEngine::canonicalName(d->dirEntry, d->fileCache.metaData);
return answer.filePath();
}
return d->fileEngine->fileName(QAbstractFileEngine::CanonicalName);
@@ -661,7 +715,9 @@ QString QDir::canonicalPath() const
QString QDir::dirName() const
{
Q_D(const QDir);
- return d->dirEntry.fileName();
+ if (!d_ptr->fileEngine)
+ return d->dirEntry.fileName();
+ return d->fileEngine->fileName(QAbstractFileEngine::BaseName);
}
@@ -756,8 +812,7 @@ QString QDir::absoluteFilePath(const QString &fileName) const
return fileName;
Q_D(const QDir);
- d->resolveAbsoluteEntry();
- const QString absoluteDirPath = d->absoluteDirEntry.filePath();
+ QString absoluteDirPath = d->resolveAbsoluteEntry();
if (fileName.isEmpty())
return absoluteDirPath;
#ifdef Q_OS_WIN
@@ -979,6 +1034,9 @@ bool QDir::cd(const QString &dirName)
otherwise returns \c false. Note that the logical cdUp() operation is
not performed if the new directory does not exist.
+ \note On Android, this is not supported for content URIs. For more information,
+ see \l {Android: DocumentFile.getParentFile()}{DocumentFile.getParentFile()}.
+
\sa cd(), isReadable(), exists(), path()
*/
bool QDir::cdUp()
@@ -1013,9 +1071,7 @@ QStringList QDir::nameFilters() const
void QDir::setNameFilters(const QStringList &nameFilters)
{
Q_D(QDir);
- d->initFileEngine();
- d->clearFileLists();
-
+ d->clearCache(QDirPrivate::KeepMetaData);
d->nameFilters = nameFilters;
}
@@ -1194,9 +1250,7 @@ QDir::Filters QDir::filter() const
void QDir::setFilter(Filters filters)
{
Q_D(QDir);
- d->initFileEngine();
- d->clearFileLists();
-
+ d->clearCache(QDirPrivate::KeepMetaData);
d->filters = filters;
}
@@ -1240,6 +1294,7 @@ QDir::SortFlags QDir::sorting() const
after the directories, again in reverse order.
*/
+#ifndef QT_BOOTSTRAPPED
/*!
Sets the sort order used by entryList() and entryInfoList().
@@ -1251,9 +1306,7 @@ QDir::SortFlags QDir::sorting() const
void QDir::setSorting(SortFlags sort)
{
Q_D(QDir);
- d->initFileEngine();
- d->clearFileLists();
-
+ d->clearCache(QDirPrivate::KeepMetaData);
d->sort = sort;
}
@@ -1271,7 +1324,7 @@ qsizetype QDir::count(QT6_IMPL_NEW_OVERLOAD) const
{
Q_D(const QDir);
d->initFileLists(*this);
- return d->files.size();
+ return d->fileCache.files.size();
}
/*!
@@ -1287,7 +1340,7 @@ QString QDir::operator[](qsizetype pos) const
{
Q_D(const QDir);
d->initFileLists(*this);
- return d->files[pos];
+ return d->fileCache.files[pos];
}
/*!
@@ -1364,17 +1417,27 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters,
if (sort == NoSort)
sort = d->sort;
+ const bool needsSorting = (sort & QDir::SortByMask) != QDir::Unsorted;
+
if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) {
- d->initFileLists(*this);
- return d->files;
+ // Don't fill a QFileInfo cache if we just need names
+ if (needsSorting || d->fileCache.fileListsInitialized) {
+ d->initFileLists(*this);
+ return d->fileCache.files;
+ }
}
- QFileInfoList l;
- QDirIterator it(d->dirEntry.filePath(), nameFilters, filters);
- while (it.hasNext())
- l.append(it.nextFileInfo());
+ QDirListing dirList(d->dirEntry.filePath(), nameFilters, filters);
QStringList ret;
- d->sortFileList(sort, l, &ret, nullptr);
+ if (needsSorting) {
+ QFileInfoList l;
+ for (const auto &dirEntry : dirList)
+ l.emplace_back(dirEntry.fileInfo());
+ d->sortFileList(sort, l, &ret, nullptr);
+ } else {
+ for (const auto &dirEntry : dirList)
+ ret.emplace_back(dirEntry.fileName());
+ }
return ret;
}
@@ -1406,17 +1469,17 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter
if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) {
d->initFileLists(*this);
- return d->fileInfos;
+ return d->fileCache.fileInfos;
}
QFileInfoList l;
- QDirIterator it(d->dirEntry.filePath(), nameFilters, filters);
- while (it.hasNext())
- l.append(it.nextFileInfo());
+ for (const auto &dirEntry : QDirListing(d->dirEntry.filePath(), nameFilters, filters))
+ l.emplace_back(dirEntry.fileInfo());
QFileInfoList ret;
d->sortFileList(sort, l, nullptr, &ret);
return ret;
}
+#endif // !QT_BOOTSTRAPPED
/*!
Creates a sub-directory called \a dirName.
@@ -1553,6 +1616,7 @@ bool QDir::rmpath(const QString &dirPath) const
return d->fileEngine->rmdir(fn, true);
}
+#ifndef QT_BOOTSTRAPPED
/*!
\since 5.0
Removes the directory, including all its contents.
@@ -1581,12 +1645,11 @@ bool QDir::removeRecursively()
bool success = true;
const QString dirPath = path();
// not empty -- we must empty it first
- QDirIterator di(dirPath, QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot);
- while (di.hasNext()) {
- const QFileInfo fi = di.nextFileInfo();
- const QString &filePath = di.filePath();
+ constexpr auto dirFilters = QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot;
+ for (const auto &dirEntry : QDirListing(dirPath, dirFilters)) {
+ const QString &filePath = dirEntry.filePath();
bool ok;
- if (fi.isDir() && !fi.isSymLink()) {
+ if (dirEntry.isDir() && !dirEntry.isSymLink()) {
ok = QDir(filePath).removeRecursively(); // recursive
} else {
ok = QFile::remove(filePath);
@@ -1606,6 +1669,7 @@ bool QDir::removeRecursively()
return success;
}
+#endif // !QT_BOOTSTRAPPED
/*!
Returns \c true if the directory is readable \e and we can open files
@@ -1621,10 +1685,12 @@ bool QDir::isReadable() const
Q_D(const QDir);
if (!d->fileEngine) {
- if (!d->metaData.hasFlags(QFileSystemMetaData::UserReadPermission))
- QFileSystemEngine::fillMetaData(d->dirEntry, d->metaData, QFileSystemMetaData::UserReadPermission);
-
- return d->metaData.permissions().testAnyFlag(QFile::ReadUser);
+ QMutexLocker locker(&d->fileCache.mutex);
+ if (!d->fileCache.metaData.hasFlags(QFileSystemMetaData::UserReadPermission)) {
+ QFileSystemEngine::fillMetaData(d->dirEntry, d->fileCache.metaData,
+ QFileSystemMetaData::UserReadPermission);
+ }
+ return d->fileCache.metaData.permissions().testAnyFlag(QFile::ReadUser);
}
const QAbstractFileEngine::FileFlags info =
@@ -1731,16 +1797,18 @@ bool QDir::makeAbsolute()
dir.reset(new QDirPrivate(*d_ptr.constData()));
dir->setPath(absolutePath);
} else { // native FS
- d->resolveAbsoluteEntry();
+ QString absoluteFilePath = d->resolveAbsoluteEntry();
dir.reset(new QDirPrivate(*d_ptr.constData()));
- dir->setPath(d->absoluteDirEntry.filePath());
+ dir->setPath(absoluteFilePath);
}
d_ptr = dir.release(); // actually detach
return true;
}
/*!
- Returns \c true if directory \a dir and this directory have the same
+ \fn bool QDir::operator==(const QDir &lhs, const QDir &rhs)
+
+ Returns \c true if directory \a lhs and directory \a rhs have the same
path and their sort and filter settings are the same; otherwise
returns \c false.
@@ -1748,10 +1816,10 @@ bool QDir::makeAbsolute()
\snippet code/src_corelib_io_qdir.cpp 10
*/
-bool QDir::operator==(const QDir &dir) const
+bool comparesEqual(const QDir &lhs, const QDir &rhs)
{
- Q_D(const QDir);
- const QDirPrivate *other = dir.d_ptr.constData();
+ const QDirPrivate *d = lhs.d_ptr.constData();
+ const QDirPrivate *other = rhs.d_ptr.constData();
if (d == other)
return true;
@@ -1775,18 +1843,18 @@ bool QDir::operator==(const QDir &dir) const
if (d->dirEntry.filePath() == other->dirEntry.filePath())
return true;
- if (exists()) {
- if (!dir.exists())
+ if (lhs.exists()) {
+ if (!rhs.exists())
return false; //can't be equal if only one exists
// Both exist, fallback to expensive canonical path computation
- return canonicalPath().compare(dir.canonicalPath(), sensitive) == 0;
+ return lhs.canonicalPath().compare(rhs.canonicalPath(), sensitive) == 0;
} else {
- if (dir.exists())
+ if (rhs.exists())
return false; //can't be equal if only one exists
// Neither exists, compare absolute paths rather than canonical (which would be empty strings)
- d->resolveAbsoluteEntry();
- other->resolveAbsoluteEntry();
- return d->absoluteDirEntry.filePath().compare(other->absoluteDirEntry.filePath(), sensitive) == 0;
+ QString thisFilePath = d->resolveAbsoluteEntry();
+ QString otherFilePath = other->resolveAbsoluteEntry();
+ return thisFilePath.compare(otherFilePath, sensitive) == 0;
}
}
return false;
@@ -1811,11 +1879,10 @@ QDir &QDir::operator=(const QDir &dir)
*/
/*!
- \fn bool QDir::operator!=(const QDir &dir) const
+ \fn bool QDir::operator!=(const QDir &lhs, const QDir &rhs)
- Returns \c true if directory \a dir and this directory have different
- paths or different sort or filter settings; otherwise returns
- false.
+ Returns \c true if directory \a lhs and directory \a rhs have different
+ paths or different sort or filter settings; otherwise returns \c false.
Example:
@@ -1885,6 +1952,7 @@ bool QDir::exists(const QString &name) const
return QFileInfo::exists(filePath(name));
}
+#ifndef QT_BOOTSTRAPPED
/*!
Returns whether the directory is empty.
@@ -1901,9 +1969,10 @@ bool QDir::exists(const QString &name) const
bool QDir::isEmpty(Filters filters) const
{
Q_D(const QDir);
- QDirIterator it(d->dirEntry.filePath(), d->nameFilters, filters);
- return !it.hasNext();
+ QDirListing dirList(d->dirEntry.filePath(), d->nameFilters, filters);
+ return dirList.cbegin() == dirList.cend();
}
+#endif // !QT_BOOTSTRAPPED
/*!
Returns a list of the root directories on this system.
@@ -2151,8 +2220,8 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza
QVarLengthArray<char16_t> outVector(len);
qsizetype used = len;
char16_t *out = outVector.data();
- const ushort *p = reinterpret_cast<const ushort *>(name.data());
- const ushort *prefix = p;
+ const char16_t *p = reinterpret_cast<const char16_t *>(name.data());
+ const char16_t *prefix = p;
qsizetype up = 0;
const qsizetype prefixLength = rootLength(name, allowUncPaths);
@@ -2166,10 +2235,10 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza
--i;
}
- auto isDot = [](const ushort *p, qsizetype i) {
+ auto isDot = [](const char16_t *p, qsizetype i) {
return i > 1 && p[i - 1] == '.' && p[i - 2] == '/';
};
- auto isDotDot = [](const ushort *p, qsizetype i) {
+ auto isDotDot = [](const char16_t *p, qsizetype i) {
return i > 2 && p[i - 1] == '.' && p[i - 2] == '.' && p[i - 3] == '/';
};
@@ -2290,7 +2359,7 @@ QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormaliza
// If path was not modified return the original value
if (used == 0)
return name;
- return QString::fromUtf16(out + used, len - used);
+ return QStringView(out + used, len - used).toString();
}
static QString qt_cleanPath(const QString &path, bool *ok)
@@ -2351,9 +2420,7 @@ bool QDir::isRelativePath(const QString &path)
void QDir::refresh() const
{
QDirPrivate *d = const_cast<QDir *>(this)->d_func();
- d->metaData.clear();
- d->initFileEngine();
- d->clearFileLists();
+ d->clearCache(QDirPrivate::IncludingMetaData);
}
/*!