Remove the usage of deprecated qdoc macros.
[profile/ivi/qtbase.git] / src / corelib / io / qfileinfo.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qplatformdefs.h"
43 #include "qfileinfo.h"
44 #include "qglobal.h"
45 #include "qdir.h"
46 #include "qfileinfo_p.h"
47
48 QT_BEGIN_NAMESPACE
49
50 QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const
51 {
52     if (cache_enabled && !fileNames[(int)name].isNull())
53         return fileNames[(int)name];
54
55     QString ret;
56     if (fileEngine == 0) { // local file; use the QFileSystemEngine directly
57         switch (name) {
58             case QAbstractFileEngine::CanonicalName:
59             case QAbstractFileEngine::CanonicalPathName: {
60                 QFileSystemEntry entry = QFileSystemEngine::canonicalName(fileEntry, metaData);
61                 if (cache_enabled) { // be smart and store both
62                     fileNames[QAbstractFileEngine::CanonicalName] = entry.filePath();
63                     fileNames[QAbstractFileEngine::CanonicalPathName] = entry.path();
64                 }
65                 if (name == QAbstractFileEngine::CanonicalName)
66                     ret = entry.filePath();
67                 else
68                     ret = entry.path();
69                 break;
70             }
71             case QAbstractFileEngine::LinkName:
72                 ret = QFileSystemEngine::getLinkTarget(fileEntry, metaData).filePath();
73                 break;
74             case QAbstractFileEngine::BundleName:
75                 ret = QFileSystemEngine::bundleName(fileEntry);
76                 break;
77             case QAbstractFileEngine::AbsoluteName:
78             case QAbstractFileEngine::AbsolutePathName: {
79                 QFileSystemEntry entry = QFileSystemEngine::absoluteName(fileEntry);
80                 if (cache_enabled) { // be smart and store both
81                     fileNames[QAbstractFileEngine::AbsoluteName] = entry.filePath();
82                     fileNames[QAbstractFileEngine::AbsolutePathName] = entry.path();
83                 }
84                 if (name == QAbstractFileEngine::AbsoluteName)
85                     ret = entry.filePath();
86                 else
87                     ret = entry.path();
88                 break;
89             }
90             default: break;
91         }
92     } else {
93         ret = fileEngine->fileName(name);
94     }
95     if (ret.isNull())
96         ret = QLatin1String("");
97     if (cache_enabled)
98         fileNames[(int)name] = ret;
99     return ret;
100 }
101
102 QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const
103 {
104     if (cache_enabled && !fileOwners[(int)own].isNull())
105         return fileOwners[(int)own];
106     QString ret;
107     if (fileEngine == 0) {
108         switch (own) {
109         case QAbstractFileEngine::OwnerUser:
110             ret = QFileSystemEngine::resolveUserName(fileEntry, metaData);
111             break;
112         case QAbstractFileEngine::OwnerGroup:
113             ret = QFileSystemEngine::resolveGroupName(fileEntry, metaData);
114             break;
115         }
116      } else {
117         ret = fileEngine->owner(own);
118     }
119     if (ret.isNull())
120         ret = QLatin1String("");
121     if (cache_enabled)
122         fileOwners[(int)own] = ret;
123     return ret;
124 }
125
126 uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) const
127 {
128     Q_ASSERT(fileEngine); // should never be called when using the native FS
129     // We split the testing into tests for for LinkType, BundleType, PermsMask
130     // and the rest.
131     // Tests for file permissions on Windows can be slow, expecially on network
132     // paths and NTFS drives.
133     // In order to determine if a file is a symlink or not, we have to lstat().
134     // If we're not interested in that information, we might as well avoid one
135     // extra syscall. Bundle detecton on Mac can be slow, expecially on network
136     // paths, so we separate out that as well.
137
138     QAbstractFileEngine::FileFlags req = 0;
139     uint cachedFlags = 0;
140
141     if (request & (QAbstractFileEngine::FlagsMask | QAbstractFileEngine::TypesMask)) {
142         if (!getCachedFlag(CachedFileFlags)) {
143             req |= QAbstractFileEngine::FlagsMask;
144             req |= QAbstractFileEngine::TypesMask;
145             req &= (~QAbstractFileEngine::LinkType);
146             req &= (~QAbstractFileEngine::BundleType);
147
148             cachedFlags |= CachedFileFlags;
149         }
150
151         if (request & QAbstractFileEngine::LinkType) {
152             if (!getCachedFlag(CachedLinkTypeFlag)) {
153                 req |= QAbstractFileEngine::LinkType;
154                 cachedFlags |= CachedLinkTypeFlag;
155             }
156         }
157
158         if (request & QAbstractFileEngine::BundleType) {
159             if (!getCachedFlag(CachedBundleTypeFlag)) {
160                 req |= QAbstractFileEngine::BundleType;
161                 cachedFlags |= CachedBundleTypeFlag;
162             }
163         }
164     }
165
166     if (request & QAbstractFileEngine::PermsMask) {
167         if (!getCachedFlag(CachedPerms)) {
168             req |= QAbstractFileEngine::PermsMask;
169             cachedFlags |= CachedPerms;
170         }
171     }
172
173     if (req) {
174         if (cache_enabled)
175             req &= (~QAbstractFileEngine::Refresh);
176         else
177             req |= QAbstractFileEngine::Refresh;
178
179         QAbstractFileEngine::FileFlags flags = fileEngine->fileFlags(req);
180         fileFlags |= uint(flags);
181         setCachedFlag(cachedFlags);
182     }
183
184     return fileFlags & request;
185 }
186
187 QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) const
188 {
189     Q_ASSERT(fileEngine); // should never be called when using the native FS
190     if (!cache_enabled)
191         clearFlags();
192     uint cf;
193     if (request == QAbstractFileEngine::CreationTime)
194         cf = CachedCTime;
195     else if (request == QAbstractFileEngine::ModificationTime)
196         cf = CachedMTime;
197     else
198         cf = CachedATime;
199     if (!getCachedFlag(cf)) {
200         fileTimes[request] = fileEngine->fileTime(request);
201         setCachedFlag(cf);
202     }
203     return fileTimes[request];
204 }
205
206 //************* QFileInfo
207
208 /*!
209     \class QFileInfo
210     \reentrant
211     \brief The QFileInfo class provides system-independent file information.
212
213     \ingroup io
214     \ingroup shared
215
216     QFileInfo provides information about a file's name and position
217     (path) in the file system, its access rights and whether it is a
218     directory or symbolic link, etc. The file's size and last
219     modified/read times are also available. QFileInfo can also be
220     used to obtain information about a Qt \l{resource
221     system}{resource}.
222
223     A QFileInfo can point to a file with either a relative or an
224     absolute file path. Absolute file paths begin with the directory
225     separator "/" (or with a drive specification on Windows). Relative
226     file names begin with a directory name or a file name and specify
227     a path relative to the current working directory. An example of an
228     absolute path is the string "/tmp/quartz". A relative path might
229     look like "src/fatlib". You can use the function isRelative() to
230     check whether a QFileInfo is using a relative or an absolute file
231     path. You can call the function makeAbsolute() to convert a
232     relative QFileInfo's path to an absolute path.
233
234     The file that the QFileInfo works on is set in the constructor or
235     later with setFile(). Use exists() to see if the file exists and
236     size() to get its size.
237
238     The file's type is obtained with isFile(), isDir() and
239     isSymLink(). The symLinkTarget() function provides the name of the file
240     the symlink points to.
241
242     On Unix (including Mac OS X), the symlink has the same size() has
243     the file it points to, because Unix handles symlinks
244     transparently; similarly, opening a symlink using QFile
245     effectively opens the link's target. For example:
246
247     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 0
248
249     On Windows, symlinks (shortcuts) are \c .lnk files. The reported
250     size() is that of the symlink (not the link's target), and
251     opening a symlink using QFile opens the \c .lnk file. For
252     example:
253
254     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 1
255
256     Elements of the file's name can be extracted with path() and
257     fileName(). The fileName()'s parts can be extracted with
258     baseName(), suffix() or completeSuffix(). QFileInfo objects to
259     directories created by Qt classes will not have a trailing file
260     separator. If you wish to use trailing separators in your own file
261     info objects, just append one to the file name given to the constructors
262     or setFile().
263
264     The file's dates are returned by created(), lastModified() and
265     lastRead(). Information about the file's access permissions is
266     obtained with isReadable(), isWritable() and isExecutable(). The
267     file's ownership is available from owner(), ownerId(), group() and
268     groupId(). You can examine a file's permissions and ownership in a
269     single statement using the permission() function.
270
271     \section1 Performance Issues
272
273     Some of QFileInfo's functions query the file system, but for
274     performance reasons, some functions only operate on the
275     file name itself. For example: To return the absolute path of
276     a relative file name, absolutePath() has to query the file system.
277     The path() function, however, can work on the file name directly,
278     and so it is faster.
279
280     \note To speed up performance, QFileInfo caches information about
281     the file.
282
283     To speed up performance, QFileInfo caches information about the
284     file. Because files can be changed by other users or programs, or
285     even by other parts of the same program, there is a function that
286     refreshes the file information: refresh(). If you want to switch
287     off a QFileInfo's caching and force it to access the file system
288     every time you request information from it call setCaching(false).
289
290     \sa QDir, QFile
291 */
292
293 /*!
294     \internal
295 */
296 QFileInfo::QFileInfo(QFileInfoPrivate *p) : d_ptr(p)
297 {
298 }
299
300 /*!
301     Constructs an empty QFileInfo object.
302
303     Note that an empty QFileInfo object contain no file reference.
304
305     \sa setFile()
306 */
307 QFileInfo::QFileInfo() : d_ptr(new QFileInfoPrivate())
308 {
309 }
310
311 /*!
312     Constructs a new QFileInfo that gives information about the given
313     file. The \a file can also include an absolute or relative path.
314
315     \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath()
316 */
317 QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate(file))
318 {
319 }
320
321 /*!
322     Constructs a new QFileInfo that gives information about file \a
323     file.
324
325     If the \a file has a relative path, the QFileInfo will also have a
326     relative path.
327
328     \sa isRelative()
329 */
330 QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate(file.fileName()))
331 {
332 }
333
334 /*!
335     Constructs a new QFileInfo that gives information about the given
336     \a file in the directory \a dir.
337
338     If \a dir has a relative path, the QFileInfo will also have a
339     relative path.
340
341     If \a file is an absolute path, then the directory specified
342     by \a dir will be disregarded.
343
344     \sa isRelative()
345 */
346 QFileInfo::QFileInfo(const QDir &dir, const QString &file)
347     : d_ptr(new QFileInfoPrivate(dir.filePath(file)))
348 {
349 }
350
351 /*!
352     Constructs a new QFileInfo that is a copy of the given \a fileinfo.
353 */
354 QFileInfo::QFileInfo(const QFileInfo &fileinfo)
355     : d_ptr(fileinfo.d_ptr)
356 {
357
358 }
359
360 /*!
361     Destroys the QFileInfo and frees its resources.
362 */
363
364 QFileInfo::~QFileInfo()
365 {
366 }
367
368 /*!
369     \fn bool QFileInfo::operator!=(const QFileInfo &fileinfo) const
370
371     Returns true if this QFileInfo object refers to a different file
372     than the one specified by \a fileinfo; otherwise returns false.
373
374     \sa operator==()
375 */
376
377 /*!
378     Returns true if this QFileInfo object refers to a file in the same
379     location as \a fileinfo; otherwise returns false.
380
381     Note that the result of comparing two empty QFileInfo objects,
382     containing no file references, is undefined.
383
384     \warning This will not compare two different symbolic links
385     pointing to the same file.
386
387     \warning Long and short file names that refer to the same file on Windows
388     are treated as if they referred to different files.
389
390     \sa operator!=()
391 */
392 bool QFileInfo::operator==(const QFileInfo &fileinfo) const
393 {
394     Q_D(const QFileInfo);
395     // ### Qt 5: understand long and short file names on Windows
396     // ### (GetFullPathName()).
397     if (fileinfo.d_ptr == d_ptr)
398         return true;
399     if (d->isDefaultConstructed || fileinfo.d_ptr->isDefaultConstructed)
400         return false;
401
402     // Assume files are the same if path is the same
403     if (d->fileEntry.filePath() == fileinfo.d_ptr->fileEntry.filePath())
404         return true;
405
406     Qt::CaseSensitivity sensitive;
407     if (d->fileEngine == 0 || fileinfo.d_ptr->fileEngine == 0) {
408         if (d->fileEngine != fileinfo.d_ptr->fileEngine) // one is native, the other is a custom file-engine
409             return false;
410
411         sensitive = QFileSystemEngine::isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
412     } else {
413         if (d->fileEngine->caseSensitive() != fileinfo.d_ptr->fileEngine->caseSensitive())
414             return false;
415         sensitive = d->fileEngine->caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
416     }
417
418     if (fileinfo.size() != size()) //if the size isn't the same...
419         return false;
420
421    // Fallback to expensive canonical path computation
422    return canonicalFilePath().compare(fileinfo.canonicalFilePath(), sensitive) == 0;
423 }
424
425 /*!
426     Makes a copy of the given \a fileinfo and assigns it to this QFileInfo.
427 */
428 QFileInfo &QFileInfo::operator=(const QFileInfo &fileinfo)
429 {
430     d_ptr = fileinfo.d_ptr;
431     return *this;
432 }
433
434 /*!
435     Sets the file that the QFileInfo provides information about to \a
436     file.
437
438     The \a file can also include an absolute or relative file path.
439     Absolute paths begin with the directory separator (e.g. "/" under
440     Unix) or a drive specification (under Windows). Relative file
441     names begin with a directory name or a file name and specify a
442     path relative to the current directory.
443
444     Example:
445     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 2
446
447     \sa isRelative(), QDir::setCurrent(), QDir::isRelativePath()
448 */
449 void QFileInfo::setFile(const QString &file)
450 {
451     bool caching = d_ptr.constData()->cache_enabled;
452     *this = QFileInfo(file);
453     d_ptr->cache_enabled = caching;
454 }
455
456 /*!
457     \overload
458
459     Sets the file that the QFileInfo provides information about to \a
460     file.
461
462     If \a file includes a relative path, the QFileInfo will also have
463     a relative path.
464
465     \sa isRelative()
466 */
467 void QFileInfo::setFile(const QFile &file)
468 {
469     setFile(file.fileName());
470 }
471
472 /*!
473     \overload
474
475     Sets the file that the QFileInfo provides information about to \a
476     file in directory \a dir.
477
478     If \a file includes a relative path, the QFileInfo will also
479     have a relative path.
480
481     \sa isRelative()
482 */
483 void QFileInfo::setFile(const QDir &dir, const QString &file)
484 {
485     setFile(dir.filePath(file));
486 }
487
488 /*!
489     Returns an absolute path including the file name.
490
491     The absolute path name consists of the full path and the file
492     name. On Unix this will always begin with the root, '/',
493     directory. On Windows this will always begin 'D:/' where D is a
494     drive letter, except for network shares that are not mapped to a
495     drive letter, in which case the path will begin '//sharename/'.
496     QFileInfo will uppercase drive letters. Note that QDir does not do
497     this. The code snippet below shows this.
498
499     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp newstuff
500
501     This function returns the same as filePath(), unless isRelative()
502     is true. In contrast to canonicalFilePath(), symbolic links or
503     redundant "." or ".." elements are not necessarily removed.
504
505     If the QFileInfo is empty it returns QDir::currentPath().
506
507     \sa filePath(), canonicalFilePath(), isRelative()
508 */
509 QString QFileInfo::absoluteFilePath() const
510 {
511     Q_D(const QFileInfo);
512     if (d->isDefaultConstructed)
513         return QLatin1String("");
514     return d->getFileName(QAbstractFileEngine::AbsoluteName);
515 }
516
517 /*!
518     Returns the canonical path including the file name, i.e. an absolute
519     path without symbolic links or redundant "." or ".." elements.
520
521     If the file does not exist, canonicalFilePath() returns an empty
522     string.
523
524     \sa filePath(), absoluteFilePath(), dir()
525 */
526 QString QFileInfo::canonicalFilePath() const
527 {
528     Q_D(const QFileInfo);
529     if (d->isDefaultConstructed)
530         return QLatin1String("");
531     return d->getFileName(QAbstractFileEngine::CanonicalName);
532 }
533
534
535 /*!
536     Returns a file's path absolute path. This doesn't include the
537     file name.
538
539     On Unix the absolute path will always begin with the root, '/',
540     directory. On Windows this will always begin 'D:/' where D is a
541     drive letter, except for network shares that are not mapped to a
542     drive letter, in which case the path will begin '//sharename/'.
543
544     In contrast to canonicalPath() symbolic links or redundant "." or
545     ".." elements are not necessarily removed.
546
547     \warning If the QFileInfo object was created with an empty QString,
548               the behavior of this function is undefined.
549
550     \sa absoluteFilePath(), path(), canonicalPath(), fileName(), isRelative()
551 */
552 QString QFileInfo::absolutePath() const
553 {
554     Q_D(const QFileInfo);
555
556     if (d->isDefaultConstructed) {
557         return QLatin1String("");
558     } else if (d->fileEntry.isEmpty()) {
559         qWarning("QFileInfo::absolutePath: Constructed with empty filename");
560         return QLatin1String("");
561     }
562     return d->getFileName(QAbstractFileEngine::AbsolutePathName);
563 }
564
565 /*!
566     Returns the file's path canonical path (excluding the file name),
567     i.e. an absolute path without symbolic links or redundant "." or ".." elements.
568
569     If the file does not exist, canonicalPath() returns an empty string.
570
571     \sa path(), absolutePath()
572 */
573 QString QFileInfo::canonicalPath() const
574 {
575     Q_D(const QFileInfo);
576     if (d->isDefaultConstructed)
577         return QLatin1String("");
578     return d->getFileName(QAbstractFileEngine::CanonicalPathName);
579 }
580
581 /*!
582     Returns the file's path. This doesn't include the file name.
583
584     Note that, if this QFileInfo object is given a path ending in a
585     slash, the name of the file is considered empty and this function
586     will return the entire path.
587
588     \sa filePath(), absolutePath(), canonicalPath(), dir(), fileName(), isRelative()
589 */
590 QString QFileInfo::path() const
591 {
592     Q_D(const QFileInfo);
593     if (d->isDefaultConstructed)
594         return QLatin1String("");
595     return d->fileEntry.path();
596 }
597
598 /*!
599     \fn bool QFileInfo::isAbsolute() const
600
601     Returns true if the file path name is absolute, otherwise returns
602     false if the path is relative.
603
604     \sa isRelative()
605 */
606
607 /*!
608     Returns true if the file path name is relative, otherwise returns
609     false if the path is absolute (e.g. under Unix a path is absolute
610     if it begins with a "/").
611
612     \sa isAbsolute()
613 */
614 bool QFileInfo::isRelative() const
615 {
616     Q_D(const QFileInfo);
617     if (d->isDefaultConstructed)
618         return true;
619     if (d->fileEngine == 0)
620         return d->fileEntry.isRelative();
621     return d->fileEngine->isRelativePath();
622 }
623
624 /*!
625     Converts the file's path to an absolute path if it is not already in that form.
626     Returns true to indicate that the path was converted; otherwise returns false
627     to indicate that the path was already absolute.
628
629     \sa filePath(), isRelative()
630 */
631 bool QFileInfo::makeAbsolute()
632 {
633     if (d_ptr.constData()->isDefaultConstructed
634             || !d_ptr.constData()->fileEntry.isRelative())
635         return false;
636
637     setFile(absoluteFilePath());
638     return true;
639 }
640
641 /*!
642     Returns true if the file exists; otherwise returns false.
643
644     \note If the file is a symlink that points to a non existing
645      file, false is returned.
646 */
647 bool QFileInfo::exists() const
648 {
649     Q_D(const QFileInfo);
650     if (d->isDefaultConstructed)
651         return false;
652     if (d->fileEngine == 0) {
653         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute))
654             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ExistsAttribute);
655         return d->metaData.exists();
656     }
657     return d->getFileFlags(QAbstractFileEngine::ExistsFlag);
658 }
659
660 /*!
661     Refreshes the information about the file, i.e. reads in information
662     from the file system the next time a cached property is fetched.
663
664    \note On Windows CE, there might be a delay for the file system driver
665     to detect changes on the file.
666 */
667 void QFileInfo::refresh()
668 {
669     Q_D(QFileInfo);
670     d->clear();
671 }
672
673 /*!
674     Returns the file name, including the path (which may be absolute
675     or relative).
676
677     \sa absoluteFilePath(), canonicalFilePath(), isRelative()
678 */
679 QString QFileInfo::filePath() const
680 {
681     Q_D(const QFileInfo);
682     if (d->isDefaultConstructed)
683         return QLatin1String("");
684     return d->fileEntry.filePath();
685 }
686
687 /*!
688     Returns the name of the file, excluding the path.
689
690     Example:
691     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 3
692
693     Note that, if this QFileInfo object is given a path ending in a
694     slash, the name of the file is considered empty.
695
696     \sa isRelative(), filePath(), baseName(), extension()
697 */
698 QString QFileInfo::fileName() const
699 {
700     Q_D(const QFileInfo);
701     if (d->isDefaultConstructed)
702         return QLatin1String("");
703     return d->fileEntry.fileName();
704 }
705
706 /*!
707     \since 4.3
708     Returns the name of the bundle.
709
710     On Mac OS X this returns the proper localized name for a bundle if the
711     path isBundle(). On all other platforms an empty QString is returned.
712
713     Example:
714     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 4
715
716     \sa isBundle(), filePath(), baseName(), extension()
717 */
718 QString QFileInfo::bundleName() const
719 {
720     Q_D(const QFileInfo);
721     if (d->isDefaultConstructed)
722         return QLatin1String("");
723     return d->getFileName(QAbstractFileEngine::BundleName);
724 }
725
726 /*!
727     Returns the base name of the file without the path.
728
729     The base name consists of all characters in the file up to (but
730     not including) the \e first '.' character.
731
732     Example:
733     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 5
734
735
736     The base name of a file is computed equally on all platforms, independent
737     of file naming conventions (e.g., ".bashrc" on Unix has an empty base
738     name, and the suffix is "bashrc").
739
740     \sa fileName(), suffix(), completeSuffix(), completeBaseName()
741 */
742 QString QFileInfo::baseName() const
743 {
744     Q_D(const QFileInfo);
745     if (d->isDefaultConstructed)
746         return QLatin1String("");
747     return d->fileEntry.baseName();
748 }
749
750 /*!
751     Returns the complete base name of the file without the path.
752
753     The complete base name consists of all characters in the file up
754     to (but not including) the \e last '.' character.
755
756     Example:
757     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 6
758
759     \sa fileName(), suffix(), completeSuffix(), baseName()
760 */
761 QString QFileInfo::completeBaseName() const
762 {
763     Q_D(const QFileInfo);
764     if (d->isDefaultConstructed)
765         return QLatin1String("");
766     return d->fileEntry.completeBaseName();
767 }
768
769 /*!
770     Returns the complete suffix of the file.
771
772     The complete suffix consists of all characters in the file after
773     (but not including) the first '.'.
774
775     Example:
776     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 7
777
778     \sa fileName(), suffix(), baseName(), completeBaseName()
779 */
780 QString QFileInfo::completeSuffix() const
781 {
782     Q_D(const QFileInfo);
783     if (d->isDefaultConstructed)
784         return QLatin1String("");
785     return d->fileEntry.completeSuffix();
786 }
787
788 /*!
789     Returns the suffix of the file.
790
791     The suffix consists of all characters in the file after (but not
792     including) the last '.'.
793
794     Example:
795     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 8
796
797     The suffix of a file is computed equally on all platforms, independent of
798     file naming conventions (e.g., ".bashrc" on Unix has an empty base name,
799     and the suffix is "bashrc").
800
801     \sa fileName(), completeSuffix(), baseName(), completeBaseName()
802 */
803 QString QFileInfo::suffix() const
804 {
805     Q_D(const QFileInfo);
806     if (d->isDefaultConstructed)
807         return QLatin1String("");
808     return d->fileEntry.suffix();
809 }
810
811
812 /*!
813     Returns the path of the object's parent directory as a QDir object.
814
815     \b{Note:} The QDir returned always corresponds to the object's
816     parent directory, even if the QFileInfo represents a directory.
817
818     For each of the following, dir() returns a QDir for
819     \c{"~/examples/191697"}.
820
821     \snippet doc/src/snippets/fileinfo/main.cpp 0
822
823     For each of the following, dir() returns a QDir for
824     \c{"."}.
825
826     \snippet doc/src/snippets/fileinfo/main.cpp 1
827
828     \sa absolutePath(), filePath(), fileName(), isRelative(), absoluteDir()
829 */
830 QDir QFileInfo::dir() const
831 {
832     Q_D(const QFileInfo);
833     // ### Qt5: Maybe rename this to parentDirectory(), considering what it actually do?
834     return QDir(d->fileEntry.path());
835 }
836
837 /*!
838     Returns the file's absolute path as a QDir object.
839
840     \sa dir(), filePath(), fileName(), isRelative()
841 */
842 QDir QFileInfo::absoluteDir() const
843 {
844     return QDir(absolutePath());
845 }
846
847 /*!
848     Returns true if the user can read the file; otherwise returns false.
849
850     \sa isWritable(), isExecutable(), permission()
851 */
852 bool QFileInfo::isReadable() const
853 {
854     Q_D(const QFileInfo);
855     if (d->isDefaultConstructed)
856         return false;
857     if (d->fileEngine == 0) {
858         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::UserReadPermission))
859             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::UserReadPermission);
860         return (d->metaData.permissions() & QFile::ReadUser) != 0;
861     }
862     return d->getFileFlags(QAbstractFileEngine::ReadUserPerm);
863 }
864
865 /*!
866     Returns true if the user can write to the file; otherwise returns false.
867
868     \sa isReadable(), isExecutable(), permission()
869 */
870 bool QFileInfo::isWritable() const
871 {
872     Q_D(const QFileInfo);
873     if (d->isDefaultConstructed)
874         return false;
875     if (d->fileEngine == 0) {
876         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::UserWritePermission))
877             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::UserWritePermission);
878         return (d->metaData.permissions() & QFile::WriteUser) != 0;
879     }
880     return d->getFileFlags(QAbstractFileEngine::WriteUserPerm);
881 }
882
883 /*!
884     Returns true if the file is executable; otherwise returns false.
885
886     \sa isReadable(), isWritable(), permission()
887 */
888 bool QFileInfo::isExecutable() const
889 {
890     Q_D(const QFileInfo);
891     if (d->isDefaultConstructed)
892         return false;
893     if (d->fileEngine == 0) {
894         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::UserExecutePermission))
895             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::UserExecutePermission);
896         return (d->metaData.permissions() & QFile::ExeUser) != 0;
897     }
898     return d->getFileFlags(QAbstractFileEngine::ExeUserPerm);
899 }
900
901 /*!
902     Returns true if this is a `hidden' file; otherwise returns false.
903
904     \b{Note:} This function returns true for the special entries
905     "." and ".." on Unix, even though QDir::entryList threats them as shown.
906 */
907 bool QFileInfo::isHidden() const
908 {
909     Q_D(const QFileInfo);
910     if (d->isDefaultConstructed)
911         return false;
912     if (d->fileEngine == 0) {
913         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::HiddenAttribute))
914             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::HiddenAttribute);
915         return d->metaData.isHidden();
916     }
917     return d->getFileFlags(QAbstractFileEngine::HiddenFlag);
918 }
919
920 /*!
921     \since 5.0
922     Returns true if the file path can be used directly with native APIs.
923     Returns false if the file is otherwise supported by a virtual file system
924     inside Qt, such as \l{the Qt Resource System}.
925
926     \b{Note:} Native paths may still require conversion of path separators
927     and character encoding, depending on platform and input requirements of the
928     native API.
929
930     \sa QDir::toNativeSeparators(), QFile::encodeName(), filePath(),
931     absoluteFilePath(), canonicalFilePath()
932 */
933 bool QFileInfo::isNativePath() const
934 {
935     Q_D(const QFileInfo);
936     if (d->isDefaultConstructed)
937         return false;
938     if (d->fileEngine == 0)
939         return true;
940     return d->getFileFlags(QAbstractFileEngine::LocalDiskFlag);
941 }
942
943 /*!
944     Returns true if this object points to a file or to a symbolic
945     link to a file. Returns false if the
946     object points to something which isn't a file, such as a directory.
947
948     \sa isDir(), isSymLink(), isBundle()
949 */
950 bool QFileInfo::isFile() const
951 {
952     Q_D(const QFileInfo);
953     if (d->isDefaultConstructed)
954         return false;
955     if (d->fileEngine == 0) {
956         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::FileType))
957             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::FileType);
958         return d->metaData.isFile();
959     }
960     return d->getFileFlags(QAbstractFileEngine::FileType);
961 }
962
963 /*!
964     Returns true if this object points to a directory or to a symbolic
965     link to a directory; otherwise returns false.
966
967     \sa isFile(), isSymLink(), isBundle()
968 */
969 bool QFileInfo::isDir() const
970 {
971     Q_D(const QFileInfo);
972     if (d->isDefaultConstructed)
973         return false;
974     if (d->fileEngine == 0) {
975         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::DirectoryType))
976             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::DirectoryType);
977         return d->metaData.isDirectory();
978     }
979     return d->getFileFlags(QAbstractFileEngine::DirectoryType);
980 }
981
982
983 /*!
984     \since 4.3
985     Returns true if this object points to a bundle or to a symbolic
986     link to a bundle on Mac OS X; otherwise returns false.
987
988     \sa isDir(), isSymLink(), isFile()
989 */
990 bool QFileInfo::isBundle() const
991 {
992     Q_D(const QFileInfo);
993     if (d->isDefaultConstructed)
994         return false;
995     if (d->fileEngine == 0) {
996         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::BundleType))
997             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::BundleType);
998         return d->metaData.isBundle();
999     }
1000     return d->getFileFlags(QAbstractFileEngine::BundleType);
1001 }
1002
1003 /*!
1004     Returns true if this object points to a symbolic link (or to a
1005     shortcut on Windows); otherwise returns false.
1006
1007     On Unix (including Mac OS X), opening a symlink effectively opens
1008     the \l{symLinkTarget()}{link's target}. On Windows, it opens the \c
1009     .lnk file itself.
1010
1011     Example:
1012
1013     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 9
1014
1015     \note If the symlink points to a non existing file, exists() returns
1016      false.
1017
1018     \sa isFile(), isDir(), symLinkTarget()
1019 */
1020 bool QFileInfo::isSymLink() const
1021 {
1022     Q_D(const QFileInfo);
1023     if (d->isDefaultConstructed)
1024         return false;
1025     if (d->fileEngine == 0) {
1026         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::LegacyLinkType))
1027             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::LegacyLinkType);
1028         return d->metaData.isLegacyLink();
1029     }
1030     return d->getFileFlags(QAbstractFileEngine::LinkType);
1031 }
1032
1033 /*!
1034     Returns true if the object points to a directory or to a symbolic
1035     link to a directory, and that directory is the root directory; otherwise
1036     returns false.
1037 */
1038 bool QFileInfo::isRoot() const
1039 {
1040     Q_D(const QFileInfo);
1041     if (d->isDefaultConstructed)
1042         return true;
1043     if (d->fileEngine == 0) {
1044         if (d->fileEntry.isRoot()) {
1045 #if defined(Q_OS_WIN)
1046             //the path is a drive root, but the drive may not exist
1047             //for backward compatibility, return true only if the drive exists
1048             if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute))
1049                 QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ExistsAttribute);
1050             return d->metaData.exists();
1051 #else
1052             return true;
1053 #endif
1054         }
1055         return false;
1056     }
1057     return d->getFileFlags(QAbstractFileEngine::RootFlag);
1058 }
1059
1060 /*!
1061     \fn QString QFileInfo::symLinkTarget() const
1062     \since 4.2
1063
1064     Returns the absolute path to the file or directory a symlink (or shortcut
1065     on Windows) points to, or a an empty string if the object isn't a symbolic
1066     link.
1067
1068     This name may not represent an existing file; it is only a string.
1069     QFileInfo::exists() returns true if the symlink points to an
1070     existing file.
1071
1072     \sa exists(), isSymLink(), isDir(), isFile()
1073 */
1074
1075 /*!
1076     \obsolete
1077
1078     Use symLinkTarget() instead.
1079 */
1080 QString QFileInfo::readLink() const
1081 {
1082     Q_D(const QFileInfo);
1083     if (d->isDefaultConstructed)
1084         return QLatin1String("");
1085     return d->getFileName(QAbstractFileEngine::LinkName);
1086 }
1087
1088 /*!
1089     Returns the owner of the file. On systems where files
1090     do not have owners, or if an error occurs, an empty string is
1091     returned.
1092
1093     This function can be time consuming under Unix (in the order of
1094     milliseconds).
1095
1096     \sa ownerId(), group(), groupId()
1097 */
1098 QString QFileInfo::owner() const
1099 {
1100     Q_D(const QFileInfo);
1101     if (d->isDefaultConstructed)
1102         return QLatin1String("");
1103     return d->getFileOwner(QAbstractFileEngine::OwnerUser);
1104 }
1105
1106 /*!
1107     Returns the id of the owner of the file.
1108
1109     On Windows and on systems where files do not have owners this
1110     function returns ((uint) -2).
1111
1112     \sa owner(), group(), groupId()
1113 */
1114 uint QFileInfo::ownerId() const
1115 {
1116     Q_D(const QFileInfo);
1117     if (d->isDefaultConstructed)
1118         return 0;
1119     if (d->fileEngine == 0) {
1120         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::UserId))
1121             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::UserId);
1122         return d->metaData.userId();
1123     }
1124     return d->fileEngine->ownerId(QAbstractFileEngine::OwnerUser);
1125 }
1126
1127 /*!
1128     Returns the group of the file. On Windows, on systems where files
1129     do not have groups, or if an error occurs, an empty string is
1130     returned.
1131
1132     This function can be time consuming under Unix (in the order of
1133     milliseconds).
1134
1135     \sa groupId(), owner(), ownerId()
1136 */
1137 QString QFileInfo::group() const
1138 {
1139     Q_D(const QFileInfo);
1140     if (d->isDefaultConstructed)
1141         return QLatin1String("");
1142     return d->getFileOwner(QAbstractFileEngine::OwnerGroup);
1143 }
1144
1145 /*!
1146     Returns the id of the group the file belongs to.
1147
1148     On Windows and on systems where files do not have groups this
1149     function always returns (uint) -2.
1150
1151     \sa group(), owner(), ownerId()
1152 */
1153 uint QFileInfo::groupId() const
1154 {
1155     Q_D(const QFileInfo);
1156     if (d->isDefaultConstructed)
1157         return 0;
1158     if (d->fileEngine == 0) {
1159         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::GroupId))
1160             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::GroupId);
1161         return d->metaData.groupId();
1162     }
1163     return d->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup);
1164 }
1165
1166 /*!
1167     Tests for file permissions. The \a permissions argument can be
1168     several flags of type QFile::Permissions OR-ed together to check
1169     for permission combinations.
1170
1171     On systems where files do not have permissions this function
1172     always returns true.
1173
1174     Example:
1175     \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp 10
1176
1177     \sa isReadable(), isWritable(), isExecutable()
1178 */
1179 bool QFileInfo::permission(QFile::Permissions permissions) const
1180 {
1181     Q_D(const QFileInfo);
1182     if (d->isDefaultConstructed)
1183         return false;
1184     if (d->fileEngine == 0) {
1185         // the QFileSystemMetaData::MetaDataFlag and QFile::Permissions overlap, so just static cast.
1186         QFileSystemMetaData::MetaDataFlag permissionFlags = static_cast<QFileSystemMetaData::MetaDataFlag>((int)permissions);
1187         if (!d->cache_enabled || !d->metaData.hasFlags(permissionFlags))
1188             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, permissionFlags);
1189         return (d->metaData.permissions() & permissions) == permissions;
1190     }
1191     return d->getFileFlags(QAbstractFileEngine::FileFlags((int)permissions)) == (uint)permissions;
1192 }
1193
1194 /*!
1195     Returns the complete OR-ed together combination of
1196     QFile::Permissions for the file.
1197 */
1198 QFile::Permissions QFileInfo::permissions() const
1199 {
1200     Q_D(const QFileInfo);
1201     if (d->isDefaultConstructed)
1202         return 0;
1203     if (d->fileEngine == 0) {
1204         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::Permissions))
1205             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::Permissions);
1206         return d->metaData.permissions();
1207     }
1208     return QFile::Permissions(d->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask);
1209 }
1210
1211
1212 /*!
1213     Returns the file size in bytes. If the file does not exist or cannot be
1214     fetched, 0 is returned.
1215
1216     \sa exists()
1217 */
1218 qint64 QFileInfo::size() const
1219 {
1220     Q_D(const QFileInfo);
1221     if (d->isDefaultConstructed)
1222         return 0;
1223     if (d->fileEngine == 0) {
1224         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::SizeAttribute))
1225             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::SizeAttribute);
1226         return d->metaData.size();
1227     }
1228     if (!d->getCachedFlag(QFileInfoPrivate::CachedSize)) {
1229         d->setCachedFlag(QFileInfoPrivate::CachedSize);
1230         d->fileSize = d->fileEngine->size();
1231     }
1232     return d->fileSize;
1233 }
1234
1235 /*!
1236     Returns the date and time when the file was created.
1237
1238     On most Unix systems, this function returns the time of the last
1239     status change. A status change occurs when the file is created,
1240     but it also occurs whenever the user writes or sets inode
1241     information (for example, changing the file permissions).
1242
1243     If neither creation time nor "last status change" time are not
1244     available, returns the same as lastModified().
1245
1246     \sa lastModified() lastRead()
1247 */
1248 QDateTime QFileInfo::created() const
1249 {
1250     Q_D(const QFileInfo);
1251     if (d->isDefaultConstructed)
1252         return QDateTime();
1253     if (d->fileEngine == 0) {
1254         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::CreationTime))
1255             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::CreationTime);
1256         return d->metaData.creationTime();
1257     }
1258     return d->getFileTime(QAbstractFileEngine::CreationTime);
1259 }
1260
1261 /*!
1262     Returns the date and time when the file was last modified.
1263
1264     \sa created() lastRead()
1265 */
1266 QDateTime QFileInfo::lastModified() const
1267 {
1268     Q_D(const QFileInfo);
1269     if (d->isDefaultConstructed)
1270         return QDateTime();
1271     if (d->fileEngine == 0) {
1272         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ModificationTime))
1273             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ModificationTime);
1274         return d->metaData.modificationTime();
1275     }
1276     return d->getFileTime(QAbstractFileEngine::ModificationTime);
1277 }
1278
1279 /*!
1280     Returns the date and time when the file was last read (accessed).
1281
1282     On platforms where this information is not available, returns the
1283     same as lastModified().
1284
1285     \sa created() lastModified()
1286 */
1287 QDateTime QFileInfo::lastRead() const
1288 {
1289     Q_D(const QFileInfo);
1290     if (d->isDefaultConstructed)
1291         return QDateTime();
1292     if (d->fileEngine == 0) {
1293         if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::AccessTime))
1294             QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::AccessTime);
1295         return d->metaData.accessTime();
1296     }
1297     return d->getFileTime(QAbstractFileEngine::AccessTime);
1298 }
1299
1300 /*! \internal
1301 */
1302 QFileInfoPrivate* QFileInfo::d_func()
1303 {
1304     return d_ptr.data();
1305 }
1306
1307 /*!
1308     Returns true if caching is enabled; otherwise returns false.
1309
1310     \sa setCaching(), refresh()
1311 */
1312 bool QFileInfo::caching() const
1313 {
1314     Q_D(const QFileInfo);
1315     return d->cache_enabled;
1316 }
1317
1318 /*!
1319     If \a enable is true, enables caching of file information. If \a
1320     enable is false caching is disabled.
1321
1322     When caching is enabled, QFileInfo reads the file information from
1323     the file system the first time it's needed, but generally not
1324     later.
1325
1326     Caching is enabled by default.
1327
1328     \sa refresh(), caching()
1329 */
1330 void QFileInfo::setCaching(bool enable)
1331 {
1332     Q_D(QFileInfo);
1333     d->cache_enabled = enable;
1334 }
1335
1336 /*!
1337     \typedef QFileInfoList
1338     \relates QFileInfo
1339
1340     Synonym for QList<QFileInfo>.
1341 */
1342
1343 QT_END_NAMESPACE