1 | // Copyright (C) 2020 The Qt Company Ltd. |
2 | // Copyright (C) 2016 Intel Corporation. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | #ifndef QFILE_H |
6 | #define QFILE_H |
7 | |
8 | #include <QtCore/qfiledevice.h> |
9 | #include <QtCore/qstring.h> |
10 | #include <stdio.h> |
11 | |
12 | #if QT_CONFIG(cxx17_filesystem) |
13 | #include <filesystem> |
14 | #elif defined(Q_QDOC) |
15 | namespace std { |
16 | namespace filesystem { |
17 | class path { |
18 | }; |
19 | }; |
20 | }; |
21 | #endif |
22 | |
23 | #ifdef open |
24 | #error qfile.h must be included before any header file that defines open |
25 | #endif |
26 | |
27 | QT_BEGIN_NAMESPACE |
28 | |
29 | #ifdef Q_OS_WIN |
30 | |
31 | #if QT_DEPRECATED_SINCE(6,6) |
32 | QT_DEPRECATED_VERSION_X_6_6("Use QNtfsPermissionCheckGuard RAII class instead." ) |
33 | Q_CORE_EXPORT extern int qt_ntfs_permission_lookup; // defined in qfilesystemengine_win.cpp |
34 | #endif |
35 | |
36 | Q_CORE_EXPORT bool qEnableNtfsPermissionChecks() noexcept; |
37 | Q_CORE_EXPORT bool qDisableNtfsPermissionChecks() noexcept; |
38 | Q_CORE_EXPORT bool qAreNtfsPermissionChecksEnabled() noexcept; |
39 | |
40 | class QNtfsPermissionCheckGuard |
41 | { |
42 | Q_DISABLE_COPY_MOVE(QNtfsPermissionCheckGuard) |
43 | public: |
44 | Q_NODISCARD_CTOR |
45 | QNtfsPermissionCheckGuard() |
46 | { |
47 | qEnableNtfsPermissionChecks(); |
48 | } |
49 | |
50 | ~QNtfsPermissionCheckGuard() |
51 | { |
52 | qDisableNtfsPermissionChecks(); |
53 | } |
54 | }; |
55 | #endif // Q_OS_WIN |
56 | |
57 | #if QT_CONFIG(cxx17_filesystem) |
58 | namespace QtPrivate { |
59 | inline QString fromFilesystemPath(const std::filesystem::path &path) |
60 | { |
61 | #ifdef Q_OS_WIN |
62 | return QString::fromStdWString(path.native()); |
63 | #else |
64 | return QString::fromStdString(s: path.native()); |
65 | #endif |
66 | } |
67 | |
68 | inline std::filesystem::path toFilesystemPath(const QString &path) |
69 | { |
70 | return std::filesystem::path(reinterpret_cast<const char16_t *>(path.cbegin()), |
71 | reinterpret_cast<const char16_t *>(path.cend())); |
72 | } |
73 | |
74 | // Both std::filesystem::path and QString (without QT_NO_CAST_FROM_ASCII) can be implicitly |
75 | // constructed from string literals so we force the std::fs::path parameter to only |
76 | // accept std::fs::path with no implicit conversions. |
77 | template<typename T> |
78 | using ForceFilesystemPath = typename std::enable_if_t<std::is_same_v<std::filesystem::path, T>, int>; |
79 | } |
80 | #endif // QT_CONFIG(cxx17_filesystem) |
81 | |
82 | class QTemporaryFile; |
83 | class QFilePrivate; |
84 | |
85 | // ### Qt 7: remove this, and make constructors always explicit. |
86 | #if (QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)) || defined(QT_EXPLICIT_QFILE_CONSTRUCTION_FROM_PATH) |
87 | # define QFILE_MAYBE_EXPLICIT explicit |
88 | #else |
89 | # define QFILE_MAYBE_EXPLICIT Q_IMPLICIT |
90 | #endif |
91 | |
92 | class Q_CORE_EXPORT QFile : public QFileDevice |
93 | { |
94 | #ifndef QT_NO_QOBJECT |
95 | Q_OBJECT |
96 | #endif |
97 | Q_DECLARE_PRIVATE(QFile) |
98 | |
99 | public: |
100 | QFile(); |
101 | QFILE_MAYBE_EXPLICIT QFile(const QString &name); |
102 | #ifdef Q_QDOC |
103 | QFILE_MAYBE_EXPLICIT QFile(const std::filesystem::path &name); |
104 | #elif QT_CONFIG(cxx17_filesystem) |
105 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
106 | QFILE_MAYBE_EXPLICIT QFile(const T &name) : QFile(QtPrivate::fromFilesystemPath(path: name)) |
107 | { |
108 | } |
109 | #endif // QT_CONFIG(cxx17_filesystem) |
110 | |
111 | #ifndef QT_NO_QOBJECT |
112 | explicit QFile(QObject *parent); |
113 | QFile(const QString &name, QObject *parent); |
114 | |
115 | #ifdef Q_QDOC |
116 | QFile(const std::filesystem::path &path, QObject *parent); |
117 | #elif QT_CONFIG(cxx17_filesystem) |
118 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
119 | QFile(const T &path, QObject *parent) : QFile(QtPrivate::fromFilesystemPath(path), parent) |
120 | { |
121 | } |
122 | #endif // QT_CONFIG(cxx17_filesystem) |
123 | #endif // !QT_NO_QOBJECT |
124 | ~QFile(); |
125 | |
126 | QString fileName() const override; |
127 | #if QT_CONFIG(cxx17_filesystem) || defined(Q_QDOC) |
128 | std::filesystem::path filesystemFileName() const |
129 | { return QtPrivate::toFilesystemPath(path: fileName()); } |
130 | #endif |
131 | void setFileName(const QString &name); |
132 | #ifdef Q_QDOC |
133 | void setFileName(const std::filesystem::path &name); |
134 | #elif QT_CONFIG(cxx17_filesystem) |
135 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
136 | void setFileName(const T &name) |
137 | { |
138 | setFileName(QtPrivate::fromFilesystemPath(path: name)); |
139 | } |
140 | #endif // QT_CONFIG(cxx17_filesystem) |
141 | |
142 | #if defined(Q_OS_DARWIN) |
143 | // Mac always expects filenames in UTF-8... and decomposed... |
144 | static inline QByteArray encodeName(const QString &fileName) |
145 | { |
146 | return fileName.normalized(QString::NormalizationForm_D).toUtf8(); |
147 | } |
148 | static QString decodeName(const QByteArray &localFileName) |
149 | { |
150 | // note: duplicated in qglobal.cpp (qEnvironmentVariable) |
151 | return QString::fromUtf8(localFileName).normalized(QString::NormalizationForm_C); |
152 | } |
153 | static inline QString decodeName(const char *localFileName) |
154 | { |
155 | return QString::fromUtf8(localFileName).normalized(QString::NormalizationForm_C); |
156 | } |
157 | #else |
158 | static inline QByteArray encodeName(const QString &fileName) |
159 | { |
160 | return fileName.toLocal8Bit(); |
161 | } |
162 | static QString decodeName(const QByteArray &localFileName) |
163 | { |
164 | return QString::fromLocal8Bit(ba: localFileName); |
165 | } |
166 | static inline QString decodeName(const char *localFileName) |
167 | { |
168 | return QString::fromLocal8Bit(ba: localFileName); |
169 | } |
170 | #endif |
171 | |
172 | bool exists() const; |
173 | static bool exists(const QString &fileName); |
174 | #ifdef Q_QDOC |
175 | static bool exists(const std::filesystem::path &fileName); |
176 | #elif QT_CONFIG(cxx17_filesystem) |
177 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
178 | static bool exists(const T &fileName) |
179 | { |
180 | return exists(QtPrivate::fromFilesystemPath(path: fileName)); |
181 | } |
182 | #endif // QT_CONFIG(cxx17_filesystem) |
183 | |
184 | QString symLinkTarget() const; |
185 | static QString symLinkTarget(const QString &fileName); |
186 | #ifdef Q_QDOC |
187 | std::filesystem::path filesystemSymLinkTarget() const; |
188 | static std::filesystem::path filesystemSymLinkTarget(const std::filesystem::path &fileName); |
189 | #elif QT_CONFIG(cxx17_filesystem) |
190 | std::filesystem::path filesystemSymLinkTarget() const |
191 | { |
192 | return QtPrivate::toFilesystemPath(path: symLinkTarget()); |
193 | } |
194 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
195 | static std::filesystem::path filesystemSymLinkTarget(const T &fileName) |
196 | { |
197 | return QtPrivate::toFilesystemPath(path: symLinkTarget(QtPrivate::fromFilesystemPath(path: fileName))); |
198 | } |
199 | #endif // QT_CONFIG(cxx17_filesystem) |
200 | |
201 | bool remove(); |
202 | static bool remove(const QString &fileName); |
203 | #ifdef Q_QDOC |
204 | static bool remove(const std::filesystem::path &fileName); |
205 | #elif QT_CONFIG(cxx17_filesystem) |
206 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
207 | static bool remove(const T &fileName) |
208 | { |
209 | return remove(QtPrivate::fromFilesystemPath(path: fileName)); |
210 | } |
211 | #endif // QT_CONFIG(cxx17_filesystem) |
212 | |
213 | bool moveToTrash(); |
214 | static bool moveToTrash(const QString &fileName, QString *pathInTrash = nullptr); |
215 | #ifdef Q_QDOC |
216 | static bool moveToTrash(const std::filesystem::path &fileName, QString *pathInTrash = nullptr); |
217 | #elif QT_CONFIG(cxx17_filesystem) |
218 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
219 | static bool moveToTrash(const T &fileName, QString *pathInTrash = nullptr) |
220 | { |
221 | return moveToTrash(QtPrivate::fromFilesystemPath(path: fileName), pathInTrash); |
222 | } |
223 | #endif // QT_CONFIG(cxx17_filesystem) |
224 | |
225 | bool rename(const QString &newName); |
226 | static bool rename(const QString &oldName, const QString &newName); |
227 | #ifdef Q_QDOC |
228 | bool rename(const std::filesystem::path &newName); |
229 | static bool rename(const std::filesystem::path &oldName, |
230 | const std::filesystem::path &newName); |
231 | #elif QT_CONFIG(cxx17_filesystem) |
232 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
233 | bool rename(const T &newName) |
234 | { |
235 | return rename(QtPrivate::fromFilesystemPath(path: newName)); |
236 | } |
237 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
238 | static bool rename(const T &oldName, const T &newName) |
239 | { |
240 | return rename(QtPrivate::fromFilesystemPath(path: oldName), |
241 | QtPrivate::fromFilesystemPath(path: newName)); |
242 | } |
243 | #endif // QT_CONFIG(cxx17_filesystem) |
244 | |
245 | bool link(const QString &newName); |
246 | static bool link(const QString &fileName, const QString &newName); |
247 | #ifdef Q_QDOC |
248 | bool link(const std::filesystem::path &newName); |
249 | static bool link(const std::filesystem::path &fileName, |
250 | const std::filesystem::path &newName); |
251 | #elif QT_CONFIG(cxx17_filesystem) |
252 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
253 | bool link(const T &newName) |
254 | { |
255 | return link(QtPrivate::fromFilesystemPath(path: newName)); |
256 | } |
257 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
258 | static bool link(const T &fileName, const T &newName) |
259 | { |
260 | return link(QtPrivate::fromFilesystemPath(path: fileName), |
261 | QtPrivate::fromFilesystemPath(path: newName)); |
262 | } |
263 | #endif // QT_CONFIG(cxx17_filesystem) |
264 | |
265 | bool copy(const QString &newName); |
266 | static bool copy(const QString &fileName, const QString &newName); |
267 | #ifdef Q_QDOC |
268 | bool copy(const std::filesystem::path &newName); |
269 | static bool copy(const std::filesystem::path &fileName, |
270 | const std::filesystem::path &newName); |
271 | #elif QT_CONFIG(cxx17_filesystem) |
272 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
273 | bool copy(const T &newName) |
274 | { |
275 | return copy(QtPrivate::fromFilesystemPath(path: newName)); |
276 | } |
277 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
278 | static bool copy(const T &fileName, const T &newName) |
279 | { |
280 | return copy(QtPrivate::fromFilesystemPath(path: fileName), |
281 | QtPrivate::fromFilesystemPath(path: newName)); |
282 | } |
283 | #endif // QT_CONFIG(cxx17_filesystem) |
284 | |
285 | bool open(OpenMode flags) override; |
286 | bool open(OpenMode flags, Permissions permissions); |
287 | bool open(FILE *f, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle); |
288 | bool open(int fd, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle); |
289 | |
290 | qint64 size() const override; |
291 | |
292 | bool resize(qint64 sz) override; |
293 | static bool resize(const QString &filename, qint64 sz); |
294 | |
295 | Permissions permissions() const override; |
296 | static Permissions permissions(const QString &filename); |
297 | bool setPermissions(Permissions permissionSpec) override; |
298 | static bool setPermissions(const QString &filename, Permissions permissionSpec); |
299 | #ifdef Q_QDOC |
300 | static Permissions permissions(const std::filesystem::path &filename); |
301 | static bool setPermissions(const std::filesystem::path &filename, Permissions permissionSpec); |
302 | #elif QT_CONFIG(cxx17_filesystem) |
303 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
304 | static Permissions permissions(const T &filename) |
305 | { |
306 | return permissions(QtPrivate::fromFilesystemPath(path: filename)); |
307 | } |
308 | template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> |
309 | static bool setPermissions(const T &filename, Permissions permissionSpec) |
310 | { |
311 | return setPermissions(QtPrivate::fromFilesystemPath(path: filename), permissionSpec); |
312 | } |
313 | #endif // QT_CONFIG(cxx17_filesystem) |
314 | |
315 | protected: |
316 | #ifdef QT_NO_QOBJECT |
317 | QFile(QFilePrivate &dd); |
318 | #else |
319 | QFile(QFilePrivate &dd, QObject *parent = nullptr); |
320 | #endif |
321 | |
322 | private: |
323 | friend class QTemporaryFile; |
324 | Q_DISABLE_COPY(QFile) |
325 | }; |
326 | |
327 | QT_END_NAMESPACE |
328 | |
329 | #endif // QFILE_H |
330 | |