1 /**
2  * Copyright (c) 2006-2019 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 
56 namespace love
57 {
58 namespace filesystem
59 {
60 
61 class Filesystem : public Module
62 {
63 public:
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.
getModuleType()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 
270 private:
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