1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtCore module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef QFILEINFO_P_H 41 #define QFILEINFO_P_H 42 43 // 44 // W A R N I N G 45 // ------------- 46 // 47 // This file is not part of the Qt API. It exists purely as an 48 // implementation detail. This header file may change from version to 49 // version without notice, or even be removed. 50 // 51 // We mean it. 52 // 53 54 #include "qfileinfo.h" 55 #include "qdatetime.h" 56 #include "qatomic.h" 57 #include "qshareddata.h" 58 #include "qfilesystemengine_p.h" 59 60 #include <QtCore/private/qabstractfileengine_p.h> 61 #include <QtCore/private/qfilesystementry_p.h> 62 #include <QtCore/private/qfilesystemmetadata_p.h> 63 64 #include <memory> 65 66 QT_BEGIN_NAMESPACE 67 68 class QFileInfoPrivate : public QSharedData 69 { 70 public: 71 enum { 72 // note: cachedFlags is only 30-bits wide 73 CachedFileFlags = 0x01, 74 CachedLinkTypeFlag = 0x02, 75 CachedBundleTypeFlag = 0x04, 76 CachedSize = 0x08, 77 CachedATime = 0x10, 78 CachedBTime = 0x20, 79 CachedMCTime = 0x40, 80 CachedMTime = 0x80, 81 CachedPerms = 0x100 82 }; 83 QFileInfoPrivate()84 inline QFileInfoPrivate() 85 : QSharedData(), fileEngine(nullptr), 86 cachedFlags(0), 87 isDefaultConstructed(true), 88 cache_enabled(true), fileFlags(0), fileSize(0) 89 {} QFileInfoPrivate(const QFileInfoPrivate & copy)90 inline QFileInfoPrivate(const QFileInfoPrivate ©) 91 : QSharedData(copy), 92 fileEntry(copy.fileEntry), 93 metaData(copy.metaData), 94 fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)), 95 cachedFlags(0), 96 #ifndef QT_NO_FSFILEENGINE 97 isDefaultConstructed(false), 98 #else 99 isDefaultConstructed(!fileEngine), 100 #endif 101 cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) 102 {} QFileInfoPrivate(const QString & file)103 inline QFileInfoPrivate(const QString &file) 104 : fileEntry(QDir::fromNativeSeparators(file)), 105 fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)), 106 cachedFlags(0), 107 #ifndef QT_NO_FSFILEENGINE 108 isDefaultConstructed(file.isEmpty()), 109 #else 110 isDefaultConstructed(!fileEngine), 111 #endif 112 cache_enabled(true), fileFlags(0), fileSize(0) 113 { 114 } 115 QFileInfoPrivate(const QFileSystemEntry & file,const QFileSystemMetaData & data)116 inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data) 117 : QSharedData(), 118 fileEntry(file), 119 metaData(data), 120 fileEngine(QFileSystemEngine::resolveEntryAndCreateLegacyEngine(fileEntry, metaData)), 121 cachedFlags(0), 122 isDefaultConstructed(false), 123 cache_enabled(true), fileFlags(0), fileSize(0) 124 { 125 //If the file engine is not null, this maybe a "mount point" for a custom file engine 126 //in which case we can't trust the metadata 127 if (fileEngine) 128 metaData = QFileSystemMetaData(); 129 } 130 QFileInfoPrivate(const QFileSystemEntry & file,const QFileSystemMetaData & data,std::unique_ptr<QAbstractFileEngine> engine)131 inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, std::unique_ptr<QAbstractFileEngine> engine) 132 : fileEntry(file), 133 metaData(data), 134 fileEngine{std::move(engine)}, 135 cachedFlags(0), 136 #ifndef QT_NO_FSFILEENGINE 137 isDefaultConstructed(false), 138 #else 139 isDefaultConstructed(!fileEngine), 140 #endif 141 cache_enabled(true), fileFlags(0), fileSize(0) 142 { 143 } 144 clearFlags()145 inline void clearFlags() const { 146 fileFlags = 0; 147 cachedFlags = 0; 148 if (fileEngine) 149 (void)fileEngine->fileFlags(QAbstractFileEngine::Refresh); 150 } clear()151 inline void clear() { 152 metaData.clear(); 153 clearFlags(); 154 for (int i = QAbstractFileEngine::NFileNames - 1 ; i >= 0 ; --i) 155 fileNames[i].clear(); 156 fileOwners[1].clear(); 157 fileOwners[0].clear(); 158 } 159 160 uint getFileFlags(QAbstractFileEngine::FileFlags) const; 161 QDateTime &getFileTime(QAbstractFileEngine::FileTime) const; 162 QString getFileName(QAbstractFileEngine::FileName) const; 163 QString getFileOwner(QAbstractFileEngine::FileOwner own) const; 164 165 QFileSystemEntry fileEntry; 166 mutable QFileSystemMetaData metaData; 167 168 std::unique_ptr<QAbstractFileEngine> const fileEngine; 169 170 mutable QString fileNames[QAbstractFileEngine::NFileNames]; 171 mutable QString fileOwners[2]; // QAbstractFileEngine::FileOwner: OwnerUser and OwnerGroup 172 mutable QDateTime fileTimes[4]; // QAbstractFileEngine::FileTime: BirthTime, MetadataChangeTime, ModificationTime, AccessTime 173 174 mutable uint cachedFlags : 30; 175 bool const isDefaultConstructed : 1; // QFileInfo is a default constructed instance 176 bool cache_enabled : 1; 177 mutable uint fileFlags; 178 mutable qint64 fileSize; getCachedFlag(uint c)179 inline bool getCachedFlag(uint c) const 180 { return cache_enabled ? (cachedFlags & c) : 0; } setCachedFlag(uint c)181 inline void setCachedFlag(uint c) const 182 { if (cache_enabled) cachedFlags |= c; } 183 184 template <typename Ret, typename FSLambda, typename EngineLambda> checkAttribute(Ret defaultValue,QFileSystemMetaData::MetaDataFlags fsFlags,const FSLambda & fsLambda,const EngineLambda & engineLambda)185 Ret checkAttribute(Ret defaultValue, QFileSystemMetaData::MetaDataFlags fsFlags, const FSLambda &fsLambda, 186 const EngineLambda &engineLambda) const 187 { 188 if (isDefaultConstructed) 189 return defaultValue; 190 if (fileEngine) 191 return engineLambda(); 192 if (!cache_enabled || !metaData.hasFlags(fsFlags)) { 193 QFileSystemEngine::fillMetaData(fileEntry, metaData, fsFlags); 194 // ignore errors, fillMetaData will have cleared the flags 195 } 196 return fsLambda(); 197 } 198 199 template <typename Ret, typename FSLambda, typename EngineLambda> checkAttribute(QFileSystemMetaData::MetaDataFlags fsFlags,const FSLambda & fsLambda,const EngineLambda & engineLambda)200 Ret checkAttribute(QFileSystemMetaData::MetaDataFlags fsFlags, const FSLambda &fsLambda, 201 const EngineLambda &engineLambda) const 202 { 203 return checkAttribute(Ret(), fsFlags, fsLambda, engineLambda); 204 } 205 }; 206 207 QT_END_NAMESPACE 208 209 #endif // QFILEINFO_P_H 210