Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/FileSystems/MetaFileSystem.h
5654 views
1
// Copyright (c) 2012- PPSSPP Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18
#pragma once
19
20
#include <string>
21
#include <string_view>
22
#include <vector>
23
#include <mutex>
24
#include <memory>
25
26
#include "Core/FileSystems/FileSystem.h"
27
28
class MetaFileSystem : public IHandleAllocator, public IFileSystem {
29
private:
30
s32 current;
31
struct MountPoint {
32
std::string prefix;
33
std::shared_ptr<IFileSystem> system;
34
35
bool operator == (const MountPoint &other) const {
36
return prefix == other.prefix && system == other.system;
37
}
38
};
39
40
// The order of this vector is meaningful - lookups are always a linear search from the start.
41
std::vector<MountPoint> fileSystems;
42
43
typedef std::map<int, std::string> currentDir_t;
44
currentDir_t currentDir;
45
46
std::string startingDirectory;
47
mutable std::recursive_mutex lock; // must be recursive. TODO: fix that
48
49
// Assumes the lock is held
50
void Reset() {
51
// This used to be 6, probably an attempt to replicate PSP handles.
52
// However, that's an artifact of using psplink anyway...
53
current = 1;
54
startingDirectory.clear();
55
}
56
57
public:
58
MetaFileSystem() {
59
Reset();
60
}
61
62
// Will replace the existing mount if already exists.
63
void Mount(std::string_view prefix, std::shared_ptr<IFileSystem> system);
64
65
void UnmountAll();
66
void Unmount(std::string_view prefix);
67
68
// Would like to make this const, but...
69
std::vector<MountPoint> &GetMounts() {
70
return fileSystems;
71
}
72
73
// The pointer returned from these are for temporary usage only. Do not store.
74
IFileSystem *GetSystem(std::string_view prefix);
75
IFileSystem *GetSystemFromFilename(std::string_view filename);
76
IFileSystem *GetHandleOwner(u32 handle) const;
77
FileSystemFlags FlagsFromFilename(std::string_view filename) {
78
IFileSystem *sys = GetSystemFromFilename(filename);
79
return sys ? sys->Flags() : FileSystemFlags::NONE;
80
}
81
82
void ThreadEnded(int threadID);
83
void Shutdown();
84
85
u32 GetNewHandle() override {
86
u32 res = current++;
87
if (current < 0) {
88
// Some code assumes it'll never become 0.
89
current = 1;
90
}
91
return res;
92
}
93
void FreeHandle(u32 handle) override {}
94
95
void DoState(PointerWrap &p) override;
96
97
int MapFilePath(std::string_view inpath, std::string *outpath, MountPoint **system);
98
99
inline int MapFilePath(std::string_view inpath, std::string *outpath, IFileSystem **system) {
100
MountPoint *mountPoint = nullptr;
101
int error = MapFilePath(inpath, outpath, &mountPoint);
102
if (error == 0) {
103
*system = mountPoint->system.get();
104
return error;
105
}
106
107
return error;
108
}
109
110
std::string NormalizePrefix(std::string_view prefix) const;
111
112
std::vector<PSPFileInfo> GetDirListing(const std::string &path, bool *exists = nullptr) override;
113
int OpenFile(std::string filename, FileAccess access, const char *devicename = nullptr) override;
114
void CloseFile(u32 handle) override;
115
size_t ReadFile(u32 handle, u8 *pointer, s64 size) override;
116
size_t ReadFile(u32 handle, u8 *pointer, s64 size, int &usec) override;
117
size_t WriteFile(u32 handle, const u8 *pointer, s64 size) override;
118
size_t WriteFile(u32 handle, const u8 *pointer, s64 size, int &usec) override;
119
size_t SeekFile(u32 handle, s32 position, FileMove type) override;
120
PSPFileInfo GetFileInfo(std::string filename) override;
121
PSPFileInfo GetFileInfoByHandle(u32 handle) override;
122
bool OwnsHandle(u32 handle) override { return false; }
123
inline size_t GetSeekPos(u32 handle) {
124
return SeekFile(handle, 0, FILEMOVE_CURRENT);
125
}
126
127
virtual int ChDir(const std::string &dir);
128
129
bool MkDir(const std::string &dirname) override;
130
bool RmDir(const std::string &dirname) override;
131
int RenameFile(const std::string &from, const std::string &to) override;
132
bool RemoveFile(const std::string &filename) override;
133
int Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) override;
134
PSPDevType DevType(u32 handle) override;
135
FileSystemFlags Flags() const override { return FileSystemFlags::NONE; }
136
u64 FreeDiskSpace(const std::string &path) override;
137
138
// Convenience helper - returns < 0 on failure.
139
int ReadEntireFile(const std::string &filename, std::vector<u8> &data, bool quiet = false);
140
141
void SetStartingDirectory(std::string_view dir) {
142
std::lock_guard<std::recursive_mutex> guard(lock);
143
startingDirectory = dir;
144
}
145
146
int64_t ComputeRecursiveDirectorySize(std::string_view dirPath);
147
148
bool ComputeRecursiveDirSizeIfFast(const std::string &path, int64_t *size) override;
149
150
void Describe(char *buf, size_t size) const override { snprintf(buf, size, "Meta"); }
151
152
private:
153
int64_t RecursiveSize(std::string_view dirPath);
154
};
155
156