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 QFSFILEENGINE_P_H
5#define QFSFILEENGINE_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/private/qabstractfileengine_p.h"
20#include <QtCore/private/qfilesystementry_p.h>
21#include <QtCore/private/qfilesystemmetadata_p.h>
22#include <qhash.h>
23
24#include <optional>
25
26#ifdef Q_OS_UNIX
27#include <sys/types.h> // for mode_t
28#endif
29
30#ifndef QT_NO_FSFILEENGINE
31
32QT_BEGIN_NAMESPACE
33
34struct ProcessOpenModeResult
35{
36 bool ok;
37 QIODevice::OpenMode openMode;
38 QString error;
39};
40Q_CORE_EXPORT ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode mode);
41
42class QFSFileEnginePrivate;
43
44class Q_CORE_EXPORT QFSFileEngine : public QAbstractFileEngine
45{
46 Q_DECLARE_PRIVATE(QFSFileEngine)
47public:
48 QFSFileEngine();
49 explicit QFSFileEngine(const QString &file);
50 ~QFSFileEngine();
51
52 bool open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) override;
53 bool open(QIODevice::OpenMode flags, FILE *fh);
54 bool close() override;
55 bool flush() override;
56 bool syncToDisk() override;
57 qint64 size() const override;
58 qint64 pos() const override;
59 bool seek(qint64) override;
60 bool isSequential() const override;
61 bool remove() override;
62 bool copy(const QString &newName) override;
63 bool rename(const QString &newName) override;
64 bool renameOverwrite(const QString &newName) override;
65 bool link(const QString &newName) override;
66 bool mkdir(const QString &dirName, bool createParentDirectories,
67 std::optional<QFile::Permissions> permissions) const override;
68 bool rmdir(const QString &dirName, bool recurseParentDirectories) const override;
69 bool setSize(qint64 size) override;
70 bool caseSensitive() const override;
71 bool isRelativePath() const override;
72 QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const override;
73 FileFlags fileFlags(FileFlags type) const override;
74 bool setPermissions(uint perms) override;
75 QByteArray id() const override;
76 QString fileName(FileName file) const override;
77 uint ownerId(FileOwner) const override;
78 QString owner(FileOwner) const override;
79 bool setFileTime(const QDateTime &newDate, FileTime time) override;
80 QDateTime fileTime(FileTime time) const override;
81 void setFileName(const QString &file) override;
82 int handle() const override;
83
84#ifndef QT_NO_FILESYSTEMITERATOR
85 Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override;
86 Iterator *endEntryList() override;
87#endif
88
89 qint64 read(char *data, qint64 maxlen) override;
90 qint64 readLine(char *data, qint64 maxlen) override;
91 qint64 write(const char *data, qint64 len) override;
92 bool cloneTo(QAbstractFileEngine *target) override;
93
94 virtual bool isUnnamedFile() const
95 { return false; }
96
97 bool extension(Extension extension, const ExtensionOption *option = nullptr, ExtensionReturn *output = nullptr) override;
98 bool supportsExtension(Extension extension) const override;
99
100 //FS only!!
101 bool open(QIODevice::OpenMode flags, int fd);
102 bool open(QIODevice::OpenMode flags, int fd, QFile::FileHandleFlags handleFlags);
103 bool open(QIODevice::OpenMode flags, FILE *fh, QFile::FileHandleFlags handleFlags);
104 static bool setCurrentPath(const QString &path);
105 static QString currentPath(const QString &path = QString());
106 static QString homePath();
107 static QString rootPath();
108 static QString tempPath();
109 static QFileInfoList drives();
110
111protected:
112 QFSFileEngine(QFSFileEnginePrivate &dd);
113};
114
115class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate
116{
117 Q_DECLARE_PUBLIC(QFSFileEngine)
118
119public:
120#ifdef Q_OS_WIN
121 static QString longFileName(const QString &path);
122#endif
123
124 QFileSystemEntry fileEntry;
125 QIODevice::OpenMode openMode;
126
127 bool nativeOpen(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions);
128 bool openFh(QIODevice::OpenMode flags, FILE *fh);
129 bool openFd(QIODevice::OpenMode flags, int fd);
130 bool nativeClose();
131 bool closeFdFh();
132 bool nativeFlush();
133 bool nativeSyncToDisk();
134 bool flushFh();
135 qint64 nativeSize() const;
136#ifndef Q_OS_WIN
137 qint64 sizeFdFh() const;
138#endif
139 qint64 nativePos() const;
140 qint64 posFdFh() const;
141 bool nativeSeek(qint64);
142 bool seekFdFh(qint64);
143 qint64 nativeRead(char *data, qint64 maxlen);
144 qint64 readFdFh(char *data, qint64 maxlen);
145 qint64 nativeReadLine(char *data, qint64 maxlen);
146 qint64 readLineFdFh(char *data, qint64 maxlen);
147 qint64 nativeWrite(const char *data, qint64 len);
148 qint64 writeFdFh(const char *data, qint64 len);
149 int nativeHandle() const;
150 bool nativeIsSequential() const;
151#ifndef Q_OS_WIN
152 bool isSequentialFdFh() const;
153#endif
154
155 uchar *map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags);
156 bool unmap(uchar *ptr);
157 void unmapAll();
158
159 mutable QFileSystemMetaData metaData;
160
161 FILE *fh;
162
163#ifdef Q_OS_WIN
164 HANDLE fileHandle;
165 HANDLE mapHandle;
166 QHash<uchar *, DWORD /* offset % AllocationGranularity */> maps;
167
168 mutable int cachedFd;
169 mutable DWORD fileAttrib;
170#else
171 struct StartAndLength {
172 int start; // offset % PageSize
173 size_t length; // length + offset % PageSize
174 };
175 QHash<uchar *, StartAndLength> maps;
176#endif
177 int fd;
178
179 enum LastIOCommand
180 {
181 IOFlushCommand,
182 IOReadCommand,
183 IOWriteCommand
184 };
185 LastIOCommand lastIOCommand;
186 bool lastFlushFailed;
187 bool closeFileHandle;
188
189 mutable uint is_sequential : 2;
190 mutable uint tried_stat : 1;
191 mutable uint need_lstat : 1;
192 mutable uint is_link : 1;
193
194#if defined(Q_OS_WIN)
195 bool doStat(QFileSystemMetaData::MetaDataFlags flags) const;
196#else
197 bool doStat(QFileSystemMetaData::MetaDataFlags flags = QFileSystemMetaData::PosixStatFlags) const;
198#endif
199 bool isSymlink() const;
200
201#if defined(Q_OS_WIN32)
202 int sysOpen(const QString &, int flags);
203#endif
204
205 static bool openModeCanCreate(QIODevice::OpenMode openMode)
206 {
207 // WriteOnly can create, but only when ExistingOnly isn't specified.
208 // ReadOnly by itself never creates.
209 return (openMode & QFile::WriteOnly) && !(openMode & QFile::ExistingOnly);
210 }
211protected:
212 QFSFileEnginePrivate();
213
214 void init();
215
216 QAbstractFileEngine::FileFlags getPermissions(QAbstractFileEngine::FileFlags type) const;
217
218#ifdef Q_OS_UNIX
219 bool nativeOpenImpl(QIODevice::OpenMode openMode, mode_t mode);
220#endif
221};
222
223QT_END_NAMESPACE
224
225#endif // QT_NO_FSFILEENGINE
226
227#endif // QFSFILEENGINE_P_H
228

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