1 /*
2  * DQt - D bindings for the Qt Toolkit
3  *
4  * GNU Lesser General Public License Usage
5  * This file may be used under the terms of the GNU Lesser
6  * General Public License version 3 as published by the Free Software
7  * Foundation and appearing in the file LICENSE.LGPL3 included in the
8  * packaging of this file. Please review the following information to
9  * ensure the GNU Lesser General Public License version 3 requirements
10  * will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
11  */
12 module qt.core.file;
13 extern(C++):
14 
15 import core.stdc.stdio;
16 import qt.config;
17 import qt.core.bytearray;
18 import qt.core.filedevice;
19 import qt.core.global;
20 import qt.core.object;
21 import qt.core.string;
22 import qt.helpers;
23 
24 /+ #if QT_CONFIG(cxx17_filesystem)
25 #elif defined(Q_CLANG_QDOC)
26 namespace std {
27     namespace filesystem {
28         class path {
29         };
30     };
31 };
32 #endif
33 
34 #ifdef open
35 #error qfile.h must be included before any header file that defines open
36 #endif
37 
38 
39 #if QT_CONFIG(cxx17_filesystem)
40 namespace QtPrivate {
41 inline QString fromFilesystemPath(const std::filesystem::path &path)
42 {
43 #ifdef Q_OS_WIN
44     return QString::fromStdWString(path.native());
45 #else
46     return QString::fromStdString(path.native());
47 #endif
48 }
49 
50 inline std::filesystem::path toFilesystemPath(const QString &path)
51 {
52     return std::filesystem::path(reinterpret_cast<const char16_t *>(path.cbegin()),
53                                  reinterpret_cast<const char16_t *>(path.cend()));
54 }
55 
56 // Both std::filesystem::path and QString (without QT_NO_CAST_FROM_ASCII) can be implicitly
57 // constructed from string literals so we force the std::fs::path parameter to only
58 // accept std::fs::path with no implicit conversions.
59 template<typename T>
60 using ForceFilesystemPath = typename std::enable_if_t<std::is_same_v<std::filesystem::path, T>, int>;
61 }
62 #endif +/ // QT_CONFIG(cxx17_filesystem)
63 
64 extern(C++, class) struct QTemporaryFile;
65 extern(C++, class) struct QFilePrivate;
66 
67 /// Binding for C++ class [QFile](https://doc.qt.io/qt-6/qfile.html).
68 class /+ Q_CORE_EXPORT +/ QFile : QFileDevice
69 {
70 /+ #ifndef QT_NO_QOBJECT +/
71     mixin(Q_OBJECT);
72 /+ #endif
73     Q_DECLARE_PRIVATE(QFile) +/
74 
75 public:
76     this();
77     this(ref const(QString) name);
78 /+ #ifdef Q_CLANG_QDOC
79     QFile(const std::filesystem::path &name);
80 #elif QT_CONFIG(cxx17_filesystem)
81     template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
82     QFile(const T &name) : QFile(QtPrivate::fromFilesystemPath(name))
83     {
84     }
85 #endif // QT_CONFIG(cxx17_filesystem)
86 
87 #ifndef QT_NO_QOBJECT +/
88     /+ explicit +/this(QObject parent);
89     this(ref const(QString) name, QObject parent);
90 
91 /+ #ifdef Q_CLANG_QDOC
92     QFile(const std::filesystem::path &path, QObject *parent);
93 #elif QT_CONFIG(cxx17_filesystem)
94     template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
95     QFile(const T &path, QObject *parent) : QFile(QtPrivate::fromFilesystemPath(path), parent)
96     {
97     }
98 #endif // QT_CONFIG(cxx17_filesystem)
99 #endif +/ // !QT_NO_QOBJECT
100     ~this();
101 
102     override QString fileName() const;
103 /+ #if QT_CONFIG(cxx17_filesystem) || defined(Q_CLANG_QDOC)
104     std::filesystem::path filesystemFileName() const
105     { return QtPrivate::toFilesystemPath(fileName()); }
106 #endif +/
107     final void setFileName(ref const(QString) name);
108 /+ #ifdef Q_CLANG_QDOC
109     void setFileName(const std::filesystem::path &name);
110 #elif QT_CONFIG(cxx17_filesystem)
111     template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
112     void setFileName(const T &name)
113     {
114         setFileName(QtPrivate::fromFilesystemPath(name));
115     }
116 #endif // QT_CONFIG(cxx17_filesystem)
117 
118 #if defined(Q_OS_DARWIN) +/
119     // Mac always expects filenames in UTF-8... and decomposed...
120     static if((versionIsSet!("OSX") || versionIsSet!("iOS") || versionIsSet!("TVOS") || versionIsSet!("WatchOS")))
121     {
122         pragma(inline, true) static QByteArray encodeName(ref const(QString) fileName)
123         {
124             return fileName.normalized(QString.NormalizationForm.NormalizationForm_D).toUtf8();
125         }
126         static QString decodeName(ref const(QByteArray) localFileName)
127         {
128             // note: duplicated in qglobal.cpp (qEnvironmentVariable)
129             return QString.fromUtf8(localFileName).normalized(QString.NormalizationForm.NormalizationForm_C);
130         }
131         pragma(inline, true) static QString decodeName(const(char)* localFileName)
132         {
133             return QString.fromUtf8(localFileName).normalized(QString.NormalizationForm.NormalizationForm_C);
134         }
135     }
136     else
137     {
138     /+ #else +/
139         pragma(inline, true) static QByteArray encodeName(ref const(QString) fileName)
140         {
141             return fileName.toLocal8Bit();
142         }
143         static QString decodeName(ref const(QByteArray) localFileName)
144         {
145             return QString.fromLocal8Bit(localFileName);
146         }
147         pragma(inline, true) static QString decodeName(const(char)* localFileName)
148         {
149             import qt.core.bytearrayview;
150 
151             return QString.fromLocal8Bit(cast(QByteArrayView)(localFileName));
152         }
153     }
154 /+ #endif +/
155 
156     final bool exists() const;
157     static bool exists(ref const(QString) fileName);
158 
159     final QString symLinkTarget() const;
160     static QString symLinkTarget(ref const(QString) fileName);
161 
162     final bool remove();
163     static bool remove(ref const(QString) fileName);
164 
165     final bool moveToTrash();
166     static bool moveToTrash(ref const(QString) fileName, QString* pathInTrash = null);
167 
168     final bool rename(ref const(QString) newName);
169 /+ #ifdef Q_CLANG_QDOC
170     bool rename(const std::filesystem::path &newName);
171 #elif QT_CONFIG(cxx17_filesystem)
172     template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
173     bool rename(const T &newName)
174     {
175         return rename(QtPrivate::fromFilesystemPath(newName));
176     }
177 #endif +/ // QT_CONFIG(cxx17_filesystem)
178     static bool rename(ref const(QString) oldName, ref const(QString) newName);
179 
180     final bool link(ref const(QString) newName);
181 /+ #ifdef Q_CLANG_QDOC
182     bool link(const std::filesystem::path &newName);
183 #elif QT_CONFIG(cxx17_filesystem)
184     template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
185     bool link(const T &newName)
186     {
187         return link(QtPrivate::fromFilesystemPath(newName));
188     }
189 #endif +/ // QT_CONFIG(cxx17_filesystem)
190     static bool link(ref const(QString) oldname, ref const(QString) newName);
191 
192     /+ bool copy(const QString &newName); +/
193 /+ #ifdef Q_CLANG_QDOC
194     bool copy(const std::filesystem::path &newName);
195 #elif QT_CONFIG(cxx17_filesystem)
196     template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
197     bool copy(const T &newName)
198     {
199         return copy(QtPrivate::fromFilesystemPath(newName));
200     }
201 #endif +/ // QT_CONFIG(cxx17_filesystem)
202     /+ static bool copy(const QString &fileName, const QString &newName); +/
203 
204     override bool open(OpenMode flags);
205     //final bool open(FILE* f, OpenMode ioFlags, FileHandleFlags handleFlags=FileHandleFlag.DontCloseHandle);
206     final bool open(int fd, OpenMode ioFlags, FileHandleFlags handleFlags=FileHandleFlag.DontCloseHandle);
207 
208     override qint64 size() const;
209 
210     override bool resize(qint64 sz);
211     static bool resize(ref const(QString) filename, qint64 sz);
212 
213     override Permissions permissions() const;
214     static Permissions permissions(ref const(QString) filename);
215     override bool setPermissions(Permissions permissionSpec);
216     static bool setPermissions(ref const(QString) filename, Permissions permissionSpec);
217 /+ #ifdef Q_CLANG_QDOC
218     static Permissions permissions(const std::filesystem::path &filename);
219     static bool setPermissions(const std::filesystem::path &filename, Permissions permissionSpec);
220 #elif QT_CONFIG(cxx17_filesystem)
221     template<typename T,  QtPrivate::ForceFilesystemPath<T> = 0>
222     static Permissions permissions(const T &filename)
223     {
224         return permissions(QtPrivate::fromFilesystemPath(filename));
225     }
226     template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
227     static bool setPermissions(const T &filename, Permissions permissionSpec)
228     {
229         return setPermissions(QtPrivate::fromFilesystemPath(filename), permissionSpec);
230     }
231 #endif +/ // QT_CONFIG(cxx17_filesystem)
232 
233 protected:
234 /+ #ifdef QT_NO_QOBJECT
235     QFile(QFilePrivate &dd);
236 #else +/
237     this(ref QFilePrivate dd, QObject parent = null);
238 /+ #endif +/
239 
240 private:
241     /+ friend class QTemporaryFile; +/
242     /+ Q_DISABLE_COPY(QFile) +/
243     mixin(CREATE_CONVENIENCE_WRAPPERS);
244 }
245