Pioneer
Loading...
Searching...
No Matches
FileSystem.h
Go to the documentation of this file.
1// Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3
4#ifndef _FILESYSTEM_H
5#define _FILESYSTEM_H
6
7#include "ByteRange.h"
8#include "DateTime.h"
9#include "RefCounted.h"
10#include "StringRange.h"
11#include <deque>
12#include <memory>
13#include <string>
14#include <vector>
15
16/*
17 * Functionality:
18 * - Overlay multiple file sources (directories and archives)
19 * in a single virtual file system.
20 * - Enumerate entries from that combined virtual file system.
21 * - Read a file from the virtual file system.
22 * - Determine the path of the application's installed files.
23 * - Determine a sensible path for application configuration files.
24 */
25
26namespace FileSystem {
27
28 class FileSource;
29 class FileData;
30 class FileSourceFS;
31 class FileSourceUnion;
32
33 void Init();
34 void Uninit();
35
36 extern FileSourceUnion gameDataFiles;
38
39 std::string GetUserDir();
40 std::string GetDataDir();
41
45 std::string SanitiseFileName(const std::string &a);
46
49 std::string JoinPath(const std::string &a, const std::string &b);
50
55 std::string JoinPathBelow(const std::string &base, const std::string &path);
56
59 std::string GetRelativePath(const std::string &base, const std::string &path);
60
66 std::string NormalisePath(const std::string &path);
67
68 enum class CopyMode {
69 OVERWRITE, // overwrite all files in target with files from source
70 ONLY_MISSING_IN_TARGET // only copy files that aren't present in target
71 };
72
75 bool CopyDir(FileSource &sourceFS, std::string sourceDir, FileSourceFS &targetFS, std::string targetDir, CopyMode copymode = CopyMode::OVERWRITE);
76
77 class FileInfo {
78 friend class FileSource;
79
80 public:
82 m_source(0),
83 m_dirLen(0),
84 m_type(FT_NON_EXISTENT) {}
85
86 enum FileType {
87 // note: order here affects sort-order of FileInfo
92 };
93
94 enum FileType GetType() const { return m_type; }
95 bool Exists() const { return (m_type != FT_NON_EXISTENT); }
96 bool IsDir() const { return (m_type == FT_DIR); }
97 bool IsFile() const { return (m_type == FT_FILE); }
98 bool IsSpecial() const { return (m_type == FT_SPECIAL); }
99
100 // modification time specified in *local* time (not UTC)
101 // (specified in local time because we want it to be easy to display)
102 Time::DateTime GetModificationTime() const { return m_modTime; }
103
104 const std::string &GetPath() const { return m_path; }
105 std::string GetName() const { return m_path.substr(m_dirLen); }
106 std::string GetDir() const { return m_path.substr(0, m_dirLen); }
107 std::string GetAbsoluteDir() const;
108 std::string GetAbsolutePath() const;
109
110 const FileSource &GetSource() const { return *m_source; }
111
113
114 friend bool operator==(const FileInfo &a, const FileInfo &b)
115 {
116 return (a.m_source == b.m_source && a.m_type == b.m_type && a.m_path == b.m_path);
117 }
118 friend bool operator!=(const FileInfo &a, const FileInfo &b)
119 {
120 return (a.m_source != b.m_source || a.m_type != b.m_type || a.m_path != b.m_path);
121 }
122 friend bool operator<(const FileInfo &a, const FileInfo &b)
123 {
124 int c = a.m_path.compare(b.m_path);
125 if (c != 0) {
126 return (c < 0);
127 }
128 if (a.m_type != b.m_type) {
129 return (a.m_type < b.m_type);
130 }
131 return (a.m_source < b.m_source);
132 }
133 friend bool operator<=(const FileInfo &a, const FileInfo &b)
134 {
135 int c = a.m_path.compare(b.m_path);
136 if (c != 0) {
137 return (c < 0);
138 }
139 if (a.m_type != b.m_type) {
140 return (a.m_type < b.m_type);
141 }
142 return (a.m_source <= b.m_source);
143 }
144 friend bool operator>(const FileInfo &a, const FileInfo &b) { return (b < a); }
145 friend bool operator>=(const FileInfo &a, const FileInfo &b) { return (b <= a); }
146
147 private:
148 // use FileSource::MakeFileInfo to create your FileInfos
149 FileInfo(FileSource *source, const std::string &path, FileType type, Time::DateTime modTime);
150
151 FileSource *m_source;
152 std::string m_path;
153 Time::DateTime m_modTime;
154 int m_dirLen;
155 FileType m_type;
156 };
157
158 class FileData : public RefCounted {
159 public:
160 virtual ~FileData() {}
161
162 const FileInfo &GetInfo() const { return m_info; }
163 size_t GetSize() const { return m_size; }
164 const char *GetData() const
165 {
166 assert(m_info.IsFile());
167 return m_data;
168 }
171 std::string_view AsStringView() const { return std::string_view(m_data, m_size); }
172
173 protected:
174 FileData(const FileInfo &info, size_t size, char *data) :
175 m_info(info),
176 m_data(data),
177 m_size(size) {}
178 FileData(const FileInfo &info) :
179 m_info(info),
180 m_data(0),
181 m_size(0) {}
182
184 char *m_data;
185 size_t m_size;
186 };
187
188 class FileDataMalloc : public FileData {
189 public:
190 FileDataMalloc(const FileInfo &info, size_t size) :
191 FileData(info, size, static_cast<char *>(std::malloc(size))) {}
192 FileDataMalloc(const FileInfo &info, size_t size, char *data) :
193 FileData(info, size, data) {}
194 virtual ~FileDataMalloc() { std::free(m_data); }
195 };
196
198 public:
199 explicit FileSource(const std::string &root, bool trusted = false) :
200 m_root(root),
201 m_trusted(trusted) {}
202 virtual ~FileSource() {}
203
204 const std::string &GetRoot() const { return m_root; }
205
206 virtual FileInfo Lookup(const std::string &path) = 0;
207 virtual RefCountedPtr<FileData> ReadFile(const std::string &path) = 0;
208 virtual bool ReadDirectory(const std::string &path, std::vector<FileInfo> &output) = 0;
209
210 bool IsTrusted() const { return m_trusted; }
211
212 protected:
213 FileInfo MakeFileInfo(const std::string &path, FileInfo::FileType entryType, Time::DateTime modTime);
214 FileInfo MakeFileInfo(const std::string &path, FileInfo::FileType entryType);
215
216 private:
217 std::string m_root;
218 bool m_trusted;
219 };
220
221 class FileSourceFS : public FileSource {
222 public:
223 explicit FileSourceFS(const std::string &root, bool trusted = false);
225
226 virtual FileInfo Lookup(const std::string &path);
227 virtual RefCountedPtr<FileData> ReadFile(const std::string &path);
228 virtual bool ReadDirectory(const std::string &path, std::vector<FileInfo> &output);
229
230 bool MakeDirectory(const std::string &path);
231
233 WRITE_TEXT = 1
234 };
235
236 // similar to fopen(path, "rb")
237 FILE *OpenReadStream(const std::string &path);
238 // similar to fopen(path, "wb")
239 FILE *OpenWriteStream(const std::string &path, int flags = 0);
240 };
241
243 public:
246
247 // add and remove sources
248 // note: order is important. The array of sources works like a PATH array:
249 // that is, earlier sources take priority over later sources
253
254 virtual FileInfo Lookup(const std::string &path);
255 std::vector<FileInfo> LookupAll(const std::string &path);
256 virtual RefCountedPtr<FileData> ReadFile(const std::string &path);
257 virtual bool ReadDirectory(const std::string &path, std::vector<FileInfo> &output);
258
259 private:
260 std::vector<FileSource *> m_sources;
261 };
262
264 public:
265 enum Flags {
269 Recurse = 8
270 };
271
272 explicit FileEnumerator(FileSource &fs, int flags = 0);
273 explicit FileEnumerator(FileSource &fs, const std::string &path, int flags = 0);
275
276 void AddSearchRoot(const std::string &path);
277
278 bool Finished() const { return m_queue.empty(); }
279 void Next();
280 const FileInfo &Current() const { return m_queue.front(); }
281
282 private:
283 void ExpandDirQueue();
284 void QueueDirectoryContents(const FileInfo &info);
285
286 FileSource *m_source;
287 std::deque<FileInfo> m_queue;
288 std::deque<FileInfo> m_dirQueue;
289 int m_flags;
290 };
291
292} // namespace FileSystem
293
294inline std::string FileSystem::FileInfo::GetAbsoluteDir() const
295{
296 return JoinPath(m_source->GetRoot(), GetDir());
297}
298
300{
301 return JoinPath(m_source->GetRoot(), GetPath());
302}
303
305{
306 return m_source->ReadFile(m_path);
307}
308
309#endif
Definition FileSystem.h:188
FileDataMalloc(const FileInfo &info, size_t size)
Definition FileSystem.h:190
FileDataMalloc(const FileInfo &info, size_t size, char *data)
Definition FileSystem.h:192
virtual ~FileDataMalloc()
Definition FileSystem.h:194
Definition FileSystem.h:158
ByteRange AsByteRange() const
Definition FileSystem.h:170
FileData(const FileInfo &info, size_t size, char *data)
Definition FileSystem.h:174
StringRange AsStringRange() const
Definition FileSystem.h:169
size_t m_size
Definition FileSystem.h:185
FileData(const FileInfo &info)
Definition FileSystem.h:178
size_t GetSize() const
Definition FileSystem.h:163
char * m_data
Definition FileSystem.h:184
virtual ~FileData()
Definition FileSystem.h:160
const char * GetData() const
Definition FileSystem.h:164
const FileInfo & GetInfo() const
Definition FileSystem.h:162
FileInfo m_info
Definition FileSystem.h:183
std::string_view AsStringView() const
Definition FileSystem.h:171
Definition FileSystem.h:263
Flags
Definition FileSystem.h:265
@ Recurse
Definition FileSystem.h:269
@ ExcludeFiles
Definition FileSystem.h:268
@ IncludeSpecials
Definition FileSystem.h:267
@ IncludeDirs
Definition FileSystem.h:266
const FileInfo & Current() const
Definition FileSystem.h:280
void Next()
Definition FileSystem.cpp:385
~FileEnumerator()
Definition FileSystem.cpp:374
void AddSearchRoot(const std::string &path)
Definition FileSystem.cpp:376
bool Finished() const
Definition FileSystem.h:278
Definition FileSystem.h:77
std::string GetName() const
Definition FileSystem.h:105
friend bool operator<=(const FileInfo &a, const FileInfo &b)
Definition FileSystem.h:133
friend bool operator!=(const FileInfo &a, const FileInfo &b)
Definition FileSystem.h:118
FileInfo()
Definition FileSystem.h:81
bool IsFile() const
Definition FileSystem.h:97
enum FileType GetType() const
Definition FileSystem.h:94
std::string GetDir() const
Definition FileSystem.h:106
std::string GetAbsoluteDir() const
Definition FileSystem.h:294
Time::DateTime GetModificationTime() const
Definition FileSystem.h:102
std::string GetAbsolutePath() const
Definition FileSystem.h:299
bool Exists() const
Definition FileSystem.h:95
FileType
Definition FileSystem.h:86
@ FT_SPECIAL
Definition FileSystem.h:91
@ FT_NON_EXISTENT
Definition FileSystem.h:90
@ FT_FILE
Definition FileSystem.h:89
@ FT_DIR
Definition FileSystem.h:88
RefCountedPtr< FileData > Read() const
Definition FileSystem.h:304
friend bool operator<(const FileInfo &a, const FileInfo &b)
Definition FileSystem.h:122
friend bool operator>(const FileInfo &a, const FileInfo &b)
Definition FileSystem.h:144
friend bool operator>=(const FileInfo &a, const FileInfo &b)
Definition FileSystem.h:145
bool IsSpecial() const
Definition FileSystem.h:98
const std::string & GetPath() const
Definition FileSystem.h:104
bool IsDir() const
Definition FileSystem.h:96
friend bool operator==(const FileInfo &a, const FileInfo &b)
Definition FileSystem.h:114
const FileSource & GetSource() const
Definition FileSystem.h:110
Definition FileSystem.h:221
virtual bool ReadDirectory(const std::string &path, std::vector< FileInfo > &output)
Definition FileSystemPosix.cpp:205
FILE * OpenReadStream(const std::string &path)
Definition FileSystemPosix.cpp:274
virtual FileInfo Lookup(const std::string &path)
Definition FileSystemPosix.cpp:162
virtual RefCountedPtr< FileData > ReadFile(const std::string &path)
Definition FileSystemPosix.cpp:170
WriteFlags
Definition FileSystem.h:232
@ WRITE_TEXT
Definition FileSystem.h:233
bool MakeDirectory(const std::string &path)
Definition FileSystemPosix.cpp:268
~FileSourceFS()
Definition FileSystemPosix.cpp:129
FILE * OpenWriteStream(const std::string &path, int flags=0)
Definition FileSystemPosix.cpp:280
Definition FileSystem.h:242
virtual bool ReadDirectory(const std::string &path, std::vector< FileInfo > &output)
Definition FileSystem.cpp:327
virtual RefCountedPtr< FileData > ReadFile(const std::string &path)
Definition FileSystem.cpp:277
void AppendSource(FileSource *fs)
Definition FileSystem.cpp:239
void PrependSource(FileSource *fs)
Definition FileSystem.cpp:232
void RemoveSource(FileSource *fs)
Definition FileSystem.cpp:246
std::vector< FileInfo > LookupAll(const std::string &path)
Definition FileSystem.cpp:265
virtual FileInfo Lookup(const std::string &path)
Definition FileSystem.cpp:252
FileSourceUnion()
Definition FileSystem.cpp:228
~FileSourceUnion()
Definition FileSystem.cpp:230
Definition FileSystem.h:197
FileInfo MakeFileInfo(const std::string &path, FileInfo::FileType entryType, Time::DateTime modTime)
Definition FileSystem.cpp:218
virtual bool ReadDirectory(const std::string &path, std::vector< FileInfo > &output)=0
virtual FileInfo Lookup(const std::string &path)=0
FileSource(const std::string &root, bool trusted=false)
Definition FileSystem.h:199
const std::string & GetRoot() const
Definition FileSystem.h:204
virtual RefCountedPtr< FileData > ReadFile(const std::string &path)=0
virtual ~FileSource()
Definition FileSystem.h:202
bool IsTrusted() const
Definition FileSystem.h:210
Definition RefCounted.h:36
Definition RefCounted.h:11
Definition DateTime.h:84
Definition CityOnPlanet.h:27
std::string JoinPathBelow(const std::string &base, const std::string &path)
Definition FileSystem.cpp:102
void Init()
Definition FileSystem.cpp:188
std::string GetUserDir()
Definition FileSystemPosix.cpp:114
void Uninit()
Definition FileSystem.cpp:194
std::string SanitiseFileName(const std::string &a)
Definition FileSystem.cpp:21
CopyMode
Definition FileSystem.h:68
std::string GetDataDir()
Definition FileSystemPosix.cpp:120
std::string NormalisePath(const std::string &path)
Definition FileSystem.cpp:94
bool CopyDir(FileSource &sourceFS, std::string sourceDir, FileSourceFS &targetFS, std::string targetDir, FileSystem::CopyMode copymode)
Definition FileSystem.cpp:148
FileSourceUnion gameDataFiles
Definition FileSystem.cpp:17
std::string JoinPath(const std::string &a, const std::string &b)
Definition FileSystem.cpp:46
std::string GetRelativePath(const std::string &base, const std::string &path)
Definition FileSystem.cpp:126
FileSourceFS userFiles(GetUserDir())
Definition FileSystem.h:37
Definition ByteRange.h:12
Definition StringRange.h:11