Source code
Revision control
Copy as Markdown
// Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2024 Ahmad Samir <a.samirh78@gmail.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default
#ifndef QDIRLISTING_H
#define QDIRLISTING_H
#include <QtCore/qtdeprecationmarkers.h>
#include <QtCore/qfiledevice.h>
#include <QtCore/qflags.h>
#include <QtCore/qobjectdefs.h>
#include <QtCore/qtclasshelpermacros.h>
#include <QtCore/qtcoreexports.h>
#include <QtCore/qdatetime.h>
#include <iterator>
#include <utility>
QT_BEGIN_NAMESPACE
class QDirListingPrivate;
class QFileInfo;
class QDir;
class QTimeZone;
class QDirListing
{
Q_GADGET_EXPORT(Q_CORE_EXPORT)
public:
enum class IteratorFlag {
Default = 0x000000,
ExcludeFiles = 0x000004,
ExcludeDirs = 0x000008,
#if QT_DEPRECATED_SINCE(6, 14)
ExcludeSpecial QT_DEPRECATED_VERSION_X_6_14("Use ExcludeOther instead.") = 0x000010,
#endif
ExcludeOther = 0x000010,
ResolveSymlinks = 0x000020,
FilesOnly = ExcludeDirs | ExcludeOther,
DirsOnly = ExcludeFiles | ExcludeOther,
IncludeHidden = 0x000040,
IncludeDotAndDotDot = 0x000080,
CaseSensitive = 0x000100,
Recursive = 0x000400,
FollowDirSymlinks = 0x000800,
IncludeBrokenSymlinks = 0x001000,
NoNameFiltersForDirs = 0x040000, // used internally
};
Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)
Q_FLAG(IteratorFlags)
Q_CORE_EXPORT explicit QDirListing(const QString &path,
IteratorFlags flags = IteratorFlag::Default);
Q_CORE_EXPORT explicit QDirListing(const QString &path, const QStringList &nameFilters,
IteratorFlags flags = IteratorFlag::Default);
QDirListing(QDirListing &&other) noexcept
: d{std::exchange(other.d, nullptr)} {}
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QDirListing)
void swap(QDirListing &other) noexcept { qt_ptr_swap(d, other.d); }
Q_CORE_EXPORT ~QDirListing();
Q_CORE_EXPORT QString iteratorPath() const;
Q_CORE_EXPORT IteratorFlags iteratorFlags() const;
Q_CORE_EXPORT QStringList nameFilters() const;
class DirEntry
{
friend class QDirListing;
QDirListingPrivate *dirListPtr = nullptr;
public:
Q_CORE_EXPORT QString fileName() const;
Q_CORE_EXPORT QString baseName() const;
Q_CORE_EXPORT QString completeBaseName() const;
Q_CORE_EXPORT QString suffix() const;
Q_CORE_EXPORT QString bundleName() const;
Q_CORE_EXPORT QString completeSuffix() const;
Q_CORE_EXPORT QString filePath() const;
Q_CORE_EXPORT bool isDir() const;
Q_CORE_EXPORT bool isFile() const;
Q_CORE_EXPORT bool isSymLink() const;
Q_CORE_EXPORT bool exists() const;
Q_CORE_EXPORT bool isHidden() const;
Q_CORE_EXPORT bool isReadable() const;
Q_CORE_EXPORT bool isWritable() const;
Q_CORE_EXPORT bool isExecutable() const;
Q_CORE_EXPORT QFileInfo fileInfo() const;
Q_CORE_EXPORT QString canonicalFilePath() const;
Q_CORE_EXPORT QString absoluteFilePath() const;
Q_CORE_EXPORT QString absolutePath() const;
Q_CORE_EXPORT qint64 size() const;
QDateTime birthTime(const QTimeZone &tz) const
{ return fileTime(QFileDevice::FileBirthTime, tz); }
QDateTime metadataChangeTime(const QTimeZone &tz) const
{ return fileTime(QFileDevice::FileMetadataChangeTime, tz); }
QDateTime lastModified(const QTimeZone &tz) const
{ return fileTime(QFileDevice::FileModificationTime, tz); }
QDateTime lastRead(const QTimeZone &tz) const
{ return fileTime(QFileDevice::FileAccessTime, tz); }
Q_CORE_EXPORT QDateTime fileTime(QFileDevice::FileTime type, const QTimeZone &tz) const;
};
class sentinel
{
friend constexpr bool operator==(sentinel, sentinel) noexcept { return true; }
friend constexpr bool operator!=(sentinel, sentinel) noexcept { return false; }
};
class const_iterator
{
Q_DISABLE_COPY(const_iterator)
friend class QDirListing;
explicit const_iterator(QDirListingPrivate *dp) { dirEntry.dirListPtr = dp; }
DirEntry dirEntry;
public:
using iterator_category = std::input_iterator_tag;
using value_type = DirEntry;
using difference_type = qint64;
using pointer = const value_type *;
using reference = const value_type &;
const_iterator() = default;
const_iterator(const_iterator &&) noexcept = default;
const_iterator &operator=(const_iterator &&) noexcept = default;
reference operator*() const { return dirEntry; }
pointer operator->() const { return &dirEntry; }
const_iterator &operator++() { dirEntry = next(dirEntry); return *this; }
void operator++(int) { ++*this; } // [iterator.concept.winc]/14 not required to return sth
private:
bool atEnd() const noexcept { return dirEntry.dirListPtr == nullptr; }
friend bool operator==(const const_iterator &lhs, sentinel) noexcept { return lhs.atEnd(); }
#ifndef __cpp_impl_three_way_comparison
friend bool operator!=(const const_iterator &lhs, sentinel) noexcept
{ return !operator==(lhs, sentinel{}); }
friend bool operator==(sentinel, const const_iterator &rhs) noexcept
{ return operator==(rhs, sentinel{}); }
friend bool operator!=(sentinel, const const_iterator &rhs) noexcept
{ return !operator==(sentinel{}, rhs); }
#endif // __cpp_impl_three_way_comparison
};
Q_CORE_EXPORT const_iterator begin() const;
const_iterator cbegin() const { return begin(); }
sentinel end() const { return {}; }
sentinel cend() const { return end(); }
// Qt compatibility
const_iterator constBegin() const { return begin(); }
sentinel constEnd() const { return end(); }
private:
Q_DISABLE_COPY(QDirListing)
Q_CORE_EXPORT static DirEntry next(DirEntry);
QDirListingPrivate *d;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDirListing::IteratorFlags)
QT_END_NAMESPACE
#endif // QDIRLISTING_H