1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21#ifndef LOVE_FILESYSTEM_FILESYSTEM_H
22#define LOVE_FILESYSTEM_FILESYSTEM_H
23
24// LOVE
25#include "common/config.h"
26#include "common/Module.h"
27#include "common/int.h"
28#include "common/StringMap.h"
29#include "FileData.h"
30#include "File.h"
31
32// C++
33#include <string>
34#include <vector>
35
36// In Windows, we would like to use "LOVE" as the
37// application folder, but in Linux, we like .love.
38#define LOVE_APPDATA_PREFIX ""
39#ifdef LOVE_WINDOWS
40# define LOVE_APPDATA_FOLDER "LOVE"
41# define LOVE_PATH_SEPARATOR "/"
42# define LOVE_MAX_PATH _MAX_PATH
43#else
44# if defined(LOVE_MACOSX) || defined(LOVE_IOS)
45# define LOVE_APPDATA_FOLDER "LOVE"
46# elif defined(LOVE_LINUX)
47# define LOVE_APPDATA_FOLDER "love"
48# else
49# define LOVE_APPDATA_PREFIX "."
50# define LOVE_APPDATA_FOLDER "love"
51# endif
52# define LOVE_PATH_SEPARATOR "/"
53# define LOVE_MAX_PATH MAXPATHLEN
54#endif
55
56namespace love
57{
58namespace filesystem
59{
60
61class Filesystem : public Module
62{
63public:
64
65 enum FileType
66 {
67 FILETYPE_FILE,
68 FILETYPE_DIRECTORY,
69 FILETYPE_SYMLINK,
70 FILETYPE_OTHER,
71 FILETYPE_MAX_ENUM
72 };
73
74 struct Info
75 {
76 // Numbers will be -1 if they cannot be determined.
77 int64 size;
78 int64 modtime;
79 FileType type;
80 };
81
82 static love::Type type;
83
84 Filesystem();
85 virtual ~Filesystem();
86
87 // Implements Module.
88 virtual ModuleType getModuleType() const { return M_FILESYSTEM; }
89
90 virtual void init(const char *arg0) = 0;
91
92 virtual void setFused(bool fused) = 0;
93 virtual bool isFused() const = 0;
94
95 /**
96 * This sets up the save directory. If the
97 * it is already set up, nothing happens.
98 * @return True on success, false otherwise.
99 **/
100 virtual bool setupWriteDirectory() = 0;
101
102 /**
103 * This sets the save location on Android.
104 * False for internal, true for external
105 * @param external Bool for whether
106 * Android should use external file storage.
107 **/
108 virtual void setAndroidSaveExternal(bool useExternal = false);
109
110 /**
111 * Gets whether the Android save is external.
112 * Returns a bool.
113 **/
114 virtual bool isAndroidSaveExternal() const;
115
116 /**
117 * Sets the name of the save folder.
118 * @param ident The name of the game. Will be used to
119 * to create the folder in the LOVE data folder.
120 **/
121 virtual bool setIdentity(const char *ident, bool appendToPath = false) = 0;
122 virtual const char *getIdentity() const = 0;
123
124 /**
125 * Sets the path to the game source.
126 * This can only be set once.
127 * @param source Path to a directory or a .love-file.
128 **/
129 virtual bool setSource(const char *source) = 0;
130
131 /**
132 * Gets the path to the game source.
133 * Returns a 0-length string if the source has not been set.
134 **/
135 virtual const char *getSource() const = 0;
136
137 virtual bool mount(const char *archive, const char *mountpoint, bool appendToPath = false) = 0;
138 virtual bool mount(Data *data, const char *archivename, const char *mountpoint, bool appendToPath = false) = 0;
139 virtual bool unmount(const char *archive) = 0;
140 virtual bool unmount(Data *data) = 0;
141
142 /**
143 * Creates a new file.
144 **/
145 virtual File *newFile(const char *filename) const = 0;
146
147 /**
148 * Creates a new FileData object. Data will be copied.
149 * @param data Pointer to the data.
150 * @param size The size of the data.
151 * @param filename The full filename used to file type identification.
152 **/
153 virtual FileData *newFileData(const void *data, size_t size, const char *filename) const;
154
155 /**
156 * Gets the current working directory.
157 **/
158 virtual const char *getWorkingDirectory() = 0;
159
160 /**
161 * Gets the user home directory.
162 **/
163 virtual std::string getUserDirectory() = 0;
164
165 /**
166 * Gets the APPDATA directory. On Windows, this is the folder
167 * in the %APPDATA% enviroment variable. On Linux, this is the
168 * user home folder.
169 **/
170 virtual std::string getAppdataDirectory() = 0;
171
172 /**
173 * Gets the full path of the save folder.
174 **/
175 virtual const char *getSaveDirectory() = 0;
176
177 /**
178 * Gets the full path to the directory containing the game source.
179 * For example if the game source is C:\Games\mygame.love, this will return
180 * C:\Games.
181 **/
182 virtual std::string getSourceBaseDirectory() const = 0;
183
184 /**
185 * Gets the real directory path containing the file.
186 **/
187 virtual std::string getRealDirectory(const char *filename) const = 0;
188
189 /**
190 * Gets information about the item at the specified filepath. Returns false
191 * if nothing exists at the path.
192 **/
193 virtual bool getInfo(const char *filepath, Info &info) const = 0;
194
195 /**
196 * Creates a directory. Write dir must be set.
197 * @param dir The directory to create.
198 **/
199 virtual bool createDirectory(const char *dir) = 0;
200
201 /**
202 * Removes a file (or directory).
203 * @param file The file or directory to remove.
204 **/
205 virtual bool remove(const char *file) = 0;
206
207 /**
208 * Reads data from a file.
209 * @param filename The name of the file to read from.
210 * @param size The size in bytes of the data to read.
211 **/
212 virtual FileData *read(const char *filename, int64 size = File::ALL) const = 0;
213
214 /**
215 * Write data to a file.
216 * @param filename The name of the file to write to.
217 * @param data The data to write.
218 * @param size The size in bytes of the data to write.
219 **/
220 virtual void write(const char *filename, const void *data, int64 size) const = 0;
221
222 /**
223 * Append data to a file, creating it if it doesn't exist.
224 * @param filename The name of the file to write to.
225 * @param data The data to append.
226 * @param size The size in bytes of the data to append.
227 **/
228 virtual void append(const char *filename, const void *data, int64 size) const = 0;
229
230 /**
231 * This "native" method returns a table of all
232 * files in a given directory.
233 **/
234 virtual void getDirectoryItems(const char *dir, std::vector<std::string> &items) = 0;
235
236 /**
237 * Enable or disable symbolic link support in love.filesystem.
238 **/
239 virtual void setSymlinksEnabled(bool enable) = 0;
240
241 /**
242 * Gets whether symbolic link support is enabled.
243 **/
244 virtual bool areSymlinksEnabled() const = 0;
245
246 // Require path accessors
247 // Not const because it's R/W
248 virtual std::vector<std::string> &getRequirePath() = 0;
249 virtual std::vector<std::string> &getCRequirePath() = 0;
250
251 /**
252 * Allows a full (OS-dependent) path to be used with Filesystem::mount.
253 **/
254 virtual void allowMountingForPath(const std::string &path) = 0;
255
256 /**
257 * Gets whether the given full (OS-dependent) path is a directory.
258 **/
259 virtual bool isRealDirectory(const std::string &path) const;
260
261 /**
262 * Gets the full platform-dependent path to the executable.
263 **/
264 virtual std::string getExecutablePath() const;
265
266 static bool getConstant(const char *in, FileType &out);
267 static bool getConstant(FileType in, const char *&out);
268 static std::vector<std::string> getConstants(FileType);
269
270private:
271
272 // Should we save external or internal for Android
273 bool useExternal;
274
275 static StringMap<FileType, FILETYPE_MAX_ENUM>::Entry fileTypeEntries[];
276 static StringMap<FileType, FILETYPE_MAX_ENUM> fileTypes;
277
278}; // Filesystem
279
280} // filesystem
281} // love
282
283#endif // LOVE_FILESYSTEM_FILESYSTEM_H
284