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// LOVE
22#include "Filesystem.h"
23#include "common/utf8.h"
24
25// Assume POSIX or Visual Studio.
26#include <sys/types.h>
27#include <sys/stat.h>
28
29#if defined(LOVE_MACOSX)
30#include "common/macosx.h"
31#elif defined(LOVE_IOS)
32#include "common/ios.h"
33#elif defined(LOVE_WINDOWS)
34#include <windows.h>
35#include "common/utf8.h"
36#elif defined(LOVE_LINUX)
37#include <unistd.h>
38#endif
39
40namespace love
41{
42namespace filesystem
43{
44
45love::Type Filesystem::type("filesystem", &Module::type);
46
47Filesystem::Filesystem()
48{
49}
50
51Filesystem::~Filesystem()
52{
53}
54
55void Filesystem::setAndroidSaveExternal(bool useExternal)
56{
57 this->useExternal = useExternal;
58}
59
60bool Filesystem::isAndroidSaveExternal() const
61{
62 return useExternal;
63}
64
65FileData *Filesystem::newFileData(const void *data, size_t size, const char *filename) const
66{
67 FileData *fd = new FileData(size, std::string(filename));
68 memcpy(fd->getData(), data, size);
69 return fd;
70}
71
72bool Filesystem::isRealDirectory(const std::string &path) const
73{
74#ifdef LOVE_WINDOWS
75 // make sure non-ASCII paths work.
76 std::wstring wpath = to_widestr(path);
77
78 struct _stat buf;
79 if (_wstat(wpath.c_str(), &buf) != 0)
80 return false;
81
82 return (buf.st_mode & _S_IFDIR) == _S_IFDIR;
83#else
84 // Assume POSIX support...
85 struct stat buf;
86 if (stat(path.c_str(), &buf) != 0)
87 return false;
88
89 return S_ISDIR(buf.st_mode) != 0;
90#endif
91}
92
93std::string Filesystem::getExecutablePath() const
94{
95#if defined(LOVE_MACOSX)
96 return love::macosx::getExecutablePath();
97#elif defined(LOVE_IOS)
98 return love::ios::getExecutablePath();
99#elif defined(LOVE_WINDOWS)
100
101 wchar_t buffer[MAX_PATH + 1] = {0};
102
103 if (GetModuleFileNameW(nullptr, buffer, MAX_PATH) == 0)
104 return "";
105
106 return to_utf8(buffer);
107
108#elif defined(LOVE_LINUX)
109
110 char buffer[2048] = {0};
111
112 ssize_t len = readlink("/proc/self/exe", buffer, 2048);
113 if (len <= 0)
114 return "";
115
116 return std::string(buffer, len);
117
118#else
119#error Missing implementation for Filesystem::getExecutablePath!
120#endif
121}
122
123bool Filesystem::getConstant(const char *in, FileType &out)
124{
125 return fileTypes.find(in, out);
126}
127
128bool Filesystem::getConstant(FileType in, const char *&out)
129{
130 return fileTypes.find(in, out);
131}
132
133std::vector<std::string> Filesystem::getConstants(FileType)
134{
135 return fileTypes.getNames();
136}
137
138StringMap<Filesystem::FileType, Filesystem::FILETYPE_MAX_ENUM>::Entry Filesystem::fileTypeEntries[] =
139{
140 { "file", FILETYPE_FILE },
141 { "directory", FILETYPE_DIRECTORY },
142 { "symlink", FILETYPE_SYMLINK },
143 { "other", FILETYPE_OTHER },
144};
145
146StringMap<Filesystem::FileType, Filesystem::FILETYPE_MAX_ENUM> Filesystem::fileTypes(Filesystem::fileTypeEntries, sizeof(Filesystem::fileTypeEntries));
147
148} // filesystem
149} // love
150