| 1 | // Copyright (C) 2020 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 |  | 
| 4 | #include "qplatformdefs.h" | 
| 5 | #include "qfileinfo.h" | 
| 6 | #include "qglobal.h" | 
| 7 | #include "qdir.h" | 
| 8 | #include "qfileinfo_p.h" | 
| 9 | #include "qdebug.h" | 
| 10 |  | 
| 11 | QT_BEGIN_NAMESPACE | 
| 12 |  | 
| 13 | using namespace Qt::StringLiterals; | 
| 14 |  | 
| 15 | QT_IMPL_METATYPE_EXTERN(QFileInfo) | 
| 16 |  | 
| 17 | QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const | 
| 18 | { | 
| 19 |     if (cache_enabled && !fileNames[(int)name].isNull()) | 
| 20 |         return fileNames[(int)name]; | 
| 21 |  | 
| 22 |     QString ret; | 
| 23 |     if (fileEngine == nullptr) { // local file; use the QFileSystemEngine directly | 
| 24 |         switch (name) { | 
| 25 |             case QAbstractFileEngine::CanonicalName: | 
| 26 |             case QAbstractFileEngine::CanonicalPathName: { | 
| 27 |                 QFileSystemEntry entry = QFileSystemEngine::canonicalName(entry: fileEntry, data&: metaData); | 
| 28 |                 if (cache_enabled) { // be smart and store both | 
| 29 |                     fileNames[QAbstractFileEngine::CanonicalName] = entry.filePath(); | 
| 30 |                     fileNames[QAbstractFileEngine::CanonicalPathName] = entry.path(); | 
| 31 |                 } | 
| 32 |                 if (name == QAbstractFileEngine::CanonicalName) | 
| 33 |                     ret = entry.filePath(); | 
| 34 |                 else | 
| 35 |                     ret = entry.path(); | 
| 36 |                 break; | 
| 37 |             } | 
| 38 |             case QAbstractFileEngine::AbsoluteLinkTarget: | 
| 39 |                 ret = QFileSystemEngine::getLinkTarget(link: fileEntry, data&: metaData).filePath(); | 
| 40 |                 break; | 
| 41 |             case QAbstractFileEngine::RawLinkPath: | 
| 42 |                 ret = QFileSystemEngine::getRawLinkPath(link: fileEntry, data&: metaData).filePath(); | 
| 43 |                 break; | 
| 44 |             case QAbstractFileEngine::JunctionName: | 
| 45 |                 ret = QFileSystemEngine::getJunctionTarget(link: fileEntry, data&: metaData).filePath(); | 
| 46 |                 break; | 
| 47 |             case QAbstractFileEngine::BundleName: | 
| 48 |                 ret = QFileSystemEngine::bundleName(fileEntry); | 
| 49 |                 break; | 
| 50 |             case QAbstractFileEngine::AbsoluteName: | 
| 51 |             case QAbstractFileEngine::AbsolutePathName: { | 
| 52 |                 QFileSystemEntry entry = QFileSystemEngine::absoluteName(entry: fileEntry); | 
| 53 |                 if (cache_enabled) { // be smart and store both | 
| 54 |                     fileNames[QAbstractFileEngine::AbsoluteName] = entry.filePath(); | 
| 55 |                     fileNames[QAbstractFileEngine::AbsolutePathName] = entry.path(); | 
| 56 |                 } | 
| 57 |                 if (name == QAbstractFileEngine::AbsoluteName) | 
| 58 |                     ret = entry.filePath(); | 
| 59 |                 else | 
| 60 |                     ret = entry.path(); | 
| 61 |                 break; | 
| 62 |             } | 
| 63 |             default: break; | 
| 64 |         } | 
| 65 |     } else { | 
| 66 |         ret = fileEngine->fileName(file: name); | 
| 67 |     } | 
| 68 |     if (ret.isNull()) | 
| 69 |         ret = ""_L1 ; | 
| 70 |     if (cache_enabled) | 
| 71 |         fileNames[(int)name] = ret; | 
| 72 |     return ret; | 
| 73 | } | 
| 74 |  | 
| 75 | QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const | 
| 76 | { | 
| 77 |     if (cache_enabled && !fileOwners[(int)own].isNull()) | 
| 78 |         return fileOwners[(int)own]; | 
| 79 |     QString ret; | 
| 80 |     if (fileEngine == nullptr) { | 
| 81 |         switch (own) { | 
| 82 |         case QAbstractFileEngine::OwnerUser: | 
| 83 |             ret = QFileSystemEngine::resolveUserName(entry: fileEntry, data&: metaData); | 
| 84 |             break; | 
| 85 |         case QAbstractFileEngine::OwnerGroup: | 
| 86 |             ret = QFileSystemEngine::resolveGroupName(entry: fileEntry, data&: metaData); | 
| 87 |             break; | 
| 88 |         } | 
| 89 |      } else { | 
| 90 |         ret = fileEngine->owner(own); | 
| 91 |     } | 
| 92 |     if (ret.isNull()) | 
| 93 |         ret = ""_L1 ; | 
| 94 |     if (cache_enabled) | 
| 95 |         fileOwners[(int)own] = ret; | 
| 96 |     return ret; | 
| 97 | } | 
| 98 |  | 
| 99 | uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) const | 
| 100 | { | 
| 101 |     Q_ASSERT(fileEngine); // should never be called when using the native FS | 
| 102 |     // We split the testing into tests for for LinkType, BundleType, PermsMask | 
| 103 |     // and the rest. | 
| 104 |     // Tests for file permissions on Windows can be slow, especially on network | 
| 105 |     // paths and NTFS drives. | 
| 106 |     // In order to determine if a file is a symlink or not, we have to lstat(). | 
| 107 |     // If we're not interested in that information, we might as well avoid one | 
| 108 |     // extra syscall. Bundle detecton on Mac can be slow, especially on network | 
| 109 |     // paths, so we separate out that as well. | 
| 110 |  | 
| 111 |     QAbstractFileEngine::FileFlags req; | 
| 112 |     uint cachedFlags = 0; | 
| 113 |  | 
| 114 |     if (request & (QAbstractFileEngine::FlagsMask | QAbstractFileEngine::TypesMask)) { | 
| 115 |         if (!getCachedFlag(c: CachedFileFlags)) { | 
| 116 |             req |= QAbstractFileEngine::FlagsMask; | 
| 117 |             req |= QAbstractFileEngine::TypesMask; | 
| 118 |             req &= (~QAbstractFileEngine::LinkType); | 
| 119 |             req &= (~QAbstractFileEngine::BundleType); | 
| 120 |  | 
| 121 |             cachedFlags |= CachedFileFlags; | 
| 122 |         } | 
| 123 |  | 
| 124 |         if (request & QAbstractFileEngine::LinkType) { | 
| 125 |             if (!getCachedFlag(c: CachedLinkTypeFlag)) { | 
| 126 |                 req |= QAbstractFileEngine::LinkType; | 
| 127 |                 cachedFlags |= CachedLinkTypeFlag; | 
| 128 |             } | 
| 129 |         } | 
| 130 |  | 
| 131 |         if (request & QAbstractFileEngine::BundleType) { | 
| 132 |             if (!getCachedFlag(c: CachedBundleTypeFlag)) { | 
| 133 |                 req |= QAbstractFileEngine::BundleType; | 
| 134 |                 cachedFlags |= CachedBundleTypeFlag; | 
| 135 |             } | 
| 136 |         } | 
| 137 |     } | 
| 138 |  | 
| 139 |     if (request & QAbstractFileEngine::PermsMask) { | 
| 140 |         if (!getCachedFlag(c: CachedPerms)) { | 
| 141 |             req |= QAbstractFileEngine::PermsMask; | 
| 142 |             cachedFlags |= CachedPerms; | 
| 143 |         } | 
| 144 |     } | 
| 145 |  | 
| 146 |     if (req) { | 
| 147 |         if (cache_enabled) | 
| 148 |             req &= (~QAbstractFileEngine::Refresh); | 
| 149 |         else | 
| 150 |             req |= QAbstractFileEngine::Refresh; | 
| 151 |  | 
| 152 |         QAbstractFileEngine::FileFlags flags = fileEngine->fileFlags(type: req); | 
| 153 |         fileFlags |= uint(flags.toInt()); | 
| 154 |         setCachedFlag(cachedFlags); | 
| 155 |     } | 
| 156 |  | 
| 157 |     return fileFlags & request.toInt(); | 
| 158 | } | 
| 159 |  | 
| 160 | QDateTime &QFileInfoPrivate::getFileTime(QFile::FileTime request) const | 
| 161 | { | 
| 162 |     Q_ASSERT(fileEngine); // should never be called when using the native FS | 
| 163 |     if (!cache_enabled) | 
| 164 |         clearFlags(); | 
| 165 |  | 
| 166 |     uint cf = 0; | 
| 167 |     switch (request) { | 
| 168 |     case QFile::FileAccessTime: | 
| 169 |         cf = CachedATime; | 
| 170 |         break; | 
| 171 |     case QFile::FileBirthTime: | 
| 172 |         cf = CachedBTime; | 
| 173 |         break; | 
| 174 |     case QFile::FileMetadataChangeTime: | 
| 175 |         cf = CachedMCTime; | 
| 176 |         break; | 
| 177 |     case QFile::FileModificationTime: | 
| 178 |         cf = CachedMTime; | 
| 179 |         break; | 
| 180 |     } | 
| 181 |  | 
| 182 |     if (!getCachedFlag(c: cf)) { | 
| 183 |         fileTimes[request] = fileEngine->fileTime(time: request); | 
| 184 |         setCachedFlag(cf); | 
| 185 |     } | 
| 186 |     return fileTimes[request]; | 
| 187 | } | 
| 188 |  | 
| 189 | //************* QFileInfo | 
| 190 |  | 
| 191 | /*! | 
| 192 |     \class QFileInfo | 
| 193 |     \inmodule QtCore | 
| 194 |     \reentrant | 
| 195 |     \brief The QFileInfo class provides an OS-independent API to retrieve | 
| 196 |     information about file system entries. | 
| 197 |  | 
| 198 |     \ingroup io | 
| 199 |     \ingroup shared | 
| 200 |  | 
| 201 |     \compares equality | 
| 202 |  | 
| 203 |     QFileInfo provides information about a file system entry, such as its | 
| 204 |     name, path, access rights and whether it is a regular file, directory or | 
| 205 |     symbolic link. The entry's size and last modified/read times are also | 
| 206 |     available. QFileInfo can also be used to obtain information about a Qt | 
| 207 |     \l{resource system}{resource}. | 
| 208 |  | 
| 209 |     A QFileInfo can point to a file system entry with either an absolute or | 
| 210 |     a relative path: | 
| 211 |     \list | 
| 212 |         \li \include qfileinfo.cpp absolute-path-unix-windows | 
| 213 |  | 
| 214 |         \li \include qfileinfo.cpp relative-path-note | 
| 215 |     \endlist | 
| 216 |  | 
| 217 |     An example of an absolute path is the string \c {"/tmp/quartz"}. A relative | 
| 218 |     path may look like \c {"src/fatlib"}. You can use the function isRelative() | 
| 219 |     to check whether a QFileInfo is using a relative or an absolute path. You | 
| 220 |     can call the function makeAbsolute() to convert a relative QFileInfo's | 
| 221 |     path to an absolute path. | 
| 222 |  | 
| 223 | //! [qresource-virtual-fs-colon] | 
| 224 |     \note Paths starting with a colon (\e{:}) are always considered | 
| 225 |     absolute, as they denote a QResource. | 
| 226 | //! [qresource-virtual-fs-colon] | 
| 227 |  | 
| 228 |     The file system entry path that the QFileInfo works on is set in the | 
| 229 |     constructor or later with setFile(). Use exists() to see if the entry | 
| 230 |     actually exists and size() to get its size. | 
| 231 |  | 
| 232 |     The file system entry's type is obtained with isFile(), isDir(), and | 
| 233 |     isSymLink(). The symLinkTarget() function provides the absolute path of | 
| 234 |     the target the symlink points to. | 
| 235 |  | 
| 236 |     The path elements of the file system entry can be extracted with path() | 
| 237 |     and fileName(). The fileName()'s parts can be extracted with baseName(), | 
| 238 |     suffix(), or completeSuffix(). QFileInfo objects referring to directories | 
| 239 |     created by Qt classes will not have a trailing directory separator | 
| 240 |     \c{'/'}. If you wish to use trailing separators in your own file info | 
| 241 |     objects, just append one to the entry's path given to the constructors | 
| 242 |     or setFile(). | 
| 243 |  | 
| 244 |     Date and time related information are returned by birthTime(), fileTime(), | 
| 245 |     lastModified(), lastRead(), and metadataChangeTime(). | 
| 246 |     Information about | 
| 247 |     access permissions can be obtained with isReadable(), isWritable(), and | 
| 248 |     isExecutable(). Ownership information can be obtained with | 
| 249 |     owner(), ownerId(), group(), and groupId(). You can also examine | 
| 250 |     permissions and ownership in a single statement using the permission() | 
| 251 |     function. | 
| 252 |  | 
| 253 |     \section1 Symbolic Links and Shortcuts | 
| 254 |  | 
| 255 |     On Unix (including \macos and iOS), the property getter functions in | 
| 256 |     this class return the properties such as times and size of the target, | 
| 257 |     not the symlink, because Unix handles symlinks transparently. Opening | 
| 258 |     a symlink using QFile effectively opens the link's target. For example: | 
| 259 |  | 
| 260 |     \snippet code/src_corelib_io_qfileinfo.cpp 0 | 
| 261 |  | 
| 262 |     On Windows, shortcuts (\c .lnk files) are currently treated as symlinks. As | 
| 263 |     on Unix systems, the property getters return the size of the target, | 
| 264 |     not the \c .lnk file itself. This behavior is deprecated and will likely | 
| 265 |     be removed in a future version of Qt, after which \c .lnk files will be | 
| 266 |     treated as regular files. | 
| 267 |  | 
| 268 |     \snippet code/src_corelib_io_qfileinfo.cpp 1 | 
| 269 |  | 
| 270 |     \section1 NTFS permissions | 
| 271 |  | 
| 272 |     On NTFS file systems, ownership and permissions checking is | 
| 273 |     disabled by default for performance reasons. To enable it, | 
| 274 |     include the following line: | 
| 275 |  | 
| 276 |     \snippet ntfsp.cpp 0 | 
| 277 |  | 
| 278 |     Permission checking is then turned on and off by incrementing and | 
| 279 |     decrementing \c qt_ntfs_permission_lookup by 1. | 
| 280 |  | 
| 281 |     \snippet ntfsp.cpp 1 | 
| 282 |  | 
| 283 |     \note Since this is a non-atomic global variable, it is only safe | 
| 284 |     to increment or decrement \c qt_ntfs_permission_lookup before any | 
| 285 |     threads other than the main thread have started or after every thread | 
| 286 |     other than the main thread has ended. | 
| 287 |  | 
| 288 |     \note From Qt 6.6 the variable \c qt_ntfs_permission_lookup is | 
| 289 |     deprecated. Please use the following alternatives. | 
| 290 |  | 
| 291 |     The safe and easy way to manage permission checks is to use the RAII class | 
| 292 |     \c QNtfsPermissionCheckGuard. | 
| 293 |  | 
| 294 |     \snippet ntfsp.cpp raii | 
| 295 |  | 
| 296 |     If you need more fine-grained control, it is possible to manage the permission | 
| 297 |     with the following functions instead: | 
| 298 |  | 
| 299 |     \snippet ntfsp.cpp free-funcs | 
| 300 |  | 
| 301 |     \section1 Performance Considerations | 
| 302 |  | 
| 303 |     Some of QFileInfo's functions have to query the file system, but for | 
| 304 |     performance reasons, some functions only operate on the path string. | 
| 305 |     For example: To return the absolute path of a relative entry's path, | 
| 306 |     absolutePath() has to query the file system. The path() function, however, | 
| 307 |     can work on the file name directly, and so it is faster. | 
| 308 |  | 
| 309 |     QFileInfo also caches information about the file system entry it refers | 
| 310 |     to. Because the file system can be changed by other users or programs, | 
| 311 |     or even by other parts of the same program, there is a function that | 
| 312 |     refreshes the information stored in QFileInfo, namely refresh(). To switch | 
| 313 |     off a QFileInfo's caching (that is, force it to query the underlying file | 
| 314 |     system every time you request information from it), call setCaching(false). | 
| 315 |  | 
| 316 |     Fetching information from the file system is typically done by calling | 
| 317 |     (possibly) expensive system functions, so QFileInfo (depending on the | 
| 318 |     implementation) might not fetch all the information from the file system | 
| 319 |     at construction. To make sure that all information is read from the file | 
| 320 |     system immediately, use the stat() member function. | 
| 321 |  | 
| 322 |     \l{birthTime()}, \l{fileTime()}, \l{lastModified()}, \l{lastRead()}, | 
| 323 |     and \l{metadataChangeTime()} return times in \e{local time} by default. | 
| 324 |     Since native file system API typically uses UTC, this requires a conversion. | 
| 325 |     If you don't actually need the local time, you can avoid this by requesting | 
| 326 |     the time in QTimeZone::UTC directly. | 
| 327 |  | 
| 328 |     \section1 Platform Specific Issues | 
| 329 |  | 
| 330 |     \include android-content-uri-limitations.qdocinc | 
| 331 |  | 
| 332 |     \sa QDir, QFile | 
| 333 | */ | 
| 334 |  | 
| 335 | /*! | 
| 336 |     \fn QFileInfo &QFileInfo::operator=(QFileInfo &&other) | 
| 337 |  | 
| 338 |     Move-assigns \a other to this QFileInfo instance. | 
| 339 |  | 
| 340 |     \since 5.2 | 
| 341 | */ | 
| 342 |  | 
| 343 | /*! | 
| 344 |     \internal | 
| 345 | */ | 
| 346 | QFileInfo::QFileInfo(QFileInfoPrivate *p) : d_ptr(p) | 
| 347 | { | 
| 348 | } | 
| 349 |  | 
| 350 | /*! | 
| 351 |     Constructs an empty QFileInfo object that doesn't refer to any file | 
| 352 |     system entry. | 
| 353 |  | 
| 354 |     \sa setFile() | 
| 355 | */ | 
| 356 | QFileInfo::QFileInfo() : d_ptr(new QFileInfoPrivate()) | 
| 357 | { | 
| 358 | } | 
| 359 |  | 
| 360 | /*! | 
| 361 |     Constructs a QFileInfo that gives information about a file system entry | 
| 362 |     located at \a path that can be absolute or relative. | 
| 363 |  | 
| 364 | //! [preserve-relative-path] | 
| 365 |     If \a path is relative, the QFileInfo will also have a relative path. | 
| 366 | //! [preserve-relative-path] | 
| 367 |  | 
| 368 |     \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath() | 
| 369 | */ | 
| 370 | QFileInfo::QFileInfo(const QString &path) : d_ptr(new QFileInfoPrivate(path)) | 
| 371 | { | 
| 372 | } | 
| 373 |  | 
| 374 | /*! | 
| 375 |     Constructs a new QFileInfo that gives information about file \a | 
| 376 |     file. | 
| 377 |  | 
| 378 |     If the \a file has a relative path, the QFileInfo will also have a | 
| 379 |     relative path. | 
| 380 |  | 
| 381 |     \sa isRelative() | 
| 382 | */ | 
| 383 | QFileInfo::QFileInfo(const QFileDevice &file) : d_ptr(new QFileInfoPrivate(file.fileName())) | 
| 384 | { | 
| 385 | } | 
| 386 |  | 
| 387 | /*! | 
| 388 |     Constructs a new QFileInfo that gives information about the given | 
| 389 |     file system entry \a path that is relative to the directory \a dir. | 
| 390 |  | 
| 391 | //! [preserve-relative-or-absolute] | 
| 392 |     If \a dir has a relative path, the QFileInfo will also have a | 
| 393 |     relative path. | 
| 394 |  | 
| 395 |     If \a path is absolute, then the directory specified by \a dir | 
| 396 |     will be disregarded. | 
| 397 | //! [preserve-relative-or-absolute] | 
| 398 |  | 
| 399 |     \sa isRelative() | 
| 400 | */ | 
| 401 | QFileInfo::QFileInfo(const QDir &dir, const QString &path) | 
| 402 |     : d_ptr(new QFileInfoPrivate(dir.filePath(fileName: path))) | 
| 403 | { | 
| 404 | } | 
| 405 |  | 
| 406 | /*! | 
| 407 |     Constructs a new QFileInfo that is a copy of the given \a fileinfo. | 
| 408 | */ | 
| 409 | QFileInfo::QFileInfo(const QFileInfo &fileinfo) | 
| 410 |     : d_ptr(fileinfo.d_ptr) | 
| 411 | { | 
| 412 |  | 
| 413 | } | 
| 414 |  | 
| 415 | /*! | 
| 416 |     Destroys the QFileInfo and frees its resources. | 
| 417 | */ | 
| 418 |  | 
| 419 | QFileInfo::~QFileInfo() | 
| 420 | { | 
| 421 | } | 
| 422 |  | 
| 423 | /*! | 
| 424 |     \fn bool QFileInfo::operator!=(const QFileInfo &lhs, const QFileInfo &rhs) | 
| 425 |  | 
| 426 |     Returns \c true if QFileInfo \a lhs refers to a different file system | 
| 427 |     entry than the one referred to by \a rhs; otherwise returns \c false. | 
| 428 |  | 
| 429 |     \sa operator==() | 
| 430 | */ | 
| 431 |  | 
| 432 | /*! | 
| 433 |     \fn bool QFileInfo::operator==(const QFileInfo &lhs, const QFileInfo &rhs) | 
| 434 |  | 
| 435 |     Returns \c true if QFileInfo \a lhs and QFileInfo \a rhs refer to the same | 
| 436 |     entry on the file system; otherwise returns \c false. | 
| 437 |  | 
| 438 |     Note that the result of comparing two empty QFileInfo objects, containing | 
| 439 |     no file system entry references (paths that do not exist or are empty), | 
| 440 |     is undefined. | 
| 441 |  | 
| 442 |     \warning This will not compare two different symbolic links pointing to | 
| 443 |     the same target. | 
| 444 |  | 
| 445 |     \warning On Windows, long and short paths that refer to the same file | 
| 446 |     system entry are treated as if they referred to different entries. | 
| 447 |  | 
| 448 |     \sa operator!=() | 
| 449 | */ | 
| 450 | bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs) | 
| 451 | { | 
| 452 |     if (rhs.d_ptr == lhs.d_ptr) | 
| 453 |         return true; | 
| 454 |     if (lhs.d_ptr->isDefaultConstructed || rhs.d_ptr->isDefaultConstructed) | 
| 455 |         return false; | 
| 456 |  | 
| 457 |     // Assume files are the same if path is the same | 
| 458 |     if (lhs.d_ptr->fileEntry.filePath() == rhs.d_ptr->fileEntry.filePath()) | 
| 459 |         return true; | 
| 460 |  | 
| 461 |     Qt::CaseSensitivity sensitive; | 
| 462 |     if (lhs.d_ptr->fileEngine == nullptr || rhs.d_ptr->fileEngine == nullptr) { | 
| 463 |         if (lhs.d_ptr->fileEngine != rhs.d_ptr->fileEngine) // one is native, the other is a custom file-engine | 
| 464 |             return false; | 
| 465 |  | 
| 466 |         const bool lhsCaseSensitive = QFileSystemEngine::isCaseSensitive(entry: lhs.d_ptr->fileEntry, data&: lhs.d_ptr->metaData); | 
| 467 |         if (lhsCaseSensitive != QFileSystemEngine::isCaseSensitive(entry: rhs.d_ptr->fileEntry, data&: rhs.d_ptr->metaData)) | 
| 468 |             return false; | 
| 469 |  | 
| 470 |         sensitive = lhsCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; | 
| 471 |     } else { | 
| 472 |         if (lhs.d_ptr->fileEngine->caseSensitive() != rhs.d_ptr->fileEngine->caseSensitive()) | 
| 473 |             return false; | 
| 474 |         sensitive = lhs.d_ptr->fileEngine->caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive; | 
| 475 |     } | 
| 476 |  | 
| 477 |    // Fallback to expensive canonical path computation | 
| 478 |    return lhs.canonicalFilePath().compare(s: rhs.canonicalFilePath(), cs: sensitive) == 0; | 
| 479 | } | 
| 480 |  | 
| 481 | /*! | 
| 482 |     Makes a copy of the given \a fileinfo and assigns it to this QFileInfo. | 
| 483 | */ | 
| 484 | QFileInfo &QFileInfo::operator=(const QFileInfo &fileinfo) | 
| 485 | { | 
| 486 |     d_ptr = fileinfo.d_ptr; | 
| 487 |     return *this; | 
| 488 | } | 
| 489 |  | 
| 490 | /*! | 
| 491 |     \fn void QFileInfo::swap(QFileInfo &other) | 
| 492 |     \since 5.0 | 
| 493 |     \memberswap{file info} | 
| 494 | */ | 
| 495 |  | 
| 496 | /*! | 
| 497 |     Sets the path of the file system entry that this QFileInfo provides | 
| 498 |     information about to \a path that can be absolute or relative. | 
| 499 |  | 
| 500 | //! [absolute-path-unix-windows] | 
| 501 |     On Unix, absolute paths begin with the directory separator \c {'/'}. | 
| 502 |     On Windows, absolute paths begin with a drive specification (for example, | 
| 503 |     \c {D:/}). | 
| 504 | //! [ absolute-path-unix-windows] | 
| 505 |  | 
| 506 | //! [relative-path-note] | 
| 507 |     Relative paths begin with a directory name or a regular file name and | 
| 508 |     specify a file system entry's path relative to the current working | 
| 509 |     directory. | 
| 510 | //! [relative-path-note] | 
| 511 |  | 
| 512 |     Example: | 
| 513 |     \snippet code/src_corelib_io_qfileinfo.cpp 2 | 
| 514 |  | 
| 515 |     \sa isRelative(), QDir::setCurrent(), QDir::isRelativePath() | 
| 516 | */ | 
| 517 | void QFileInfo::setFile(const QString &path) | 
| 518 | { | 
| 519 |     bool caching = d_ptr.constData()->cache_enabled; | 
| 520 |     *this = QFileInfo(path); | 
| 521 |     d_ptr->cache_enabled = caching; | 
| 522 | } | 
| 523 |  | 
| 524 | /*! | 
| 525 |     \overload | 
| 526 |  | 
| 527 |     Sets the file that the QFileInfo provides information about to \a | 
| 528 |     file. | 
| 529 |  | 
| 530 |     If \a file includes a relative path, the QFileInfo will also have | 
| 531 |     a relative path. | 
| 532 |  | 
| 533 |     \sa isRelative() | 
| 534 | */ | 
| 535 | void QFileInfo::setFile(const QFileDevice &file) | 
| 536 | { | 
| 537 |     setFile(file.fileName()); | 
| 538 | } | 
| 539 |  | 
| 540 | /*! | 
| 541 |     \overload | 
| 542 |  | 
| 543 |     Sets the path of the file system entry that this QFileInfo provides | 
| 544 |     information about to \a path in directory \a dir. | 
| 545 |  | 
| 546 |     \include qfileinfo.cpp preserve-relative-or-absolute | 
| 547 |  | 
| 548 |     \sa isRelative() | 
| 549 | */ | 
| 550 | void QFileInfo::setFile(const QDir &dir, const QString &path) | 
| 551 | { | 
| 552 |     setFile(dir.filePath(fileName: path)); | 
| 553 | } | 
| 554 |  | 
| 555 | /*! | 
| 556 |     Returns the absolute full path to the file system entry this QFileInfo | 
| 557 |     refers to, including the entry's name. | 
| 558 |  | 
| 559 |     \include qfileinfo.cpp absolute-path-unix-windows | 
| 560 |  | 
| 561 | //! [windows-network-shares] | 
| 562 |     On Windows, the paths of network shares that are not mapped to a drive | 
| 563 |     letter begin with \c{//sharename/}. | 
| 564 | //! [windows-network-shares] | 
| 565 |  | 
| 566 |     QFileInfo will uppercase drive letters. Note that QDir does not do | 
| 567 |     this. The code snippet below shows this. | 
| 568 |  | 
| 569 |     \snippet code/src_corelib_io_qfileinfo.cpp newstuff | 
| 570 |  | 
| 571 |     This function returns the same as filePath(), unless isRelative() | 
| 572 |     is true. In contrast to canonicalFilePath(), symbolic links or | 
| 573 |     redundant "." or ".." elements are not necessarily removed. | 
| 574 |  | 
| 575 |     \warning If filePath() is empty the behavior of this function | 
| 576 |             is undefined. | 
| 577 |  | 
| 578 |     \sa filePath(), canonicalFilePath(), isRelative() | 
| 579 | */ | 
| 580 | QString QFileInfo::absoluteFilePath() const | 
| 581 | { | 
| 582 |     Q_D(const QFileInfo); | 
| 583 |     if (d->isDefaultConstructed) | 
| 584 |         return ""_L1 ; | 
| 585 |     return d->getFileName(name: QAbstractFileEngine::AbsoluteName); | 
| 586 | } | 
| 587 |  | 
| 588 | /*! | 
| 589 |     Returns the file system entry's canonical path, including the entry's | 
| 590 |     name, that is, an absolute path without symbolic links or redundant | 
| 591 |     \c{'.'} or \c{'..'} elements. | 
| 592 |  | 
| 593 |     If the entry does not exist, canonicalFilePath() returns an empty | 
| 594 |     string. | 
| 595 |  | 
| 596 |     \sa filePath(), absoluteFilePath(), dir() | 
| 597 | */ | 
| 598 | QString QFileInfo::canonicalFilePath() const | 
| 599 | { | 
| 600 |     Q_D(const QFileInfo); | 
| 601 |     if (d->isDefaultConstructed) | 
| 602 |         return ""_L1 ; | 
| 603 |     return d->getFileName(name: QAbstractFileEngine::CanonicalName); | 
| 604 | } | 
| 605 |  | 
| 606 |  | 
| 607 | /*! | 
| 608 |     Returns the absolute path of the file system entry this QFileInfo refers to, | 
| 609 |     excluding the entry's name. | 
| 610 |  | 
| 611 |     \include qfileinfo.cpp absolute-path-unix-windows | 
| 612 |  | 
| 613 |     \include qfileinfo.cpp windows-network-shares | 
| 614 |  | 
| 615 |     In contrast to canonicalPath() symbolic links or redundant "." or | 
| 616 |     ".." elements are not necessarily removed. | 
| 617 |  | 
| 618 |     \warning If filePath() is empty the behavior of this function | 
| 619 |              is undefined. | 
| 620 |  | 
| 621 |     \sa absoluteFilePath(), path(), canonicalPath(), fileName(), isRelative() | 
| 622 | */ | 
| 623 | QString QFileInfo::absolutePath() const | 
| 624 | { | 
| 625 |     Q_D(const QFileInfo); | 
| 626 |  | 
| 627 |     if (d->isDefaultConstructed) | 
| 628 |         return ""_L1 ; | 
| 629 |     return d->getFileName(name: QAbstractFileEngine::AbsolutePathName); | 
| 630 | } | 
| 631 |  | 
| 632 | /*! | 
| 633 |     Returns the file system entry's canonical path (excluding the entry's name), | 
| 634 |     i.e. an absolute path without symbolic links or redundant "." or ".." elements. | 
| 635 |  | 
| 636 |     If the entry does not exist, this method returns an empty string. | 
| 637 |  | 
| 638 |     \sa path(), absolutePath() | 
| 639 | */ | 
| 640 | QString QFileInfo::canonicalPath() const | 
| 641 | { | 
| 642 |     Q_D(const QFileInfo); | 
| 643 |     if (d->isDefaultConstructed) | 
| 644 |         return ""_L1 ; | 
| 645 |     return d->getFileName(name: QAbstractFileEngine::CanonicalPathName); | 
| 646 | } | 
| 647 |  | 
| 648 | /*! | 
| 649 |     Returns the path of the file system entry this QFileInfo refers to, | 
| 650 |     excluding the entry's name. | 
| 651 |  | 
| 652 |     \include qfileinfo.cpp path-ends-with-slash-empty-name-component | 
| 653 |     In this case, this function will return the entire path. | 
| 654 |  | 
| 655 |     \sa filePath(), absolutePath(), canonicalPath(), dir(), fileName(), isRelative() | 
| 656 | */ | 
| 657 | QString QFileInfo::path() const | 
| 658 | { | 
| 659 |     Q_D(const QFileInfo); | 
| 660 |     if (d->isDefaultConstructed) | 
| 661 |         return ""_L1 ; | 
| 662 |     return d->fileEntry.path(); | 
| 663 | } | 
| 664 |  | 
| 665 | /*! | 
| 666 |     \fn bool QFileInfo::isAbsolute() const | 
| 667 |  | 
| 668 |     Returns \c true if the file system entry's path is absolute, otherwise | 
| 669 |     returns \c false (that is, the path is relative). | 
| 670 |  | 
| 671 |     \include qfileinfo.cpp qresource-virtual-fs-colon | 
| 672 |  | 
| 673 |     \sa isRelative() | 
| 674 | */ | 
| 675 |  | 
| 676 | /*! | 
| 677 |     Returns \c true if the file system entry's path is relative, otherwise | 
| 678 |     returns \c false (that is, the path is absolute). | 
| 679 |  | 
| 680 |     \include qfileinfo.cpp absolute-path-unix-windows | 
| 681 |  | 
| 682 |     \include qfileinfo.cpp qresource-virtual-fs-colon | 
| 683 |  | 
| 684 |     \sa isAbsolute() | 
| 685 | */ | 
| 686 | bool QFileInfo::isRelative() const | 
| 687 | { | 
| 688 |     Q_D(const QFileInfo); | 
| 689 |     if (d->isDefaultConstructed) | 
| 690 |         return true; | 
| 691 |     if (d->fileEngine == nullptr) | 
| 692 |         return d->fileEntry.isRelative(); | 
| 693 |     return d->fileEngine->isRelativePath(); | 
| 694 | } | 
| 695 |  | 
| 696 | /*! | 
| 697 |     If the file system entry's path is relative, this method converts it to | 
| 698 |     an absolute path and returns \c true; if the path is already absolute, | 
| 699 |     this method returns \c false. | 
| 700 |  | 
| 701 |     \sa filePath(), isRelative() | 
| 702 | */ | 
| 703 | bool QFileInfo::makeAbsolute() | 
| 704 | { | 
| 705 |     if (d_ptr.constData()->isDefaultConstructed | 
| 706 |             || !d_ptr.constData()->fileEntry.isRelative()) | 
| 707 |         return false; | 
| 708 |  | 
| 709 |     setFile(absoluteFilePath()); | 
| 710 |     return true; | 
| 711 | } | 
| 712 |  | 
| 713 | /*! | 
| 714 |     Returns \c true if the file system entry this QFileInfo refers to exists; | 
| 715 |     otherwise returns \c false. | 
| 716 |  | 
| 717 |     \note If the entry is a symlink that points to a non-existing | 
| 718 |     target, this method returns \c false. | 
| 719 | */ | 
| 720 | bool QFileInfo::exists() const | 
| 721 | { | 
| 722 |     Q_D(const QFileInfo); | 
| 723 |     if (d->isDefaultConstructed) | 
| 724 |         return false; | 
| 725 |     if (d->fileEngine == nullptr) { | 
| 726 |         if (!d->cache_enabled || !d->metaData.hasFlags(flags: QFileSystemMetaData::ExistsAttribute)) | 
| 727 |             QFileSystemEngine::fillMetaData(entry: d->fileEntry, data&: d->metaData, what: QFileSystemMetaData::ExistsAttribute); | 
| 728 |         return d->metaData.exists(); | 
| 729 |     } | 
| 730 |     return d->getFileFlags(request: QAbstractFileEngine::ExistsFlag); | 
| 731 | } | 
| 732 |  | 
| 733 | /*! | 
| 734 |     \since 5.2 | 
| 735 |  | 
| 736 |     Returns \c true if the file system entry \a path exists; otherwise | 
| 737 |     returns \c false. | 
| 738 |  | 
| 739 |     \note If \a path is a symlink that points to a non-existing | 
| 740 |     target, this method returns \c false. | 
| 741 |  | 
| 742 |     \note Using this function is faster than using | 
| 743 |     \c QFileInfo(path).exists() for file system access. | 
| 744 | */ | 
| 745 | bool QFileInfo::exists(const QString &path) | 
| 746 | { | 
| 747 |     if (path.isEmpty()) | 
| 748 |         return false; | 
| 749 |     QFileSystemEntry entry(path); | 
| 750 |     QFileSystemMetaData data; | 
| 751 |     // Expensive fallback to non-QFileSystemEngine implementation | 
| 752 |     if (auto engine = QFileSystemEngine::createLegacyEngine(entry, data)) | 
| 753 |         return QFileInfo(new QFileInfoPrivate(entry, data, std::move(engine))).exists(); | 
| 754 |  | 
| 755 |     QFileSystemEngine::fillMetaData(entry, data, what: QFileSystemMetaData::ExistsAttribute); | 
| 756 |     return data.exists(); | 
| 757 | } | 
| 758 |  | 
| 759 | /*! | 
| 760 |     Refreshes the information about the file system entry this QFileInfo | 
| 761 |     refers to, that is, reads in information from the file system the next | 
| 762 |     time a cached property is fetched. | 
| 763 | */ | 
| 764 | void QFileInfo::refresh() | 
| 765 | { | 
| 766 |     Q_D(QFileInfo); | 
| 767 |     d->clear(); | 
| 768 | } | 
| 769 |  | 
| 770 | /*! | 
| 771 |     Returns the path of the file system entry this QFileInfo refers to; | 
| 772 |     the path may be absolute or relative. | 
| 773 |  | 
| 774 |     \sa absoluteFilePath(), canonicalFilePath(), isRelative() | 
| 775 | */ | 
| 776 | QString QFileInfo::filePath() const | 
| 777 | { | 
| 778 |     Q_D(const QFileInfo); | 
| 779 |     if (d->isDefaultConstructed) | 
| 780 |         return ""_L1 ; | 
| 781 |     return d->fileEntry.filePath(); | 
| 782 | } | 
| 783 |  | 
| 784 | /*! | 
| 785 |     Returns the name of the file system entry this QFileInfo refers to, | 
| 786 |     excluding the path. | 
| 787 |  | 
| 788 |     Example: | 
| 789 |     \snippet code/src_corelib_io_qfileinfo.cpp 3 | 
| 790 |  | 
| 791 | //! [path-ends-with-slash-empty-name-component] | 
| 792 |     \note If this QFileInfo is given a path ending with a directory separator | 
| 793 |     \c{'/'}, the entry's name part is considered empty. | 
| 794 | //! [path-ends-with-slash-empty-name-component] | 
| 795 |  | 
| 796 |     \sa isRelative(), filePath(), baseName(), suffix() | 
| 797 | */ | 
| 798 | QString QFileInfo::fileName() const | 
| 799 | { | 
| 800 |     Q_D(const QFileInfo); | 
| 801 |     if (d->isDefaultConstructed) | 
| 802 |         return ""_L1 ; | 
| 803 |     if (!d->fileEngine) | 
| 804 |         return d->fileEntry.fileName(); | 
| 805 |     return d->fileEngine->fileName(file: QAbstractFileEngine::BaseName); | 
| 806 | } | 
| 807 |  | 
| 808 | /*! | 
| 809 |     \since 4.3 | 
| 810 |     Returns the name of the bundle. | 
| 811 |  | 
| 812 |     On \macos and iOS this returns the proper localized name for a bundle if the | 
| 813 |     path isBundle(). On all other platforms an empty QString is returned. | 
| 814 |  | 
| 815 |     Example: | 
| 816 |     \snippet code/src_corelib_io_qfileinfo.cpp 4 | 
| 817 |  | 
| 818 |     \sa isBundle(), filePath(), baseName(), suffix() | 
| 819 | */ | 
| 820 | QString QFileInfo::bundleName() const | 
| 821 | { | 
| 822 |     Q_D(const QFileInfo); | 
| 823 |     if (d->isDefaultConstructed) | 
| 824 |         return ""_L1 ; | 
| 825 |     return d->getFileName(name: QAbstractFileEngine::BundleName); | 
| 826 | } | 
| 827 |  | 
| 828 | /*! | 
| 829 |     Returns the base name of the file without the path. | 
| 830 |  | 
| 831 |     The base name consists of all characters in the file up to (but | 
| 832 |     not including) the \e first '.' character. | 
| 833 |  | 
| 834 |     Example: | 
| 835 |     \snippet code/src_corelib_io_qfileinfo.cpp 5 | 
| 836 |  | 
| 837 |  | 
| 838 |     The base name of a file is computed equally on all platforms, independent | 
| 839 |     of file naming conventions (e.g., ".bashrc" on Unix has an empty base | 
| 840 |     name, and the suffix is "bashrc"). | 
| 841 |  | 
| 842 |     \sa fileName(), suffix(), completeSuffix(), completeBaseName() | 
| 843 | */ | 
| 844 | QString QFileInfo::baseName() const | 
| 845 | { | 
| 846 |     Q_D(const QFileInfo); | 
| 847 |     if (d->isDefaultConstructed) | 
| 848 |         return ""_L1 ; | 
| 849 |     if (!d->fileEngine) | 
| 850 |         return d->fileEntry.baseName(); | 
| 851 |     return QFileSystemEntry(d->fileEngine->fileName(file: QAbstractFileEngine::BaseName)).baseName(); | 
| 852 | } | 
| 853 |  | 
| 854 | /*! | 
| 855 |     Returns the complete base name of the file without the path. | 
| 856 |  | 
| 857 |     The complete base name consists of all characters in the file up | 
| 858 |     to (but not including) the \e last '.' character. | 
| 859 |  | 
| 860 |     Example: | 
| 861 |     \snippet code/src_corelib_io_qfileinfo.cpp 6 | 
| 862 |  | 
| 863 |     \sa fileName(), suffix(), completeSuffix(), baseName() | 
| 864 | */ | 
| 865 | QString QFileInfo::completeBaseName() const | 
| 866 | { | 
| 867 |     Q_D(const QFileInfo); | 
| 868 |     if (d->isDefaultConstructed) | 
| 869 |         return ""_L1 ; | 
| 870 |     if (!d->fileEngine) | 
| 871 |         return d->fileEntry.completeBaseName(); | 
| 872 |     const QString fileEngineBaseName = d->fileEngine->fileName(file: QAbstractFileEngine::BaseName); | 
| 873 |     return QFileSystemEntry(fileEngineBaseName).completeBaseName(); | 
| 874 | } | 
| 875 |  | 
| 876 | /*! | 
| 877 |     Returns the complete suffix (extension) of the file. | 
| 878 |  | 
| 879 |     The complete suffix consists of all characters in the file after | 
| 880 |     (but not including) the first '.'. | 
| 881 |  | 
| 882 |     Example: | 
| 883 |     \snippet code/src_corelib_io_qfileinfo.cpp 7 | 
| 884 |  | 
| 885 |     \sa fileName(), suffix(), baseName(), completeBaseName() | 
| 886 | */ | 
| 887 | QString QFileInfo::completeSuffix() const | 
| 888 | { | 
| 889 |     Q_D(const QFileInfo); | 
| 890 |     if (d->isDefaultConstructed) | 
| 891 |         return ""_L1 ; | 
| 892 |     return d->fileEntry.completeSuffix(); | 
| 893 | } | 
| 894 |  | 
| 895 | /*! | 
| 896 |     Returns the suffix (extension) of the file. | 
| 897 |  | 
| 898 |     The suffix consists of all characters in the file after (but not | 
| 899 |     including) the last '.'. | 
| 900 |  | 
| 901 |     Example: | 
| 902 |     \snippet code/src_corelib_io_qfileinfo.cpp 8 | 
| 903 |  | 
| 904 |     The suffix of a file is computed equally on all platforms, independent of | 
| 905 |     file naming conventions (e.g., ".bashrc" on Unix has an empty base name, | 
| 906 |     and the suffix is "bashrc"). | 
| 907 |  | 
| 908 |     \sa fileName(), completeSuffix(), baseName(), completeBaseName() | 
| 909 | */ | 
| 910 | QString QFileInfo::suffix() const | 
| 911 | { | 
| 912 |     Q_D(const QFileInfo); | 
| 913 |     if (d->isDefaultConstructed) | 
| 914 |         return ""_L1 ; | 
| 915 |     return d->fileEntry.suffix(); | 
| 916 | } | 
| 917 |  | 
| 918 |  | 
| 919 | /*! | 
| 920 |     Returns a QDir object representing the path of the parent directory of the | 
| 921 |     file system entry that this QFileInfo refers to. | 
| 922 |  | 
| 923 |     \note The QDir returned always corresponds to the object's | 
| 924 |     parent directory, even if the QFileInfo represents a directory. | 
| 925 |  | 
| 926 |     For each of the following, dir() returns the QDir | 
| 927 |     \c{"~/examples/191697"}. | 
| 928 |  | 
| 929 |     \snippet fileinfo/main.cpp 0 | 
| 930 |  | 
| 931 |     For each of the following, dir() returns the QDir | 
| 932 |     \c{"."}. | 
| 933 |  | 
| 934 |     \snippet fileinfo/main.cpp 1 | 
| 935 |  | 
| 936 |     \sa absolutePath(), filePath(), fileName(), isRelative(), absoluteDir() | 
| 937 | */ | 
| 938 | QDir QFileInfo::dir() const | 
| 939 | { | 
| 940 |     Q_D(const QFileInfo); | 
| 941 |     return QDir(d->fileEntry.path()); | 
| 942 | } | 
| 943 |  | 
| 944 | /*! | 
| 945 |     Returns a QDir object representing the absolute path of the parent | 
| 946 |     directory of the file system entry that this QFileInfo refers to. | 
| 947 |  | 
| 948 |     \snippet code/src_corelib_io_qfileinfo.cpp 11 | 
| 949 |  | 
| 950 |     \sa dir(), filePath(), fileName(), isRelative() | 
| 951 | */ | 
| 952 | QDir QFileInfo::absoluteDir() const | 
| 953 | { | 
| 954 |     return QDir(absolutePath()); | 
| 955 | } | 
| 956 |  | 
| 957 | /*! | 
| 958 |     Returns \c true if the user can read the file system entry this QFileInfo | 
| 959 |     refers to; otherwise returns \c false. | 
| 960 |  | 
| 961 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 962 |  | 
| 963 |     \note If the \l{NTFS permissions} check has not been enabled, the result | 
| 964 |     on Windows will merely reflect whether the entry exists. | 
| 965 |  | 
| 966 |     \sa isWritable(), isExecutable(), permission() | 
| 967 | */ | 
| 968 | bool QFileInfo::isReadable() const | 
| 969 | { | 
| 970 |     Q_D(const QFileInfo); | 
| 971 |     return d->checkAttribute<bool>( | 
| 972 |                 fsFlags: QFileSystemMetaData::UserReadPermission, | 
| 973 |                 fsLambda: [d]() { return d->metaData.isReadable(); }, | 
| 974 |                 engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::ReadUserPerm); }); | 
| 975 | } | 
| 976 |  | 
| 977 | /*! | 
| 978 |     Returns \c true if the user can write to the file system entry this | 
| 979 |     QFileInfo refers to; otherwise returns \c false. | 
| 980 |  | 
| 981 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 982 |  | 
| 983 |     \note If the \l{NTFS permissions} check has not been enabled, the result on | 
| 984 |     Windows will merely reflect whether the entry is marked as Read Only. | 
| 985 |  | 
| 986 |     \sa isReadable(), isExecutable(), permission() | 
| 987 | */ | 
| 988 | bool QFileInfo::isWritable() const | 
| 989 | { | 
| 990 |     Q_D(const QFileInfo); | 
| 991 |     return d->checkAttribute<bool>( | 
| 992 |                 fsFlags: QFileSystemMetaData::UserWritePermission, | 
| 993 |                 fsLambda: [d]() { return d->metaData.isWritable(); }, | 
| 994 |                 engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::WriteUserPerm); }); | 
| 995 | } | 
| 996 |  | 
| 997 | /*! | 
| 998 |     Returns \c true if the file system entry this QFileInfo refers to is | 
| 999 |     executable; otherwise returns \c false. | 
| 1000 |  | 
| 1001 | //! [info-about-target-not-symlink] | 
| 1002 |     If the file is a symlink, this function returns information about the | 
| 1003 |     target, not the symlink. | 
| 1004 | //! [info-about-target-not-symlink] | 
| 1005 |  | 
| 1006 |     \sa isReadable(), isWritable(), permission() | 
| 1007 | */ | 
| 1008 | bool QFileInfo::isExecutable() const | 
| 1009 | { | 
| 1010 |     Q_D(const QFileInfo); | 
| 1011 |     return d->checkAttribute<bool>( | 
| 1012 |                 fsFlags: QFileSystemMetaData::UserExecutePermission, | 
| 1013 |                 fsLambda: [d]() { return d->metaData.isExecutable(); }, | 
| 1014 |                 engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::ExeUserPerm); }); | 
| 1015 | } | 
| 1016 |  | 
| 1017 | /*! | 
| 1018 |     Returns \c true if the file system entry this QFileInfo refers to is | 
| 1019 |     `hidden'; otherwise returns \c false. | 
| 1020 |  | 
| 1021 |     \b{Note:} This function returns \c true for the special entries "." and | 
| 1022 |     ".." on Unix, even though QDir::entryList treats them as shown. And note | 
| 1023 |     that, since this function inspects the file name, on Unix it will inspect | 
| 1024 |     the name of the symlink, if this file is a symlink, not the target's name. | 
| 1025 |  | 
| 1026 |     On Windows, this function returns \c true if the target file is hidden (not | 
| 1027 |     the symlink). | 
| 1028 | */ | 
| 1029 | bool QFileInfo::isHidden() const | 
| 1030 | { | 
| 1031 |     Q_D(const QFileInfo); | 
| 1032 |     return d->checkAttribute<bool>( | 
| 1033 |                 fsFlags: QFileSystemMetaData::HiddenAttribute, | 
| 1034 |                 fsLambda: [d]() { return d->metaData.isHidden(); }, | 
| 1035 |                 engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::HiddenFlag); }); | 
| 1036 | } | 
| 1037 |  | 
| 1038 | /*! | 
| 1039 |     \since 5.0 | 
| 1040 |     Returns \c true if the file path can be used directly with native APIs. | 
| 1041 |     Returns \c false if the file is otherwise supported by a virtual file system | 
| 1042 |     inside Qt, such as \l{the Qt Resource System}. | 
| 1043 |  | 
| 1044 |     \b{Note:} Native paths may still require conversion of path separators | 
| 1045 |     and character encoding, depending on platform and input requirements of the | 
| 1046 |     native API. | 
| 1047 |  | 
| 1048 |     \sa QDir::toNativeSeparators(), QFile::encodeName(), filePath(), | 
| 1049 |     absoluteFilePath(), canonicalFilePath() | 
| 1050 | */ | 
| 1051 | bool QFileInfo::isNativePath() const | 
| 1052 | { | 
| 1053 |     Q_D(const QFileInfo); | 
| 1054 |     if (d->isDefaultConstructed) | 
| 1055 |         return false; | 
| 1056 |     if (d->fileEngine == nullptr) | 
| 1057 |         return true; | 
| 1058 |     return d->getFileFlags(request: QAbstractFileEngine::LocalDiskFlag); | 
| 1059 | } | 
| 1060 |  | 
| 1061 | /*! | 
| 1062 |     Returns \c true if this object points to a file or to a symbolic | 
| 1063 |     link to a file. Returns \c false if the | 
| 1064 |     object points to something that is not a file (such as a directory) | 
| 1065 |     or that does not exist. | 
| 1066 |  | 
| 1067 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1068 |  | 
| 1069 |     \sa isDir(), isSymLink(), isBundle() | 
| 1070 | */ | 
| 1071 | bool QFileInfo::isFile() const | 
| 1072 | { | 
| 1073 |     Q_D(const QFileInfo); | 
| 1074 |     return d->checkAttribute<bool>( | 
| 1075 |                 fsFlags: QFileSystemMetaData::FileType, | 
| 1076 |                 fsLambda: [d]() { return d->metaData.isFile(); }, | 
| 1077 |                 engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::FileType); }); | 
| 1078 | } | 
| 1079 |  | 
| 1080 | /*! | 
| 1081 |     Returns \c true if this object points to a directory or to a symbolic | 
| 1082 |     link to a directory. Returns \c false if the | 
| 1083 |     object points to something that is not a directory (such as a file) | 
| 1084 |     or that does not exist. | 
| 1085 |  | 
| 1086 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1087 |  | 
| 1088 |     \sa isFile(), isSymLink(), isBundle() | 
| 1089 | */ | 
| 1090 | bool QFileInfo::isDir() const | 
| 1091 | { | 
| 1092 |     Q_D(const QFileInfo); | 
| 1093 |     return d->checkAttribute<bool>( | 
| 1094 |                 fsFlags: QFileSystemMetaData::DirectoryType, | 
| 1095 |                 fsLambda: [d]() { return d->metaData.isDirectory(); }, | 
| 1096 |                 engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::DirectoryType); }); | 
| 1097 | } | 
| 1098 |  | 
| 1099 |  | 
| 1100 | /*! | 
| 1101 |     \since 4.3 | 
| 1102 |     Returns \c true if this object points to a bundle or to a symbolic | 
| 1103 |     link to a bundle on \macos and iOS; otherwise returns \c false. | 
| 1104 |  | 
| 1105 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1106 |  | 
| 1107 |     \sa isDir(), isSymLink(), isFile() | 
| 1108 | */ | 
| 1109 | bool QFileInfo::isBundle() const | 
| 1110 | { | 
| 1111 |     Q_D(const QFileInfo); | 
| 1112 |     return d->checkAttribute<bool>( | 
| 1113 |                 fsFlags: QFileSystemMetaData::BundleType, | 
| 1114 |                 fsLambda: [d]() { return d->metaData.isBundle(); }, | 
| 1115 |                 engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::BundleType); }); | 
| 1116 | } | 
| 1117 |  | 
| 1118 | /*! | 
| 1119 |     Returns \c true if this object points to a symbolic link, shortcut, | 
| 1120 |     or alias; otherwise returns \c false. | 
| 1121 |  | 
| 1122 |     Symbolic links exist on Unix (including \macos and iOS) and Windows | 
| 1123 |     and are typically created by the \c{ln -s} or \c{mklink} commands, | 
| 1124 |     respectively. Opening a symbolic link effectively opens | 
| 1125 |     the \l{symLinkTarget()}{link's target}. | 
| 1126 |  | 
| 1127 |     In addition, true will be returned for shortcuts (\c *.lnk files) on | 
| 1128 |     Windows, and aliases on \macos. This behavior is deprecated and will | 
| 1129 |     likely change in a future version of Qt. Opening a shortcut or alias | 
| 1130 |     will open the \c .lnk or alias file itself. | 
| 1131 |  | 
| 1132 |     Example: | 
| 1133 |  | 
| 1134 |     \snippet code/src_corelib_io_qfileinfo.cpp 9 | 
| 1135 |  | 
| 1136 | //! [symlink-target-exists-behavior] | 
| 1137 |     \note exists() returns \c true if the symlink points to an existing | 
| 1138 |     target, otherwise it returns \c false. | 
| 1139 | //! [symlink-target-exists-behavior] | 
| 1140 |  | 
| 1141 |     \sa isFile(), isDir(), symLinkTarget() | 
| 1142 | */ | 
| 1143 | bool QFileInfo::isSymLink() const | 
| 1144 | { | 
| 1145 |     Q_D(const QFileInfo); | 
| 1146 |     return d->checkAttribute<bool>( | 
| 1147 |                 fsFlags: QFileSystemMetaData::LegacyLinkType, | 
| 1148 |                 fsLambda: [d]() { return d->metaData.isLegacyLink(); }, | 
| 1149 |                 engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::LinkType); }); | 
| 1150 | } | 
| 1151 |  | 
| 1152 | /*! | 
| 1153 |     Returns \c true if this object points to a symbolic link; | 
| 1154 |     otherwise returns \c false. | 
| 1155 |  | 
| 1156 |     Symbolic links exist on Unix (including \macos and iOS) and Windows | 
| 1157 |     (NTFS-symlink) and are typically created by the \c{ln -s} or \c{mklink} | 
| 1158 |     commands, respectively. | 
| 1159 |  | 
| 1160 |     Unix handles symlinks transparently. Opening a symbolic link effectively | 
| 1161 |     opens the \l{symLinkTarget()}{link's target}. | 
| 1162 |  | 
| 1163 |     In contrast to isSymLink(), false will be returned for shortcuts | 
| 1164 |     (\c *.lnk files) on Windows and aliases on \macos. Use QFileInfo::isShortcut() | 
| 1165 |     and QFileInfo::isAlias() instead. | 
| 1166 |  | 
| 1167 |     \include qfileinfo.cpp symlink-target-exists-behavior | 
| 1168 |  | 
| 1169 |     \sa isFile(), isDir(), isShortcut(), symLinkTarget() | 
| 1170 | */ | 
| 1171 |  | 
| 1172 | bool QFileInfo::isSymbolicLink() const | 
| 1173 | { | 
| 1174 |     Q_D(const QFileInfo); | 
| 1175 |     return d->checkAttribute<bool>( | 
| 1176 |                 fsFlags: QFileSystemMetaData::LegacyLinkType, | 
| 1177 |                 fsLambda: [d]() { return d->metaData.isLink(); }, | 
| 1178 |                 engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::LinkType); }); | 
| 1179 | } | 
| 1180 |  | 
| 1181 | /*! | 
| 1182 |     Returns \c true if this object points to a shortcut; | 
| 1183 |     otherwise returns \c false. | 
| 1184 |  | 
| 1185 |     Shortcuts only exist on Windows and are typically \c .lnk files. | 
| 1186 |     For instance, true will be returned for shortcuts (\c *.lnk files) on | 
| 1187 |     Windows, but false will be returned on Unix (including \macos and iOS). | 
| 1188 |  | 
| 1189 |     The shortcut (.lnk) files are treated as regular files. Opening those will | 
| 1190 |     open the \c .lnk file itself. In order to open the file a shortcut | 
| 1191 |     references to, it must uses symLinkTarget() on a shortcut. | 
| 1192 |  | 
| 1193 |     \note Even if a shortcut (broken shortcut) points to a non existing file, | 
| 1194 |     isShortcut() returns true. | 
| 1195 |  | 
| 1196 |     \sa isFile(), isDir(), isSymbolicLink(), symLinkTarget() | 
| 1197 | */ | 
| 1198 | bool QFileInfo::isShortcut() const | 
| 1199 | { | 
| 1200 |     Q_D(const QFileInfo); | 
| 1201 |     return d->checkAttribute<bool>( | 
| 1202 |             fsFlags: QFileSystemMetaData::LegacyLinkType, | 
| 1203 |             fsLambda: [d]() { return d->metaData.isLnkFile(); }, | 
| 1204 |             engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::LinkType); }); | 
| 1205 | } | 
| 1206 |  | 
| 1207 | /*! | 
| 1208 |     Returns \c true if this object points to an alias; | 
| 1209 |     otherwise returns \c false. | 
| 1210 |  | 
| 1211 |     \since 6.4 | 
| 1212 |  | 
| 1213 |     Aliases only exist on \macos. They are treated as regular files, so | 
| 1214 |     opening an alias will open the file itself. In order to open the file | 
| 1215 |     or directory an alias references use symLinkTarget(). | 
| 1216 |  | 
| 1217 |     \note Even if an alias points to a non existing file, | 
| 1218 |     isAlias() returns true. | 
| 1219 |  | 
| 1220 |     \sa isFile(), isDir(), isSymLink(), symLinkTarget() | 
| 1221 | */ | 
| 1222 | bool QFileInfo::isAlias() const | 
| 1223 | { | 
| 1224 |     Q_D(const QFileInfo); | 
| 1225 |     return d->checkAttribute<bool>( | 
| 1226 |             fsFlags: QFileSystemMetaData::LegacyLinkType, | 
| 1227 |             fsLambda: [d]() { return d->metaData.isAlias(); }, | 
| 1228 |             engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::LinkType); }); | 
| 1229 | } | 
| 1230 |  | 
| 1231 | /*! | 
| 1232 |     \since 5.15 | 
| 1233 |  | 
| 1234 |     Returns \c true if the object points to a junction; | 
| 1235 |     otherwise returns \c false. | 
| 1236 |  | 
| 1237 |     Junctions only exist on Windows' NTFS file system, and are typically | 
| 1238 |     created by the \c{mklink} command. They can be thought of as symlinks for | 
| 1239 |     directories, and can only be created for absolute paths on the local | 
| 1240 |     volume. | 
| 1241 | */ | 
| 1242 | bool QFileInfo::isJunction() const | 
| 1243 | { | 
| 1244 |     Q_D(const QFileInfo); | 
| 1245 |     return d->checkAttribute<bool>( | 
| 1246 |             fsFlags: QFileSystemMetaData::LegacyLinkType, | 
| 1247 |             fsLambda: [d]() { return d->metaData.isJunction(); }, | 
| 1248 |             engineLambda: [d]() { return d->getFileFlags(request: QAbstractFileEngine::LinkType); }); | 
| 1249 | } | 
| 1250 |  | 
| 1251 | /*! | 
| 1252 |     Returns \c true if the object points to a directory or to a symbolic | 
| 1253 |     link to a directory, and that directory is the root directory; otherwise | 
| 1254 |     returns \c false. | 
| 1255 | */ | 
| 1256 | bool QFileInfo::isRoot() const | 
| 1257 | { | 
| 1258 |     Q_D(const QFileInfo); | 
| 1259 |     if (d->isDefaultConstructed) | 
| 1260 |         return false; | 
| 1261 |     if (d->fileEngine == nullptr) { | 
| 1262 |         if (d->fileEntry.isRoot()) { | 
| 1263 | #if defined(Q_OS_WIN) | 
| 1264 |             //the path is a drive root, but the drive may not exist | 
| 1265 |             //for backward compatibility, return true only if the drive exists | 
| 1266 |             if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute)) | 
| 1267 |                 QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ExistsAttribute); | 
| 1268 |             return d->metaData.exists(); | 
| 1269 | #else | 
| 1270 |             return true; | 
| 1271 | #endif | 
| 1272 |         } | 
| 1273 |         return false; | 
| 1274 |     } | 
| 1275 |     return d->getFileFlags(request: QAbstractFileEngine::RootFlag); | 
| 1276 | } | 
| 1277 |  | 
| 1278 | /*! | 
| 1279 |     \since 4.2 | 
| 1280 |  | 
| 1281 |     Returns the absolute path to the file or directory a symbolic link | 
| 1282 |     points to, or an empty string if the object isn't a symbolic | 
| 1283 |     link. | 
| 1284 |  | 
| 1285 |     This name may not represent an existing file; it is only a string. | 
| 1286 |  | 
| 1287 |     \include qfileinfo.cpp symlink-target-exists-behavior | 
| 1288 |  | 
| 1289 |     \sa exists(), isSymLink(), isDir(), isFile() | 
| 1290 | */ | 
| 1291 | QString QFileInfo::symLinkTarget() const | 
| 1292 | { | 
| 1293 |     Q_D(const QFileInfo); | 
| 1294 |     if (d->isDefaultConstructed) | 
| 1295 |         return ""_L1 ; | 
| 1296 |     return d->getFileName(name: QAbstractFileEngine::AbsoluteLinkTarget); | 
| 1297 | } | 
| 1298 |  | 
| 1299 | /*! | 
| 1300 |     \since 6.6 | 
| 1301 |     Read the path the symlink references. | 
| 1302 |  | 
| 1303 |     Returns the raw path referenced by the symbolic link, without resolving a relative | 
| 1304 |     path relative to the directory containing the symbolic link. The returned string will | 
| 1305 |     only be an absolute path if the symbolic link actually references it as such. Returns | 
| 1306 |     an empty string if the object is not a symbolic link. | 
| 1307 |  | 
| 1308 |     \sa symLinkTarget(), exists(), isSymLink(), isDir(), isFile() | 
| 1309 | */ | 
| 1310 | QString QFileInfo::readSymLink() const | 
| 1311 | { | 
| 1312 |     Q_D(const QFileInfo); | 
| 1313 |     if (d->isDefaultConstructed) | 
| 1314 |         return {}; | 
| 1315 |     return d->getFileName(name: QAbstractFileEngine::RawLinkPath); | 
| 1316 | } | 
| 1317 |  | 
| 1318 | /*! | 
| 1319 |     \since 6.2 | 
| 1320 |  | 
| 1321 |     Resolves an NTFS junction to the path it references. | 
| 1322 |  | 
| 1323 |     Returns the absolute path to the directory an NTFS junction points to, or | 
| 1324 |     an empty string if the object is not an NTFS junction. | 
| 1325 |  | 
| 1326 |     There is no guarantee that the directory named by the NTFS junction actually | 
| 1327 |     exists. | 
| 1328 |  | 
| 1329 |     \sa isJunction(), isFile(), isDir(), isSymLink(), isSymbolicLink(), | 
| 1330 |         isShortcut() | 
| 1331 | */ | 
| 1332 | QString QFileInfo::junctionTarget() const | 
| 1333 | { | 
| 1334 |     Q_D(const QFileInfo); | 
| 1335 |     if (d->isDefaultConstructed) | 
| 1336 |         return ""_L1 ; | 
| 1337 |     return d->getFileName(name: QAbstractFileEngine::JunctionName); | 
| 1338 | } | 
| 1339 |  | 
| 1340 | /*! | 
| 1341 |     Returns the owner of the file. On systems where files | 
| 1342 |     do not have owners, or if an error occurs, an empty string is | 
| 1343 |     returned. | 
| 1344 |  | 
| 1345 |     This function can be time consuming under Unix (in the order of | 
| 1346 |     milliseconds). On Windows, it will return an empty string unless | 
| 1347 |     the \l{NTFS permissions} check has been enabled. | 
| 1348 |  | 
| 1349 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1350 |  | 
| 1351 |     \sa ownerId(), group(), groupId() | 
| 1352 | */ | 
| 1353 | QString QFileInfo::owner() const | 
| 1354 | { | 
| 1355 |     Q_D(const QFileInfo); | 
| 1356 |     if (d->isDefaultConstructed) | 
| 1357 |         return ""_L1 ; | 
| 1358 |     return d->getFileOwner(own: QAbstractFileEngine::OwnerUser); | 
| 1359 | } | 
| 1360 |  | 
| 1361 | /*! | 
| 1362 |     Returns the id of the owner of the file. | 
| 1363 |  | 
| 1364 |     On Windows and on systems where files do not have owners this | 
| 1365 |     function returns ((uint) -2). | 
| 1366 |  | 
| 1367 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1368 |  | 
| 1369 |     \sa owner(), group(), groupId() | 
| 1370 | */ | 
| 1371 | uint QFileInfo::ownerId() const | 
| 1372 | { | 
| 1373 |     Q_D(const QFileInfo); | 
| 1374 |     return d->checkAttribute(defaultValue: uint(-2), | 
| 1375 |                 fsFlags: QFileSystemMetaData::UserId, | 
| 1376 |                 fsLambda: [d]() { return d->metaData.userId(); }, | 
| 1377 |                 engineLambda: [d]() { return d->fileEngine->ownerId(QAbstractFileEngine::OwnerUser); }); | 
| 1378 | } | 
| 1379 |  | 
| 1380 | /*! | 
| 1381 |     Returns the group of the file. On Windows, on systems where files | 
| 1382 |     do not have groups, or if an error occurs, an empty string is | 
| 1383 |     returned. | 
| 1384 |  | 
| 1385 |     This function can be time consuming under Unix (in the order of | 
| 1386 |     milliseconds). | 
| 1387 |  | 
| 1388 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1389 |  | 
| 1390 |     \sa groupId(), owner(), ownerId() | 
| 1391 | */ | 
| 1392 | QString QFileInfo::group() const | 
| 1393 | { | 
| 1394 |     Q_D(const QFileInfo); | 
| 1395 |     if (d->isDefaultConstructed) | 
| 1396 |         return ""_L1 ; | 
| 1397 |     return d->getFileOwner(own: QAbstractFileEngine::OwnerGroup); | 
| 1398 | } | 
| 1399 |  | 
| 1400 | /*! | 
| 1401 |     Returns the id of the group the file belongs to. | 
| 1402 |  | 
| 1403 |     On Windows and on systems where files do not have groups this | 
| 1404 |     function always returns (uint) -2. | 
| 1405 |  | 
| 1406 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1407 |  | 
| 1408 |     \sa group(), owner(), ownerId() | 
| 1409 | */ | 
| 1410 | uint QFileInfo::groupId() const | 
| 1411 | { | 
| 1412 |     Q_D(const QFileInfo); | 
| 1413 |     return d->checkAttribute(defaultValue: uint(-2), | 
| 1414 |                 fsFlags: QFileSystemMetaData::GroupId, | 
| 1415 |                 fsLambda: [d]() { return d->metaData.groupId(); }, | 
| 1416 |                 engineLambda: [d]() { return d->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup); }); | 
| 1417 | } | 
| 1418 |  | 
| 1419 | /*! | 
| 1420 |     Tests for file permissions. The \a permissions argument can be | 
| 1421 |     several flags of type QFile::Permissions OR-ed together to check | 
| 1422 |     for permission combinations. | 
| 1423 |  | 
| 1424 |     On systems where files do not have permissions this function | 
| 1425 |     always returns \c true. | 
| 1426 |  | 
| 1427 |     \note The result might be inaccurate on Windows if the | 
| 1428 |     \l{NTFS permissions} check has not been enabled. | 
| 1429 |  | 
| 1430 |     Example: | 
| 1431 |     \snippet code/src_corelib_io_qfileinfo.cpp 10 | 
| 1432 |  | 
| 1433 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1434 |  | 
| 1435 |     \sa isReadable(), isWritable(), isExecutable() | 
| 1436 | */ | 
| 1437 | bool QFileInfo::permission(QFile::Permissions permissions) const | 
| 1438 | { | 
| 1439 |     Q_D(const QFileInfo); | 
| 1440 |     // the QFileSystemMetaData::MetaDataFlag and QFile::Permissions overlap, so just cast. | 
| 1441 |     auto fseFlags = QFileSystemMetaData::MetaDataFlags::fromInt(i: permissions.toInt()); | 
| 1442 |     auto feFlags = QAbstractFileEngine::FileFlags::fromInt(i: permissions.toInt()); | 
| 1443 |     return d->checkAttribute<bool>( | 
| 1444 |                 fsFlags: fseFlags, | 
| 1445 |                 fsLambda: [=]() { return (d->metaData.permissions() & permissions) == permissions; }, | 
| 1446 |         engineLambda: [=]() { | 
| 1447 |             return d->getFileFlags(request: feFlags) == uint(permissions.toInt()); | 
| 1448 |         }); | 
| 1449 | } | 
| 1450 |  | 
| 1451 | /*! | 
| 1452 |     Returns the complete OR-ed together combination of | 
| 1453 |     QFile::Permissions for the file. | 
| 1454 |  | 
| 1455 |     \note The result might be inaccurate on Windows if the | 
| 1456 |     \l{NTFS permissions} check has not been enabled. | 
| 1457 |  | 
| 1458 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1459 | */ | 
| 1460 | QFile::Permissions QFileInfo::permissions() const | 
| 1461 | { | 
| 1462 |     Q_D(const QFileInfo); | 
| 1463 |     return d->checkAttribute<QFile::Permissions>( | 
| 1464 |                 fsFlags: QFileSystemMetaData::Permissions, | 
| 1465 |                 fsLambda: [d]() { return d->metaData.permissions(); }, | 
| 1466 |         engineLambda: [d]() { | 
| 1467 |             return QFile::Permissions(d->getFileFlags(request: QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask); | 
| 1468 |         }); | 
| 1469 | } | 
| 1470 |  | 
| 1471 |  | 
| 1472 | /*! | 
| 1473 |     Returns the file size in bytes. If the file does not exist or cannot be | 
| 1474 |     fetched, 0 is returned. | 
| 1475 |  | 
| 1476 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1477 |  | 
| 1478 |     \sa exists() | 
| 1479 | */ | 
| 1480 | qint64 QFileInfo::size() const | 
| 1481 | { | 
| 1482 |     Q_D(const QFileInfo); | 
| 1483 |     return d->checkAttribute<qint64>( | 
| 1484 |                 fsFlags: QFileSystemMetaData::SizeAttribute, | 
| 1485 |                 fsLambda: [d]() { return d->metaData.size(); }, | 
| 1486 |         engineLambda: [d]() { | 
| 1487 |             if (!d->getCachedFlag(c: QFileInfoPrivate::CachedSize)) { | 
| 1488 |                 d->setCachedFlag(QFileInfoPrivate::CachedSize); | 
| 1489 |                 d->fileSize = d->fileEngine->size(); | 
| 1490 |             } | 
| 1491 |             return d->fileSize; | 
| 1492 |         }); | 
| 1493 | } | 
| 1494 |  | 
| 1495 | /*! | 
| 1496 |     \fn QDateTime QFileInfo::birthTime() const | 
| 1497 |  | 
| 1498 |     Returns the date and time when the file was created (born), in local time. | 
| 1499 |  | 
| 1500 |     If the file birth time is not available, this function returns an invalid QDateTime. | 
| 1501 |  | 
| 1502 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1503 |  | 
| 1504 |     This function overloads QFileInfo::birthTime(const QTimeZone &tz), and | 
| 1505 |     returns the same as \c{birthTime(QTimeZone::LocalTime)}. | 
| 1506 |  | 
| 1507 |     \since 5.10 | 
| 1508 |     \sa lastModified(), lastRead(), metadataChangeTime(), fileTime() | 
| 1509 | */ | 
| 1510 |  | 
| 1511 | /*! | 
| 1512 |     \fn QDateTime QFileInfo::birthTime(const QTimeZone &tz) const | 
| 1513 |  | 
| 1514 |     Returns the date and time when the file was created (born). | 
| 1515 |  | 
| 1516 |     \include qfileinfo.cpp file-times-in-time-zone | 
| 1517 |  | 
| 1518 |     If the file birth time is not available, this function returns an invalid | 
| 1519 |     QDateTime. | 
| 1520 |  | 
| 1521 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1522 |  | 
| 1523 |     \since 6.6 | 
| 1524 |     \sa lastModified(const QTimeZone &), lastRead(const QTimeZone &), | 
| 1525 |         metadataChangeTime(const QTimeZone &), | 
| 1526 |         fileTime(QFileDevice::FileTime, const QTimeZone &) | 
| 1527 | */ | 
| 1528 |  | 
| 1529 | /*! | 
| 1530 |     \fn QDateTime QFileInfo::metadataChangeTime() const | 
| 1531 |  | 
| 1532 |     Returns the date and time when the file's metadata was last changed, | 
| 1533 |     in local time. | 
| 1534 |  | 
| 1535 |     A metadata change occurs when the file is first created, but it also | 
| 1536 |     occurs whenever the user writes or sets inode information (for example, | 
| 1537 |     changing the file permissions). | 
| 1538 |  | 
| 1539 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1540 |  | 
| 1541 |     This function overloads QFileInfo::metadataChangeTime(const QTimeZone &tz), | 
| 1542 |     and returns the same as \c{metadataChangeTime(QTimeZone::LocalTime)}. | 
| 1543 |  | 
| 1544 |     \since 5.10 | 
| 1545 |     \sa birthTime(), lastModified(), lastRead(), fileTime() | 
| 1546 | */ | 
| 1547 |  | 
| 1548 | /*! | 
| 1549 |     \fn QDateTime QFileInfo::metadataChangeTime(const QTimeZone &tz) const | 
| 1550 |  | 
| 1551 |     Returns the date and time when the file's metadata was last changed. | 
| 1552 |     A metadata change occurs when the file is first created, but it also | 
| 1553 |     occurs whenever the user writes or sets inode information (for example, | 
| 1554 |     changing the file permissions). | 
| 1555 |  | 
| 1556 |     \include qfileinfo.cpp file-times-in-time-zone | 
| 1557 |  | 
| 1558 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1559 |  | 
| 1560 |     \since 6.6 | 
| 1561 |     \sa birthTime(const QTimeZone &), lastModified(const QTimeZone &), | 
| 1562 |         lastRead(const QTimeZone &), | 
| 1563 |         fileTime(QFileDevice::FileTime time, const QTimeZone &) | 
| 1564 | */ | 
| 1565 |  | 
| 1566 | /*! | 
| 1567 |     \fn QDateTime QFileInfo::lastModified() const | 
| 1568 |  | 
| 1569 |     Returns the date and time when the file was last modified. | 
| 1570 |  | 
| 1571 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1572 |  | 
| 1573 |     This function overloads \l{QFileInfo::lastModified(const QTimeZone &)}, | 
| 1574 |     and returns the same as \c{lastModified(QTimeZone::LocalTime)}. | 
| 1575 |  | 
| 1576 |     \sa birthTime(), lastRead(), metadataChangeTime(), fileTime() | 
| 1577 | */ | 
| 1578 |  | 
| 1579 | /*! | 
| 1580 |     \fn QDateTime QFileInfo::lastModified(const QTimeZone &tz) const | 
| 1581 |  | 
| 1582 |     Returns the date and time when the file was last modified. | 
| 1583 |  | 
| 1584 |     \include qfileinfo.cpp file-times-in-time-zone | 
| 1585 |  | 
| 1586 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1587 |  | 
| 1588 |     \since 6.6 | 
| 1589 |     \sa birthTime(const QTimeZone &), lastRead(const QTimeZone &), | 
| 1590 |         metadataChangeTime(const QTimeZone &), | 
| 1591 |         fileTime(QFileDevice::FileTime, const QTimeZone &) | 
| 1592 | */ | 
| 1593 |  | 
| 1594 | /*! | 
| 1595 |     \fn QDateTime QFileInfo::lastRead() const | 
| 1596 |  | 
| 1597 |     Returns the date and time when the file was last read (accessed). | 
| 1598 |  | 
| 1599 |     On platforms where this information is not available, returns the same | 
| 1600 |     time as lastModified(). | 
| 1601 |  | 
| 1602 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1603 |  | 
| 1604 |     This function overloads \l{QFileInfo::lastRead(const QTimeZone &)}, | 
| 1605 |     and returns the same as \c{lastRead(QTimeZone::LocalTime)}. | 
| 1606 |  | 
| 1607 |     \sa birthTime(), lastModified(), metadataChangeTime(), fileTime() | 
| 1608 | */ | 
| 1609 |  | 
| 1610 | /*! | 
| 1611 |     \fn QDateTime QFileInfo::lastRead(const QTimeZone &tz) const | 
| 1612 |  | 
| 1613 |     Returns the date and time when the file was last read (accessed). | 
| 1614 |  | 
| 1615 |     \include qfileinfo.cpp file-times-in-time-zone | 
| 1616 |  | 
| 1617 |     On platforms where this information is not available, returns the same | 
| 1618 |     time as lastModified(). | 
| 1619 |  | 
| 1620 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1621 |  | 
| 1622 |     \since 6.6 | 
| 1623 |     \sa birthTime(const QTimeZone &), lastModified(const QTimeZone &), | 
| 1624 |         metadataChangeTime(const QTimeZone &), | 
| 1625 |         fileTime(QFileDevice::FileTime, const QTimeZone &) | 
| 1626 | */ | 
| 1627 |  | 
| 1628 | #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED) | 
| 1629 | /*! | 
| 1630 |     Returns the file time specified by \a time. | 
| 1631 |  | 
| 1632 |     If the time cannot be determined, an invalid date time is returned. | 
| 1633 |  | 
| 1634 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1635 |  | 
| 1636 |     This function overloads | 
| 1637 |     \l{QFileInfo::fileTime(QFileDevice::FileTime, const QTimeZone &)}, | 
| 1638 |     and returns the same as \c{fileTime(time, QTimeZone::LocalTime)}. | 
| 1639 |  | 
| 1640 |     \since 5.10 | 
| 1641 |     \sa birthTime(), lastModified(), lastRead(), metadataChangeTime() | 
| 1642 | */ | 
| 1643 | QDateTime QFileInfo::fileTime(QFile::FileTime time) const { | 
| 1644 |     return fileTime(time, tz: QTimeZone::LocalTime); | 
| 1645 | } | 
| 1646 | #endif | 
| 1647 |  | 
| 1648 | /*! | 
| 1649 |     Returns the file time specified by \a time. | 
| 1650 |  | 
| 1651 | //! [file-times-in-time-zone] | 
| 1652 |     The returned time is in the time zone specified by \a tz. For example, | 
| 1653 |     you can use QTimeZone::LocalTime or QTimeZone::UTC to get the time in | 
| 1654 |     the Local time zone or UTC, respectively. Since native file system API | 
| 1655 |     typically uses UTC, using QTimeZone::UTC is often faster, as it does not | 
| 1656 |     require any conversions. | 
| 1657 | //! [file-times-in-time-zone] | 
| 1658 |  | 
| 1659 |     If the time cannot be determined, an invalid date time is returned. | 
| 1660 |  | 
| 1661 |     \include qfileinfo.cpp info-about-target-not-symlink | 
| 1662 |  | 
| 1663 |     \since 6.6 | 
| 1664 |     \sa birthTime(const QTimeZone &), lastModified(const QTimeZone &), | 
| 1665 |         lastRead(const QTimeZone &), metadataChangeTime(const QTimeZone &), | 
| 1666 |         QDateTime::isValid() | 
| 1667 | */ | 
| 1668 | QDateTime QFileInfo::fileTime(QFile::FileTime time, const QTimeZone &tz) const | 
| 1669 | { | 
| 1670 |     Q_D(const QFileInfo); | 
| 1671 |     QFileSystemMetaData::MetaDataFlags flag; | 
| 1672 |     switch (time) { | 
| 1673 |     case QFile::FileAccessTime: | 
| 1674 |         flag = QFileSystemMetaData::AccessTime; | 
| 1675 |         break; | 
| 1676 |     case QFile::FileBirthTime: | 
| 1677 |         flag = QFileSystemMetaData::BirthTime; | 
| 1678 |         break; | 
| 1679 |     case QFile::FileMetadataChangeTime: | 
| 1680 |         flag = QFileSystemMetaData::MetadataChangeTime; | 
| 1681 |         break; | 
| 1682 |     case QFile::FileModificationTime: | 
| 1683 |         flag = QFileSystemMetaData::ModificationTime; | 
| 1684 |         break; | 
| 1685 |     } | 
| 1686 |  | 
| 1687 |     auto fsLambda = [d, time]() { return d->metaData.fileTime(time); }; | 
| 1688 |     auto engineLambda = [d, time]() { return d->getFileTime(request: time); }; | 
| 1689 |     const auto dt = | 
| 1690 |         d->checkAttribute<QDateTime>(fsFlags: flag, fsLambda: std::move(fsLambda), engineLambda: std::move(engineLambda)); | 
| 1691 |     return dt.toTimeZone(toZone: tz); | 
| 1692 | } | 
| 1693 |  | 
| 1694 | /*! | 
| 1695 |     \internal | 
| 1696 | */ | 
| 1697 | QFileInfoPrivate* QFileInfo::d_func() | 
| 1698 | { | 
| 1699 |     return d_ptr.data(); | 
| 1700 | } | 
| 1701 |  | 
| 1702 | /*! | 
| 1703 |     Returns \c true if caching is enabled; otherwise returns \c false. | 
| 1704 |  | 
| 1705 |     \sa setCaching(), refresh() | 
| 1706 | */ | 
| 1707 | bool QFileInfo::caching() const | 
| 1708 | { | 
| 1709 |     Q_D(const QFileInfo); | 
| 1710 |     return d->cache_enabled; | 
| 1711 | } | 
| 1712 |  | 
| 1713 | /*! | 
| 1714 |     If \a enable is true, enables caching of file information. If \a | 
| 1715 |     enable is false caching is disabled. | 
| 1716 |  | 
| 1717 |     When caching is enabled, QFileInfo reads the file information from | 
| 1718 |     the file system the first time it's needed, but generally not | 
| 1719 |     later. | 
| 1720 |  | 
| 1721 |     Caching is enabled by default. | 
| 1722 |  | 
| 1723 |     \sa refresh(), caching() | 
| 1724 | */ | 
| 1725 | void QFileInfo::setCaching(bool enable) | 
| 1726 | { | 
| 1727 |     Q_D(QFileInfo); | 
| 1728 |     d->cache_enabled = enable; | 
| 1729 | } | 
| 1730 |  | 
| 1731 | /*! | 
| 1732 |     Reads all attributes from the file system. | 
| 1733 |     \since 6.0 | 
| 1734 |  | 
| 1735 |     This is useful when information about the file system is collected in a | 
| 1736 |     worker thread, and then passed to the UI in the form of caching QFileInfo | 
| 1737 |     instances. | 
| 1738 |  | 
| 1739 |     \sa setCaching(), refresh() | 
| 1740 | */ | 
| 1741 | void QFileInfo::stat() | 
| 1742 | { | 
| 1743 |     Q_D(QFileInfo); | 
| 1744 |     QFileSystemEngine::fillMetaData(entry: d->fileEntry, data&: d->metaData, what: QFileSystemMetaData::AllMetaDataFlags); | 
| 1745 | } | 
| 1746 |  | 
| 1747 | /*! | 
| 1748 |     \typedef QFileInfoList | 
| 1749 |     \relates QFileInfo | 
| 1750 |  | 
| 1751 |     Synonym for QList<QFileInfo>. | 
| 1752 | */ | 
| 1753 |  | 
| 1754 | #ifndef QT_NO_DEBUG_STREAM | 
| 1755 | QDebug operator<<(QDebug dbg, const QFileInfo &fi) | 
| 1756 | { | 
| 1757 |     QDebugStateSaver saver(dbg); | 
| 1758 |     dbg.nospace(); | 
| 1759 |     dbg.noquote(); | 
| 1760 |     dbg << "QFileInfo("  << QDir::toNativeSeparators(pathName: fi.filePath()) << ')'; | 
| 1761 |     return dbg; | 
| 1762 | } | 
| 1763 | #endif | 
| 1764 |  | 
| 1765 | /*! | 
| 1766 |     \fn QFileInfo::QFileInfo(const std::filesystem::path &file) | 
| 1767 |     \since 6.0 | 
| 1768 |  | 
| 1769 |     Constructs a new QFileInfo that gives information about the given | 
| 1770 |     \a file. | 
| 1771 |  | 
| 1772 |     \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath() | 
| 1773 | */ | 
| 1774 | /*! | 
| 1775 |     \fn QFileInfo::QFileInfo(const QDir &dir, const std::filesystem::path &path) | 
| 1776 |     \since 6.0 | 
| 1777 |  | 
| 1778 |     Constructs a new QFileInfo that gives information about the file system | 
| 1779 |     entry at \a path that is relative to the directory \a dir. | 
| 1780 |  | 
| 1781 |     \include qfileinfo.cpp preserve-relative-or-absolute | 
| 1782 | */ | 
| 1783 | /*! | 
| 1784 |     \fn void QFileInfo::setFile(const std::filesystem::path &path) | 
| 1785 |     \since 6.0 | 
| 1786 |  | 
| 1787 |     Sets the path of file system entry that this QFileInfo provides | 
| 1788 |     information about to \a path. | 
| 1789 |  | 
| 1790 |     \include qfileinfo.cpp preserve-relative-path | 
| 1791 | */ | 
| 1792 | /*! | 
| 1793 |     \fn std::filesystem::path QFileInfo::filesystemFilePath() const | 
| 1794 |     \since 6.0 | 
| 1795 |  | 
| 1796 |     Returns filePath() as a \c{std::filesystem::path}. | 
| 1797 |     \sa filePath() | 
| 1798 | */ | 
| 1799 | /*! | 
| 1800 |     \fn std::filesystem::path QFileInfo::filesystemAbsoluteFilePath() const | 
| 1801 |     \since 6.0 | 
| 1802 |  | 
| 1803 |     Returns absoluteFilePath() as a \c{std::filesystem::path}. | 
| 1804 |     \sa absoluteFilePath() | 
| 1805 | */ | 
| 1806 | /*! | 
| 1807 |     \fn std::filesystem::path QFileInfo::filesystemCanonicalFilePath() const | 
| 1808 |     \since 6.0 | 
| 1809 |  | 
| 1810 |     Returns canonicalFilePath() as a \c{std::filesystem::path}. | 
| 1811 |     \sa canonicalFilePath() | 
| 1812 | */ | 
| 1813 | /*! | 
| 1814 |     \fn std::filesystem::path QFileInfo::filesystemPath() const | 
| 1815 |     \since 6.0 | 
| 1816 |  | 
| 1817 |     Returns path() as a \c{std::filesystem::path}. | 
| 1818 |     \sa path() | 
| 1819 | */ | 
| 1820 | /*! | 
| 1821 |     \fn std::filesystem::path QFileInfo::filesystemAbsolutePath() const | 
| 1822 |     \since 6.0 | 
| 1823 |  | 
| 1824 |     Returns absolutePath() as a \c{std::filesystem::path}. | 
| 1825 |     \sa absolutePath() | 
| 1826 | */ | 
| 1827 | /*! | 
| 1828 |     \fn std::filesystem::path QFileInfo::filesystemCanonicalPath() const | 
| 1829 |     \since 6.0 | 
| 1830 |  | 
| 1831 |     Returns canonicalPath() as a \c{std::filesystem::path}. | 
| 1832 |     \sa canonicalPath() | 
| 1833 | */ | 
| 1834 | /*! | 
| 1835 |     \fn std::filesystem::path QFileInfo::filesystemSymLinkTarget() const | 
| 1836 |     \since 6.0 | 
| 1837 |  | 
| 1838 |     Returns symLinkTarget() as a \c{std::filesystem::path}. | 
| 1839 |     \sa symLinkTarget() | 
| 1840 | */ | 
| 1841 | /*! | 
| 1842 |     \fn std::filesystem::path QFileInfo::filesystemReadSymLink() const | 
| 1843 |     \since 6.6 | 
| 1844 |  | 
| 1845 |     Returns readSymLink() as a \c{std::filesystem::path}. | 
| 1846 |     \sa readSymLink() | 
| 1847 | */ | 
| 1848 | /*! | 
| 1849 |     \fn std::filesystem::path QFileInfo::filesystemJunctionTarget() const | 
| 1850 |     \since 6.2 | 
| 1851 |  | 
| 1852 |     Returns junctionTarget() as a \c{std::filesystem::path}. | 
| 1853 |     \sa junctionTarget() | 
| 1854 | */ | 
| 1855 | /*! | 
| 1856 |     \macro QT_IMPLICIT_QFILEINFO_CONSTRUCTION | 
| 1857 |     \since 6.0 | 
| 1858 |     \relates QFileInfo | 
| 1859 |  | 
| 1860 |     Defining this macro makes most QFileInfo constructors implicit | 
| 1861 |     instead of explicit. Since construction of QFileInfo objects is | 
| 1862 |     expensive, one should avoid accidentally creating them, especially | 
| 1863 |     if cheaper alternatives exist. For instance: | 
| 1864 |  | 
| 1865 |     \badcode | 
| 1866 |  | 
| 1867 |     QDirIterator it(dir); | 
| 1868 |     while (it.hasNext()) { | 
| 1869 |         // Implicit conversion from QString (returned by it.next()): | 
| 1870 |         // may create unnecessary data structures and cause additional | 
| 1871 |         // accesses to the file system. Unless this macro is defined, | 
| 1872 |         // this line does not compile. | 
| 1873 |  | 
| 1874 |         QFileInfo fi = it.next(); | 
| 1875 |  | 
| 1876 |         ~~~ | 
| 1877 |     } | 
| 1878 |  | 
| 1879 |     \endcode | 
| 1880 |  | 
| 1881 |     Instead, use the right API: | 
| 1882 |  | 
| 1883 |     \code | 
| 1884 |  | 
| 1885 |     QDirIterator it(dir); | 
| 1886 |     while (it.hasNext()) { | 
| 1887 |         // Extract the QFileInfo from the iterator directly: | 
| 1888 |         QFileInfo fi = it.nextFileInfo(); | 
| 1889 |  | 
| 1890 |         ~~~ | 
| 1891 |     } | 
| 1892 |  | 
| 1893 |     \endcode | 
| 1894 |  | 
| 1895 |     Construction from QString, QFile, and so on is always possible by | 
| 1896 |     using direct initialization instead of copy initialization: | 
| 1897 |  | 
| 1898 |     \code | 
| 1899 |  | 
| 1900 |     QFileInfo fi1 = some_string; // Does not compile unless this macro is defined | 
| 1901 |     QFileInfo fi2(some_string);  // OK | 
| 1902 |     QFileInfo fi3{some_string};  // Possibly better, avoids the risk of the Most Vexing Parse | 
| 1903 |     auto fi4 = QFileInfo(some_string); // OK | 
| 1904 |  | 
| 1905 |     \endcode | 
| 1906 |  | 
| 1907 |     This macro is provided for compatibility reason. Its usage is not | 
| 1908 |     recommended in new code. | 
| 1909 | */ | 
| 1910 |  | 
| 1911 | QT_END_NAMESPACE | 
| 1912 |  |