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
qdirlisting.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2024 Ahmad Samir <a.samirh78@gmail.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6/*!
7 \since 6.8
8 \class QDirListing
9 \inmodule QtCore
10 \ingroup io
11 \brief The QDirListing class provides an STL-style iterator for directory entries.
12
13 You can use QDirListing to navigate entries of a directory one at a time.
14 It is similar to QDir::entryList() and QDir::entryInfoList(), but because
15 it lists entries one at a time instead of all at once, it scales better
16 and is more suitable for large directories. It also supports listing
17 directory contents recursively, and following symbolic links. Unlike
18 QDir::entryList(), QDirListing does not support sorting.
19
20 The QDirListing constructor takes a directory path string as
21 argument. Here's how to iterate over all entries recursively:
22
23 \snippet code/src_corelib_io_qdirlisting.cpp 0
24
25 Here's how to find and read all regular files filtered by name, recursively:
26
27 \snippet code/src_corelib_io_qdirlisting.cpp 1
28
29 Here's how to list only regular files, recursively:
30 \snippet code/src_corelib_io_qdirlisting.cpp 5
31
32 Here's how to list only regular files and symbolic links to regular
33 files, recursively:
34 \snippet code/src_corelib_io_qdirlisting.cpp 6
35
36//! [std-input-iterator-tag]
37 QDirListing::const_iterator models C++20
38 \l{https://en.cppreference.com/w/cpp/iterator/input_iterator}{std::input_iterator},
39 that is, it is a move-only, forward-only, single-pass iterator, that
40 doesn't allow random access.
41//! [std-input-iterator-tag]
42 It can be used in ranged-for loops (or with C++20 range algorithms that don't
43 require random access iterators). Dereferencing a valid iterator returns
44 a QDirListing::DirEntry object. The (c)end() sentinel marks the end of
45 the iteration. Dereferencing an iterator that is equal to \l{sentinel} is
46 undefined behavior.
47
48 QDirListing::DirEntry offers a subset of QFileInfo's API (for example,
49 fileName(), filePath(), exists()). Internally, DirEntry only constructs
50 a QFileInfo object if needed, that is, if the info hasn't been already
51 fetched by other system functions. You can use DirEntry::fileInfo()
52 to get a QFileInfo. For example:
53
54 \snippet code/src_corelib_io_qdirlisting.cpp 3
55 \snippet code/src_corelib_io_qdirlisting.cpp 4
56
57 \sa QDir, QDir::entryList()
58*/
59
60/*! \enum QDirListing::IteratorFlag
61
62 This enum class describes flags that can be used to configure the behavior
63 of QDirListing. Values from this enumerator can be bitwise OR'ed together.
64
65 \value Default
66 List all entries, that is, files, directories, symbolic links including broken
67 symbolic links (where the target doesn't exist) and special (\e other) system
68 files, see ExcludeOther for details.
69 Hidden files and directories and the special entries \c{.} and \c{..}
70 aren't listed by default.
71
72 \value ExcludeFiles
73 Don't list regular files. When combined with ResolveSymlinks, symbolic
74 links to regular files will be excluded too.
75
76 \value ExcludeDirs
77 Don't list directories. When combined with ResolveSymlinks, symbolic
78 links to directories will be excluded too.
79
80 \omitvalue ExcludeSpecial
81 \value ExcludeOther [since 6.10]
82 Don't list file system entries that are \e not directories, regular files,
83 or symbolic links.
84 \list
85 \li On Unix, a special (other) file system entry is a FIFO, socket,
86 character device, or block device. For more details see the
87 \l{https://pubs.opengroup.org/onlinepubs/9699919799/functions/mknod.html}{\c mknod}
88 manual page.
89 \li On Windows (for historical reasons) \c .lnk files are considered
90 special (other) file system entries.
91 \endlist
92
93 \value ResolveSymlinks
94 Filter symbolic links based on the type of the target of the link,
95 rather than the symbolic link itself. Broken symbolic links (where
96 the target doesn't exist) are excluded, set IncludeBrokenSymlinks
97 to include them.
98 This flag is ignored on operating systems that don't support symbolic links.
99
100 \value IncludeBrokenSymlinks [since 6.11]
101 Lists broken symbolic links, where the target doesn't exist, regardless
102 of the status of the ResolveSymlinks flag.
103 This flag is ignored on operating systems that don't support symbolic links.
104
105 \value FilesOnly
106 Only regular files will be listed. When combined with ResolveSymlinks,
107 symbolic links to files will also be listed.
108
109 \value DirsOnly
110 Only directories will be listed. When combined with ResolveSymlinks,
111 symbolic links to directories will also be listed.
112
113 \value IncludeHidden
114 List hidden entries. When combined with Recursive, the iteration will
115 recurse into hidden sub-directories as well.
116
117 \value IncludeDotAndDotDot
118 List the \c {.} and \c{..} special entries.
119
120 \value CaseSensitive
121 The file glob patterns in the name filters passed to the QDirListing
122 constructor, will be matched case sensitively (for details, see
123 QDir::setNameFilters()).
124
125 \value Recursive
126 List entries inside all sub-directories as well. When combined with
127 FollowDirSymlinks, symbolic links to directories will be iterated too.
128
129 \value FollowDirSymlinks
130 When combined with Recursive, symbolic links to directories will be
131 iterated too. Symbolic link loops (e.g., link => . or link => ..) are
132 automatically detected and ignored.
133
134 \omitvalue NoNameFiltersForDirs
135*/
136
137#include "qdirlisting.h"
138#include "qdirentryinfo_p.h"
139
140#include "qdir_p.h"
141#include "qdiriterator.h"
143
144#if QT_CONFIG(regularexpression)
145#include <QtCore/qregularexpression.h>
146#endif
147
148#include <QtCore/private/qfilesystemiterator_p.h>
149#include <QtCore/private/qfilesystementry_p.h>
150#include <QtCore/private/qfilesystemmetadata_p.h>
151#include <QtCore/private/qfilesystemengine_p.h>
152#include <QtCore/private/qfileinfo_p.h>
153#include <QtCore/private/qduplicatetracker_p.h>
154
155#include <memory>
156#include <vector>
157
158QT_BEGIN_NAMESPACE
159
160using namespace Qt::StringLiterals;
161
204
206{
207 if (nameFilters.contains("*"_L1))
208 nameFilters.clear();
209
210#if QT_CONFIG(regularexpression)
211 nameRegExps.reserve(nameFilters.size());
212
213 const bool isCase = iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::CaseSensitive);
214 const auto cs = isCase ? Qt::CaseSensitive : Qt::CaseInsensitive;
215 for (const auto &filter : nameFilters)
216 nameRegExps.emplace_back(QRegularExpression::fromWildcard(filter, cs));
217#endif
218
219 engine = QFileSystemEngine::createLegacyEngine(initialEntryInfo.entry,
220 initialEntryInfo.metaData);
221}
222
223/*!
224 \internal
225
226 Resets the iteration state (if any), so that calling begin()/cbegin()
227 always starts iterating anew.
228*/
230{
231#ifndef QT_NO_FILESYSTEMITERATOR
232 nativeIterators.clear();
233#endif
234 fileEngineIterators.clear();
235 visitedLinks.clear();
236 pushDirectory(initialEntryInfo);
237}
238
240{
241 const QString path = [&entryInfo] {
242#ifdef Q_OS_WIN
243 if (entryInfo.isSymLink())
244 return entryInfo.canonicalFilePath();
245#endif
246 return entryInfo.filePath();
247 }();
248
249
250 if (iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::FollowDirSymlinks)) {
251 // Stop link loops
252 if (visitedLinks.hasSeen(entryInfo.canonicalFilePath()))
253 return;
254 }
255
256 if (engine) {
257 engine->setFileName(path);
258 if (auto it = engine->beginEntryList(path, iteratorFlags, nameFilters)) {
259 fileEngineIterators.emplace_back(std::move(it));
260 } else {
261 // No iterator; no entry list.
262 }
263 } else {
264#ifndef QT_NO_FILESYSTEMITERATOR
265 QFileSystemEntry *fentry = nullptr;
266 if (entryInfo.fileInfoOpt)
267 fentry = &entryInfo.fileInfoOpt->d_ptr->fileEntry;
268 else
269 fentry = &entryInfo.entry;
270 nativeIterators.emplace_back(std::make_unique<QFileSystemIterator>(*fentry, iteratorFlags));
271#else
272 qWarning("Qt was built with -no-feature-filesystemiterator: no files/plugins will be found!");
273#endif
274 }
275}
276
278{
280 return matchesFilters(entryInfo);
281}
282
283/*!
284 \internal
285
286 Advances the internal iterator, either a QAbstractFileEngineIterator (e.g.
287 QResourceFileEngineIterator) or a QFileSystemIterator (which uses low-level
288 system methods, e.g. readdir() on Unix). The iterators are stored in a
289 vector.
290
291 A typical example of doing recursive iteration:
292 - while iterating directory A we find a sub-dir B
293 - an iterator for B is added to the vector
294 - B's iterator is processed (vector.back()) first; then the loop
295 goes back to processing A's iterator
296*/
298{
299 // Use get() in both code paths below because the iterator returned by back()
300 // may be invalidated due to reallocation when appending new iterators in
301 // pushDirectory().
302
303 if (engine) {
304 while (!fileEngineIterators.empty()) {
305 // Find the next valid iterator that matches the filters.
306 QAbstractFileEngineIterator *it;
307 while (it = fileEngineIterators.back().get(), it->advance()) {
308 QDirEntryInfo entryInfo;
309 entryInfo.fileInfoOpt = it->currentFileInfo();
310 if (entryMatches(entryInfo)) {
311 currentEntryInfo = std::move(entryInfo);
312 return;
313 }
314 }
315
316 fileEngineIterators.pop_back();
317 }
318 } else {
319#ifndef QT_NO_FILESYSTEMITERATOR
320 QDirEntryInfo entryInfo;
321 while (!nativeIterators.empty()) {
322 // Find the next valid iterator that matches the filters.
323 QFileSystemIterator *it;
324 while (it = nativeIterators.back().get(),
325 it->advance(entryInfo.entry, entryInfo.metaData)) {
326 if (entryMatches(entryInfo)) {
327 currentEntryInfo = std::move(entryInfo);
328 return;
329 }
330 entryInfo = {};
331 }
332
333 nativeIterators.pop_back();
334 }
335#endif
336 }
337}
338
339static bool isDotOrDotDot(QStringView fileName)
340{
341 return fileName == "."_L1 || fileName == ".."_L1;
342}
343
345{
346 using F = QDirListing::IteratorFlag;
347 // If we're doing flat iteration, we're done.
348 if (!iteratorFlags.testAnyFlags(F::Recursive))
349 return;
350
351 // Follow symlinks only when asked
352 if (!iteratorFlags.testAnyFlags(F::FollowDirSymlinks) && entryInfo.isSymLink())
353 return;
354
355 // Never follow . and ..
356 if (isDotOrDotDot(entryInfo.fileName()))
357 return;
358
359 // No hidden directories unless requested
360 const bool includeHidden = iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::IncludeHidden);
361 if (!includeHidden && entryInfo.isHidden())
362 return;
363
364 // Never follow non-directory entries
365 if (!entryInfo.isDir())
366 return;
367
368 pushDirectory(entryInfo);
369}
370
371/*!
372 \internal
373
374 This function returns \c true if the current entry matches the filters
375 (i.e., the current entry will be returned as part of the directory
376 iteration); otherwise, \c false is returned.
377*/
379{
380 using F = QDirListing::IteratorFlag;
381
382 const QString &fileName = entryInfo.fileName();
383 if (fileName.isEmpty())
384 return false;
385
386 // name filter
387#if QT_CONFIG(regularexpression)
388 const bool skipNameFilters = iteratorFlags.testAnyFlags(F::NoNameFiltersForDirs)
389 && entryInfo.isDir();
390 if (!skipNameFilters) {
391 if (!regexMatchesName(fileName))
392 return false;
393 }
394#endif // QT_CONFIG(regularexpression)
395
396 if (isDotOrDotDot(fileName))
397 return iteratorFlags.testFlags(F::IncludeDotAndDotDot);
398
399 if (!iteratorFlags.testAnyFlag(F::IncludeHidden) && entryInfo.isHidden())
400 return false;
401
402 const bool includeBrokenSymlinks = iteratorFlags.testAnyFlags(F::IncludeBrokenSymlinks);
403 if (includeBrokenSymlinks && entryInfo.isSymLink() && !entryInfo.exists())
404 return true;
405
406 if (iteratorFlags.testFlag(F::ResolveSymlinks)) {
407 if (entryInfo.isSymLink() && !entryInfo.exists())
408 return false; // Exclude broken symlinks; anything else will be filtered below
409 } else {
410 constexpr auto f = F::ExcludeFiles | F::ExcludeDirs | F::ExcludeOther;
411 const bool filterByTargetType = iteratorFlags.testAnyFlags(f);
412 if (filterByTargetType && entryInfo.isSymLink())
413 return false;
414 }
415
416 if (iteratorFlags.testAnyFlag(F::ExcludeOther)
417 && !entryInfo.isFile() && !entryInfo.isDir() && !entryInfo.isSymLink()) {
418 return false;
419 }
420
421 if (iteratorFlags.testAnyFlags(F::ExcludeDirs) && entryInfo.isDir())
422 return false;
423
424 if (iteratorFlags.testAnyFlags(F::ExcludeFiles) && entryInfo.isFile())
425 return false;
426
427 return true;
428}
429
431{
432 if (engine)
433 return !fileEngineIterators.empty();
434
435#if !defined(QT_NO_FILESYSTEMITERATOR)
436 return !nativeIterators.empty();
437#endif
438
439 return false;
440}
441
442/*!
443 Constructs a QDirListing that can iterate over \a path.
444
445 You can pass options via \a flags to control how the directory should
446 be iterated.
447
448 By default, \a flags is IteratorFlag::Default.
449
450 \sa IteratorFlags
451*/
452QDirListing::QDirListing(const QString &path, IteratorFlags flags)
453 : d(new QDirListingPrivate)
454{
455 d->initialEntryInfo.entry = QFileSystemEntry(path);
456 d->iteratorFlags = flags;
457 d->init();
458}
459
460/*!
461 Constructs a QDirListing that can iterate over \a path.
462
463 You can pass options via \a flags to control how the directory should
464 be iterated. By default, \a flags is IteratorFlag::Default.
465
466 The listed entries will be filtered according to the file glob patterns
467 in \a nameFilters, which are converted to a regular expression using
468 QRegularExpression::fromWildcard (see QDir::setNameFilters() for more
469 details).
470
471 For example, the following iterator could be used to iterate over audio
472 files:
473
474 \snippet code/src_corelib_io_qdirlisting.cpp 2
475
476 Sometimes you can filter by name more efficiently by iterating over the
477 entries with a range-for loop, using string comparison. For example:
478
479 \snippet code/src_corelib_io_qdirlisting.cpp 7
480
481 \sa IteratorFlags, QDir::setNameFilters()
482*/
483QDirListing::QDirListing(const QString &path, const QStringList &nameFilters, IteratorFlags flags)
484 : d(new QDirListingPrivate)
485{
486 d->initialEntryInfo.entry = QFileSystemEntry(path);
487 d->nameFilters = nameFilters;
488 d->iteratorFlags = flags;
489 d->init();
490}
491
492/*!
493 \fn QDirListing::QDirListing(QDirListing &&other)
494
495 Move constructor. Moves \a other into this QDirListing.
496
497//! [partially-formed]
498 \note The moved-from object \a other is placed in a partially-formed state,
499 in which the only valid operations are destruction and assignment of a new
500 value.
501//! [partially-formed]
502*/
503
504/*!
505 \fn QDirListing &QDirListing::operator=(QDirListing &&other)
506
507 Move-assigns \a other to this QDirListing.
508
509 \include qdirlisting.cpp partially-formed
510*/
511
512/*!
513 Destroys the QDirListing.
514*/
515QDirListing::~QDirListing()
516{
517 delete d;
518}
519
520/*!
521 Returns the directory path used to construct this QDirListing.
522*/
523QString QDirListing::iteratorPath() const
524{
525 return d->initialEntryInfo.filePath();
526}
527
528/*!
529 Returns the set of IteratorFlags used to construct this QDirListing.
530*/
531QDirListing::IteratorFlags QDirListing::iteratorFlags() const
532{
533 return d->iteratorFlags;
534}
535
536/*!
537 Returns the list of file name glob filters used to construct this
538 QDirListing.
539*/
540QStringList QDirListing::nameFilters() const
541{
542 return d->nameFilters;
543}
544
545/*!
546 \class QDirListing::const_iterator
547 \since 6.8
548 \inmodule QtCore
549 \ingroup io
550
551 The iterator type returned by QDirListing::cbegin().
552
553//! [dirlisting-iterator-behavior]
554 \list
555 \li This is a forward-only, single-pass iterator (you cannot iterate
556 directory entries in reverse order)
557 \li Can't be copied, only \c{std::move()}d.
558 \li \include qdirlisting.cpp post-increment-partially-formed
559 \li Doesn't allow random access
560 \li Can be used in ranged-for loops; or with C++20 std::ranges algorithms
561 that don't require random access iterators
562 \li Dereferencing a valid iterator returns a \c{const DirEntry &}
563 \li (c)end() returns a \l QDirListing::sentinel that signals the end of
564 the iteration. Dereferencing an iterator that compares equal to end()
565 is undefined behavior
566 \endlist
567//! [dirlisting-iterator-behavior]
568
569 \include qdirlisting.cpp ranges-algorithms-note
570
571 \sa QDirListing, QDirListing::sentinel, QDirListing::DirEntry
572*/
573
574/*!
575 \typealias QDirListing::const_iterator::reference
576
577 A typedef for \c {const QDirListing::DirEntry &}.
578*/
579
580/*!
581 \typealias QDirListing::const_iterator::pointer
582
583 A typedef for \c {const QDirListing::DirEntry *}.
584*/
585
586/*!
587 \class QDirListing::sentinel
588 \since 6.8
589 \inmodule QtCore
590 \ingroup io
591
592 \l QDirListing returns an object of this type to signal the end of
593 iteration. Dereferencing a \l QDirListing::const_iterator that is
594 equal to \c sentinel{} is undefined behavior.
595
596 \include qdirlisting.cpp ranges-algorithms-note
597
598 \sa QDirListing, QDirListing::const_iterator, QDirListing::DirEntry
599*/
600
601/*!
602 \fn QDirListing::const_iterator QDirListing::begin() const
603 \fn QDirListing::const_iterator QDirListing::cbegin() const
604 \fn QDirListing::sentinel QDirListing::end() const
605 \fn QDirListing::sentinel QDirListing::cend() const
606
607 (c)begin() returns a QDirListing::const_iterator that can be used to
608 iterate over directory entries.
609
610 \include qdirlisting.cpp dirlisting-iterator-behavior
611
612 \note Each time (c)begin() is called on the same QDirListing object,
613 the internal state is reset and the iteration starts anew.
614
615 (Some of the above restrictions are dictated by the underlying system
616 library functions' implementation).
617
618 For example:
619 \snippet code/src_corelib_io_qdirlisting.cpp 0
620
621 Here's how to find and read all files filtered by name, recursively:
622 \snippet code/src_corelib_io_qdirlisting.cpp 1
623
624//! [ranges-algorithms-note]
625 \note The "classical" STL algorithms don't support iterator/sentinel, so
626 you need to use C++20 std::ranges algorithms for QDirListing, or else a
627 3rd-party library that provides range-based algorithms in C++17.
628//! [ranges-algorithms-note]
629
630 \sa QDirListing::DirEntry
631*/
633{
635 const_iterator it{d};
636 ++it;
637 return it;
638}
639
640/*!
641 \fn const QDirListing::DirEntry &QDirListing::const_iterator::operator*() const
642
643 Returns a \c{const QDirListing::DirEntry &} of the directory entry this
644 iterator points to.
645*/
646
647/*!
648 \fn const QDirListing::DirEntry *QDirListing::const_iterator::operator->() const
649
650 Returns a \c{const QDirListing::DirEntry *} to the directory entry this
651 iterator points to.
652*/
653
654/*!
655 \fn QDirListing::const_iterator::operator++()
656
657 Pre-increment operator.
658 Advances the iterator and returns a reference to it.
659*/
660
661/*!
662 \fn void QDirListing::const_iterator::operator++(int)
663
664 Post-increment operator.
665
666 \include qdirlisting.cpp std-input-iterator-tag
667
668//! [post-increment-partially-formed]
669 The return value of post-increment on objects that model
670 \c std::input_iterator is partially-formed (a copy of an iterator that
671 has since been advanced), the only valid operations on such an object
672 are destruction and assignment of a new iterator. Therefore the
673 post-increment operator advances the iterator and returns \c void.
674//! [post-increment-partially-formed]
675*/
676
677/*!
678 \internal
679
680 Implements the actual advancing. Not a member function to avoid forcing
681 DirEntry objects (and therefore const_iterator ones) onto the stack.
682*/
683auto QDirListing::next(DirEntry dirEntry) -> DirEntry
684{
685 dirEntry.dirListPtr->advance();
686 if (!dirEntry.dirListPtr->hasIterators())
687 return {}; // All done, make `this` equal to the end() iterator
688 return dirEntry;
689}
690
691/*!
692 \class QDirListing::DirEntry
693 \inmodule QtCore
694 \ingroup io
695
696 Dereferencing a valid QDirListing::const_iterator returns a DirEntry
697 object.
698
699 DirEntry offers a subset of QFileInfo's API (for example, fileName(),
700 filePath(), exists()). Internally, DirEntry only constructs a QFileInfo
701 object if needed, that is, if the info hasn't been already fetched
702 by other system functions. You can use DirEntry::fileInfo() to get a
703 QFileInfo. For example:
704
705 \snippet code/src_corelib_io_qdirlisting.cpp 3
706
707 \snippet code/src_corelib_io_qdirlisting.cpp 4
708*/
709
710/*!
711 \fn QFileInfo QDirListing::DirEntry::fileInfo() const
712 \fn QString QDirListing::DirEntry::fileName() const
713 \fn QString QDirListing::DirEntry::baseName() const
714 \fn QString QDirListing::DirEntry::completeBaseName() const
715 \fn QString QDirListing::DirEntry::suffix() const
716 \fn QString QDirListing::DirEntry::bundleName() const
717 \fn QString QDirListing::DirEntry::completeSuffix() const
718 \fn QString QDirListing::DirEntry::filePath() const
719 \fn QString QDirListing::DirEntry::canonicalFilePath() const
720 \fn QString QDirListing::DirEntry::absoluteFilePath() const
721 \fn QString QDirListing::DirEntry::absolutePath() const
722 \fn bool QDirListing::DirEntry::isDir() const
723 \fn bool QDirListing::DirEntry::isFile() const
724 \fn bool QDirListing::DirEntry::isSymLink() const
725 \fn bool QDirListing::DirEntry::exists() const
726 \fn bool QDirListing::DirEntry::isHidden() const
727 \fn bool QDirListing::DirEntry::isReadable() const
728 \fn bool QDirListing::DirEntry::isWritable() const
729 \fn bool QDirListing::DirEntry::isExecutable() const
730 \fn qint64 QDirListing::DirEntry::size() const
731 \fn QDateTime QDirListing::DirEntry::fileTime(QFile::FileTime type, const QTimeZone &tz) const
732 \fn QDateTime QDirListing::DirEntry::birthTime(const QTimeZone &tz) const;
733 \fn QDateTime QDirListing::DirEntry::metadataChangeTime(const QTimeZone &tz) const;
734 \fn QDateTime QDirListing::DirEntry::lastModified(const QTimeZone &tz) const;
735 \fn QDateTime QDirListing::DirEntry::lastRead(const QTimeZone &tz) const;
736
737 See the QFileInfo methods with the same names.
738*/
739
740QFileInfo QDirListing::DirEntry::fileInfo() const
741{
742 return dirListPtr->currentEntryInfo.fileInfo();
743}
744
745QString QDirListing::DirEntry::fileName() const
746{
747 return dirListPtr->currentEntryInfo.fileName();
748}
749
750QString QDirListing::DirEntry::baseName() const
751{
752 return dirListPtr->currentEntryInfo.baseName();
753}
754
755QString QDirListing::DirEntry::completeBaseName() const
756{
757 return dirListPtr->currentEntryInfo.completeBaseName();
758}
759
760QString QDirListing::DirEntry::suffix() const
761{
762 return dirListPtr->currentEntryInfo.suffix();
763}
764
765QString QDirListing::DirEntry::bundleName() const
766{
767 return dirListPtr->currentEntryInfo.bundleName();
768}
769
770QString QDirListing::DirEntry::completeSuffix() const
771{
772 return dirListPtr->currentEntryInfo.completeSuffix();
773}
774
775QString QDirListing::DirEntry::filePath() const
776{
777 return dirListPtr->currentEntryInfo.filePath();
778}
779
780QString QDirListing::DirEntry::canonicalFilePath() const
781{
782 return dirListPtr->currentEntryInfo.canonicalFilePath();
783}
784
785QString QDirListing::DirEntry::absoluteFilePath() const
786{
787 return dirListPtr->currentEntryInfo.absoluteFilePath();
788}
789
790QString QDirListing::DirEntry::absolutePath() const
791{
792 return dirListPtr->currentEntryInfo.absolutePath();
793}
794
796{
797 return dirListPtr->currentEntryInfo.isDir();
798}
799
801{
802 return dirListPtr->currentEntryInfo.isFile();
803}
804
806{
807 return dirListPtr->currentEntryInfo.isSymLink();
808}
809
811{
812 return dirListPtr->currentEntryInfo.exists();
813}
814
816{
817 return dirListPtr->currentEntryInfo.isHidden();
818}
819
821{
822 return dirListPtr->currentEntryInfo.isReadable();
823}
824
826{
827 return dirListPtr->currentEntryInfo.isWritable();
828}
829
831{
832 return dirListPtr->currentEntryInfo.isExecutable();
833}
834
835qint64 QDirListing::DirEntry::size() const
836{
837 return dirListPtr->currentEntryInfo.size();
838}
839
840QDateTime QDirListing::DirEntry::fileTime(QFile::FileTime type, const QTimeZone &tz) const
841{
842 return dirListPtr->currentEntryInfo.fileTime(type, tz);
843}
844
845#ifndef QT_NO_DEBUG_STREAM
846/*
847 Since 6.11.
848*/
849QDebug operator<<(QDebug debug, QDirListing::IteratorFlags flags)
850{
851 QDebugStateSaver save(debug);
852 debug.resetFormat();
853
854 QByteArray ret = "QDirListing::IteratorFlags(";
855 using F = QDirListing::IteratorFlag;
856 if (flags.testFlags(F::Default))
857 ret += "Default|";
858 if (flags.testFlags(F::ExcludeFiles))
859 ret += "ExcludeFiles|";
860 if (flags.testFlags(F::ExcludeDirs))
861 ret += "ExcludeDirs|";
862 if (flags.testFlags(F::ExcludeOther))
863 ret += "ExcludeOther|";
864 if (flags.testFlags(F::ResolveSymlinks))
865 ret += "ResolveSymlinks|";
866 // if (flags.testFlags(F::FilesOnly)) // covered by F::ExcludeDirs | F::ExcludeOther
867 // ret += "FilesOnly|";
868 // if (flags.testFlags(F::DirsOnly)) // covered by F::ExcludeFiles | F::ExcludeOther
869 // ret += "DirsOnly|";
870 if (flags.testFlags(F::IncludeHidden))
871 ret += "IncludeHidden|";
872 if (flags.testFlags(F::IncludeDotAndDotDot))
873 ret += "IncludeDotAndDotDot|";
874 if (flags.testFlags(F::CaseSensitive))
875 ret += "CaseSensitive|";
876 if (flags.testFlags(F::Recursive))
877 ret += "Recursive|";
878 if (flags.testFlags(F::FollowDirSymlinks))
879 ret += "FollowDirSymlinks|";
880 if (flags.testFlags(F::IncludeBrokenSymlinks))
881 ret += "IncludeBrokenSymlinks|";
882 if (flags.testFlags(F::NoNameFiltersForDirs))
883 ret += "NoNameFiltersForDirs|";
884
885 if (ret.endsWith('|'))
886 ret.chop(1);
887 ret += ')';
888
889 debug.noquote() << ret;
890 return debug;
891}
892#endif
893
894QT_END_NAMESPACE
bool entryMatches(QDirEntryInfo &info)
QDirListing::IteratorFlags iteratorFlags
void pushInitialDirectory()
QStringList nameFilters
void checkAndPushDirectory(QDirEntryInfo &info)
std::unique_ptr< QAbstractFileEngine > engine
QDuplicateTracker< QString > visitedLinks
bool hasIterators() const
bool matchesFilters(QDirEntryInfo &data) const
QDirEntryInfo initialEntryInfo
QDirEntryInfo currentEntryInfo
std::vector< FEngineIteratorPtr > fileEngineIterators
std::vector< FsIteratorPtr > nativeIterators
void pushDirectory(QDirEntryInfo &info)
\inmodule QtCore
Definition qdirlisting.h:68
Q_CORE_EXPORT bool isReadable() const
Q_CORE_EXPORT bool isHidden() const
Q_CORE_EXPORT bool isWritable() const
Q_CORE_EXPORT bool isExecutable() const
Q_CORE_EXPORT bool isFile() const
Q_CORE_EXPORT bool exists() const
Q_CORE_EXPORT bool isSymLink() const
Q_CORE_EXPORT bool isDir() const
const_iterator & operator++()
Pre-increment operator.
IteratorFlag
This enum class describes flags that can be used to configure the behavior of QDirListing.
Definition qdirlisting.h:29
static bool isDotOrDotDot(QStringView fileName)