1// Copyright (C) 2016 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#ifndef QFILESYSTEMMETADATA_P_H
5#define QFILESYSTEMMETADATA_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qplatformdefs.h"
19#include <QtCore/qglobal.h>
20#include <QtCore/qdatetime.h>
21#include <QtCore/qtimezone.h>
22#include <QtCore/private/qabstractfileengine_p.h>
23
24// Platform-specific includes
25#ifdef Q_OS_WIN
26# include <QtCore/qt_windows.h>
27# ifndef IO_REPARSE_TAG_SYMLINK
28# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
29# endif
30#endif
31
32#ifdef Q_OS_UNIX
33struct statx;
34#endif
35
36QT_BEGIN_NAMESPACE
37
38class QFileSystemEngine;
39
40class Q_AUTOTEST_EXPORT QFileSystemMetaData
41{
42public:
43 QFileSystemMetaData()
44 : size_(-1)
45 {
46 }
47
48 enum MetaDataFlag {
49 // Permissions, overlaps with QFile::Permissions
50 OtherReadPermission = 0x00000004, OtherWritePermission = 0x00000002, OtherExecutePermission = 0x00000001,
51 GroupReadPermission = 0x00000040, GroupWritePermission = 0x00000020, GroupExecutePermission = 0x00000010,
52 UserReadPermission = 0x00000400, UserWritePermission = 0x00000200, UserExecutePermission = 0x00000100,
53 OwnerReadPermission = 0x00004000, OwnerWritePermission = 0x00002000, OwnerExecutePermission = 0x00001000,
54
55 OtherPermissions = OtherReadPermission | OtherWritePermission | OtherExecutePermission,
56 GroupPermissions = GroupReadPermission | GroupWritePermission | GroupExecutePermission,
57 UserPermissions = UserReadPermission | UserWritePermission | UserExecutePermission,
58 OwnerPermissions = OwnerReadPermission | OwnerWritePermission | OwnerExecutePermission,
59
60 ReadPermissions = OtherReadPermission | GroupReadPermission | UserReadPermission | OwnerReadPermission,
61 WritePermissions = OtherWritePermission | GroupWritePermission | UserWritePermission | OwnerWritePermission,
62 ExecutePermissions = OtherExecutePermission | GroupExecutePermission | UserExecutePermission | OwnerExecutePermission,
63
64 Permissions = OtherPermissions | GroupPermissions | UserPermissions | OwnerPermissions,
65
66 // Type
67 LinkType = 0x00010000,
68 FileType = 0x00020000,
69 DirectoryType = 0x00040000,
70#if defined(Q_OS_DARWIN)
71 BundleType = 0x00080000,
72 AliasType = 0x08000000,
73#else
74 BundleType = 0x0,
75 AliasType = 0x0,
76#endif
77#if defined(Q_OS_WIN)
78 JunctionType = 0x04000000,
79 WinLnkType = 0x08000000, // Note: Uses the same position for AliasType on Mac
80#else
81 JunctionType = 0x0,
82 WinLnkType = 0x0,
83#endif
84 SequentialType = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag
85
86 LegacyLinkType = LinkType | AliasType | WinLnkType,
87
88 Type = LinkType | FileType | DirectoryType | BundleType | SequentialType | AliasType,
89
90 // Attributes
91 HiddenAttribute = 0x00100000,
92 SizeAttribute = 0x00200000, // Note: overlaps with QAbstractFileEngine::LocalDiskFlag
93 ExistsAttribute = 0x00400000, // For historical reasons, indicates existence of data, not the file
94#if defined(Q_OS_WIN)
95 WasDeletedAttribute = 0x0,
96#else
97 WasDeletedAttribute = 0x40000000, // Indicates the file was deleted
98#endif
99
100 Attributes = HiddenAttribute | SizeAttribute | ExistsAttribute | WasDeletedAttribute,
101
102 // Times - if we know one of them, we know them all
103 AccessTime = 0x02000000,
104 BirthTime = 0x02000000,
105 MetadataChangeTime = 0x02000000,
106 ModificationTime = 0x02000000,
107
108 Times = AccessTime | BirthTime | MetadataChangeTime | ModificationTime,
109
110 // Owner IDs
111 UserId = 0x10000000,
112 GroupId = 0x20000000,
113
114 CaseSensitive = 0x80000000,
115
116 OwnerIds = UserId | GroupId,
117
118 PosixStatFlags = QFileSystemMetaData::OtherPermissions
119 | QFileSystemMetaData::GroupPermissions
120 | QFileSystemMetaData::OwnerPermissions
121 | QFileSystemMetaData::FileType
122 | QFileSystemMetaData::DirectoryType
123 | QFileSystemMetaData::SequentialType
124 | QFileSystemMetaData::SizeAttribute
125 | QFileSystemMetaData::WasDeletedAttribute
126 | QFileSystemMetaData::Times
127 | QFileSystemMetaData::OwnerIds,
128
129#if defined(Q_OS_WIN)
130 WinStatFlags = QFileSystemMetaData::FileType
131 | QFileSystemMetaData::DirectoryType
132 | QFileSystemMetaData::HiddenAttribute
133 | QFileSystemMetaData::ExistsAttribute
134 | QFileSystemMetaData::SizeAttribute
135 | QFileSystemMetaData::Times,
136#endif
137
138 AllMetaDataFlags = 0xFFFFFFFF
139
140 };
141 Q_DECLARE_FLAGS(MetaDataFlags, MetaDataFlag)
142
143 bool hasFlags(MetaDataFlags flags) const
144 {
145 return ((knownFlagsMask & flags) == flags);
146 }
147
148 MetaDataFlags missingFlags(MetaDataFlags flags)
149 {
150 return flags & ~knownFlagsMask;
151 }
152
153 void clear()
154 {
155 knownFlagsMask = {};
156 }
157
158 void clearFlags(MetaDataFlags flags = AllMetaDataFlags)
159 {
160 knownFlagsMask &= ~flags;
161 }
162
163 bool exists() const { return entryFlags.testAnyFlag(flag: ExistsAttribute); }
164
165 bool isLink() const { return entryFlags.testAnyFlag(flag: LinkType); }
166 bool isFile() const { return entryFlags.testAnyFlag(flag: FileType); }
167 bool isDirectory() const { return entryFlags.testAnyFlag(flag: DirectoryType); }
168 bool isBundle() const;
169 bool isAlias() const;
170 bool isLegacyLink() const { return entryFlags.testAnyFlag(flag: LegacyLinkType); }
171 bool isSequential() const { return entryFlags.testAnyFlag(flag: SequentialType); }
172 bool isHidden() const { return entryFlags.testAnyFlag(flag: HiddenAttribute); }
173 bool wasDeleted() const { return entryFlags.testAnyFlag(flag: WasDeletedAttribute); }
174#if defined(Q_OS_WIN)
175 bool isLnkFile() const { return entryFlags.testAnyFlag(WinLnkType); }
176 bool isJunction() const { return entryFlags.testAnyFlag(JunctionType); }
177#else
178 bool isLnkFile() const { return false; }
179 bool isJunction() const { return false; }
180#endif
181
182 qint64 size() const { return size_; }
183
184 inline QFile::Permissions permissions() const;
185
186 QDateTime accessTime() const;
187 QDateTime birthTime() const;
188 QDateTime metadataChangeTime() const;
189 QDateTime modificationTime() const;
190
191 QDateTime fileTime(QFile::FileTime time) const;
192 uint userId() const;
193 uint groupId() const;
194 uint ownerId(QAbstractFileEngine::FileOwner owner) const;
195
196 bool isReadable() const { return permissions().testAnyFlags(flags: QFile::ReadUser); }
197 bool isWritable() const { return permissions().testAnyFlags(flags: QFile::WriteUser); }
198 bool isExecutable() const { return permissions().testAnyFlags(flags: QFile::ExeUser); }
199
200#ifdef Q_OS_UNIX
201 void fillFromStatxBuf(const struct statx &statBuffer);
202 void fillFromStatBuf(const QT_STATBUF &statBuffer);
203 void fillFromDirEnt(const QT_DIRENT &statBuffer);
204#endif
205
206#if defined(Q_OS_WIN)
207 inline void fillFromFileAttribute(DWORD fileAttribute, bool isDriveRoot = false);
208 inline void fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType = false, bool isDriveRoot = false);
209 inline void fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo);
210#endif
211private:
212 friend class QFileSystemEngine;
213
214 MetaDataFlags knownFlagsMask;
215 MetaDataFlags entryFlags;
216
217 qint64 size_ = 0;
218
219 // Platform-specific data goes here:
220#if defined(Q_OS_WIN)
221 DWORD fileAttribute_;
222 FILETIME birthTime_;
223 FILETIME changeTime_;
224 FILETIME lastAccessTime_;
225 FILETIME lastWriteTime_;
226#else
227 // msec precision
228 qint64 accessTime_ = 0;
229 qint64 birthTime_ = 0;
230 qint64 metadataChangeTime_ = 0;
231 qint64 modificationTime_ = 0;
232
233 uint userId_ = (uint) -2;
234 uint groupId_ = (uint) -2;
235#endif
236
237};
238
239Q_DECLARE_OPERATORS_FOR_FLAGS(QFileSystemMetaData::MetaDataFlags)
240
241inline QFile::Permissions QFileSystemMetaData::permissions() const { return QFile::Permissions::fromInt(i: (Permissions & entryFlags).toInt()); }
242
243#if defined(Q_OS_DARWIN)
244inline bool QFileSystemMetaData::isBundle() const { return entryFlags.testAnyFlag(BundleType); }
245inline bool QFileSystemMetaData::isAlias() const { return entryFlags.testAnyFlag(AliasType); }
246#else
247inline bool QFileSystemMetaData::isBundle() const { return false; }
248inline bool QFileSystemMetaData::isAlias() const { return false; }
249#endif
250
251#if defined(Q_OS_UNIX) || defined (Q_OS_WIN)
252inline QDateTime QFileSystemMetaData::fileTime(QFile::FileTime time) const
253{
254 switch (time) {
255 case QFile::FileModificationTime:
256 return modificationTime();
257
258 case QFile::FileAccessTime:
259 return accessTime();
260
261 case QFile::FileBirthTime:
262 return birthTime();
263
264 case QFile::FileMetadataChangeTime:
265 return metadataChangeTime();
266 }
267
268 return QDateTime();
269}
270#endif
271
272#if defined(Q_OS_UNIX)
273inline QDateTime QFileSystemMetaData::birthTime() const
274{
275 return birthTime_
276 ? QDateTime::fromMSecsSinceEpoch(msecs: birthTime_, timeZone: QTimeZone::UTC)
277 : QDateTime();
278}
279inline QDateTime QFileSystemMetaData::metadataChangeTime() const
280{
281 return metadataChangeTime_
282 ? QDateTime::fromMSecsSinceEpoch(msecs: metadataChangeTime_, timeZone: QTimeZone::UTC)
283 : QDateTime();
284}
285inline QDateTime QFileSystemMetaData::modificationTime() const
286{
287 return modificationTime_
288 ? QDateTime::fromMSecsSinceEpoch(msecs: modificationTime_, timeZone: QTimeZone::UTC)
289 : QDateTime();
290}
291inline QDateTime QFileSystemMetaData::accessTime() const
292{
293 return accessTime_
294 ? QDateTime::fromMSecsSinceEpoch(msecs: accessTime_, timeZone: QTimeZone::UTC)
295 : QDateTime();
296}
297
298inline uint QFileSystemMetaData::userId() const { return userId_; }
299inline uint QFileSystemMetaData::groupId() const { return groupId_; }
300
301inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const
302{
303 if (owner == QAbstractFileEngine::OwnerUser)
304 return userId();
305 else
306 return groupId();
307}
308#endif
309
310#if defined(Q_OS_WIN)
311inline uint QFileSystemMetaData::userId() const { return (uint) -2; }
312inline uint QFileSystemMetaData::groupId() const { return (uint) -2; }
313inline uint QFileSystemMetaData::ownerId(QAbstractFileEngine::FileOwner owner) const
314{
315 if (owner == QAbstractFileEngine::OwnerUser)
316 return userId();
317 else
318 return groupId();
319}
320
321inline void QFileSystemMetaData::fillFromFileAttribute(DWORD fileAttribute,bool isDriveRoot)
322{
323 fileAttribute_ = fileAttribute;
324 // Ignore the hidden attribute for drives.
325 if (!isDriveRoot && (fileAttribute_ & FILE_ATTRIBUTE_HIDDEN))
326 entryFlags |= HiddenAttribute;
327 entryFlags |= ((fileAttribute & FILE_ATTRIBUTE_DIRECTORY) ? DirectoryType: FileType);
328 entryFlags |= ExistsAttribute;
329 knownFlagsMask |= FileType | DirectoryType | HiddenAttribute | ExistsAttribute;
330}
331
332inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType, bool isDriveRoot)
333{
334 fillFromFileAttribute(findData.dwFileAttributes, isDriveRoot);
335 birthTime_ = findData.ftCreationTime;
336 lastAccessTime_ = findData.ftLastAccessTime;
337 changeTime_ = lastWriteTime_ = findData.ftLastWriteTime;
338 if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) {
339 size_ = 0;
340 } else {
341 size_ = findData.nFileSizeHigh;
342 size_ <<= 32;
343 size_ += findData.nFileSizeLow;
344 }
345 knownFlagsMask |= Times | SizeAttribute;
346 if (setLinkType) {
347 knownFlagsMask |= LinkType;
348 entryFlags &= ~LinkType;
349 if (fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) {
350 if (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
351 entryFlags |= LinkType;
352#if defined(IO_REPARSE_TAG_MOUNT_POINT)
353 } else if ((fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY)
354 && (findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) {
355 entryFlags |= JunctionType;
356#endif
357 }
358 }
359 }
360}
361
362inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo)
363{
364 fillFromFileAttribute(fileInfo.dwFileAttributes);
365 birthTime_ = fileInfo.ftCreationTime;
366 lastAccessTime_ = fileInfo.ftLastAccessTime;
367 changeTime_ = lastWriteTime_ = fileInfo.ftLastWriteTime;
368 if (fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) {
369 size_ = 0;
370 } else {
371 size_ = fileInfo.nFileSizeHigh;
372 size_ <<= 32;
373 size_ += fileInfo.nFileSizeLow;
374 }
375 knownFlagsMask |= Times | SizeAttribute;
376}
377#endif // Q_OS_WIN
378
379QT_END_NAMESPACE
380
381#endif // include guard
382

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/corelib/io/qfilesystemmetadata_p.h