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