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)
15namespace 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
27QT_BEGIN_NAMESPACE
28
29#ifdef Q_OS_WIN
30
31#if QT_DEPRECATED_SINCE(6,6)
32QT_DEPRECATED_VERSION_X_6_6("Use QNtfsPermissionCheckGuard RAII class instead.")
33Q_CORE_EXPORT extern int qt_ntfs_permission_lookup; // defined in qfilesystemengine_win.cpp
34#endif
35
36Q_CORE_EXPORT bool qEnableNtfsPermissionChecks() noexcept;
37Q_CORE_EXPORT bool qDisableNtfsPermissionChecks() noexcept;
38Q_CORE_EXPORT bool qAreNtfsPermissionChecksEnabled() noexcept;
39
40class QNtfsPermissionCheckGuard
41{
42 Q_DISABLE_COPY_MOVE(QNtfsPermissionCheckGuard)
43public:
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)
58namespace QtPrivate {
59inline 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
68inline 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.
77template<typename T>
78using ForceFilesystemPath = typename std::enable_if_t<std::is_same_v<std::filesystem::path, T>, int>;
79}
80#endif // QT_CONFIG(cxx17_filesystem)
81
82class QTemporaryFile;
83class 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
92class Q_CORE_EXPORT QFile : public QFileDevice
93{
94#ifndef QT_NO_QOBJECT
95 Q_OBJECT
96#endif
97 Q_DECLARE_PRIVATE(QFile)
98
99public:
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
315protected:
316#ifdef QT_NO_QOBJECT
317 QFile(QFilePrivate &dd);
318#else
319 QFile(QFilePrivate &dd, QObject *parent = nullptr);
320#endif
321
322private:
323 friend class QTemporaryFile;
324 Q_DISABLE_COPY(QFile)
325};
326
327QT_END_NAMESPACE
328
329#endif // QFILE_H
330

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