summaryrefslogtreecommitdiff
path: root/src/core/file_sys/vfs.cpp
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-07-06 10:51:32 -0400
committerGravatar bunnei2018-07-06 10:51:32 -0400
commit77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2 (patch)
tree38ef6451732c5eecb0efdd198f3db4d33848453c /src/core/file_sys/vfs.cpp
parentMerge pull request #629 from Subv/depth_test (diff)
downloadyuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.gz
yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.xz
yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.zip
Virtual Filesystem (#597)
* Add VfsFile and VfsDirectory classes * Finish abstract Vfs classes * Implement RealVfsFile (computer fs backend) * Finish RealVfsFile and RealVfsDirectory * Finished OffsetVfsFile * More changes * Fix import paths * Major refactor * Remove double const * Use experimental/filesystem or filesystem depending on compiler * Port partition_filesystem * More changes * More Overhaul * FSP_SRV fixes * Fixes and testing * Try to get filesystem to compile * Filesystem on linux * Remove std::filesystem and document/test * Compile fixes * Missing include * Bug fixes * Fixes * Rename v_file and v_dir * clang-format fix * Rename NGLOG_* to LOG_* * Most review changes * Fix TODO * Guess 'main' to be Directory by filename
Diffstat (limited to 'src/core/file_sys/vfs.cpp')
-rw-r--r--src/core/file_sys/vfs.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp
new file mode 100644
index 000000000..c99071d6a
--- /dev/null
+++ b/src/core/file_sys/vfs.cpp
@@ -0,0 +1,187 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <numeric>
7#include "common/file_util.h"
8#include "core/file_sys/vfs.h"
9
10namespace FileSys {
11
12VfsFile::~VfsFile() = default;
13
14std::string VfsFile::GetExtension() const {
15 return FileUtil::GetExtensionFromFilename(GetName());
16}
17
18VfsDirectory::~VfsDirectory() = default;
19
20boost::optional<u8> VfsFile::ReadByte(size_t offset) const {
21 u8 out{};
22 size_t size = Read(&out, 1, offset);
23 if (size == 1)
24 return out;
25
26 return boost::none;
27}
28
29std::vector<u8> VfsFile::ReadBytes(size_t size, size_t offset) const {
30 std::vector<u8> out(size);
31 size_t read_size = Read(out.data(), size, offset);
32 out.resize(read_size);
33 return out;
34}
35
36std::vector<u8> VfsFile::ReadAllBytes() const {
37 return ReadBytes(GetSize());
38}
39
40bool VfsFile::WriteByte(u8 data, size_t offset) {
41 return Write(&data, 1, offset) == 1;
42}
43
44size_t VfsFile::WriteBytes(std::vector<u8> data, size_t offset) {
45 return Write(data.data(), data.size(), offset);
46}
47
48std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(const std::string& path) const {
49 auto vec = FileUtil::SplitPathComponents(path);
50 vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
51 vec.end());
52 if (vec.empty())
53 return nullptr;
54 if (vec.size() == 1)
55 return GetFile(vec[0]);
56 auto dir = GetSubdirectory(vec[0]);
57 for (size_t i = 1; i < vec.size() - 1; ++i) {
58 if (dir == nullptr)
59 return nullptr;
60 dir = dir->GetSubdirectory(vec[i]);
61 }
62 if (dir == nullptr)
63 return nullptr;
64 return dir->GetFile(vec.back());
65}
66
67std::shared_ptr<VfsFile> VfsDirectory::GetFileAbsolute(const std::string& path) const {
68 if (IsRoot())
69 return GetFileRelative(path);
70
71 return GetParentDirectory()->GetFileAbsolute(path);
72}
73
74std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryRelative(const std::string& path) const {
75 auto vec = FileUtil::SplitPathComponents(path);
76 vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
77 vec.end());
78 if (vec.empty())
79 // return std::shared_ptr<VfsDirectory>(this);
80 return nullptr;
81 auto dir = GetSubdirectory(vec[0]);
82 for (size_t i = 1; i < vec.size(); ++i) {
83 dir = dir->GetSubdirectory(vec[i]);
84 }
85 return dir;
86}
87
88std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryAbsolute(const std::string& path) const {
89 if (IsRoot())
90 return GetDirectoryRelative(path);
91
92 return GetParentDirectory()->GetDirectoryAbsolute(path);
93}
94
95std::shared_ptr<VfsFile> VfsDirectory::GetFile(const std::string& name) const {
96 const auto& files = GetFiles();
97 const auto iter = std::find_if(files.begin(), files.end(),
98 [&name](const auto& file1) { return name == file1->GetName(); });
99 return iter == files.end() ? nullptr : *iter;
100}
101
102std::shared_ptr<VfsDirectory> VfsDirectory::GetSubdirectory(const std::string& name) const {
103 const auto& subs = GetSubdirectories();
104 const auto iter = std::find_if(subs.begin(), subs.end(),
105 [&name](const auto& file1) { return name == file1->GetName(); });
106 return iter == subs.end() ? nullptr : *iter;
107}
108
109bool VfsDirectory::IsRoot() const {
110 return GetParentDirectory() == nullptr;
111}
112
113size_t VfsDirectory::GetSize() const {
114 const auto& files = GetFiles();
115 const auto file_total =
116 std::accumulate(files.begin(), files.end(), 0ull,
117 [](const auto& f1, const auto& f2) { return f1 + f2->GetSize(); });
118
119 const auto& sub_dir = GetSubdirectories();
120 const auto subdir_total =
121 std::accumulate(sub_dir.begin(), sub_dir.end(), 0ull,
122 [](const auto& f1, const auto& f2) { return f1 + f2->GetSize(); });
123
124 return file_total + subdir_total;
125}
126
127bool VfsDirectory::DeleteSubdirectoryRecursive(const std::string& name) {
128 auto dir = GetSubdirectory(name);
129 if (dir == nullptr)
130 return false;
131
132 bool success = true;
133 for (const auto& file : dir->GetFiles()) {
134 if (!DeleteFile(file->GetName()))
135 success = false;
136 }
137
138 for (const auto& sdir : dir->GetSubdirectories()) {
139 if (!dir->DeleteSubdirectoryRecursive(sdir->GetName()))
140 success = false;
141 }
142
143 return success;
144}
145
146bool VfsDirectory::Copy(const std::string& src, const std::string& dest) {
147 const auto f1 = GetFile(src);
148 auto f2 = CreateFile(dest);
149 if (f1 == nullptr || f2 == nullptr)
150 return false;
151
152 if (!f2->Resize(f1->GetSize())) {
153 DeleteFile(dest);
154 return false;
155 }
156
157 return f2->WriteBytes(f1->ReadAllBytes()) == f1->GetSize();
158}
159
160bool ReadOnlyVfsDirectory::IsWritable() const {
161 return false;
162}
163
164bool ReadOnlyVfsDirectory::IsReadable() const {
165 return true;
166}
167
168std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateSubdirectory(const std::string& name) {
169 return nullptr;
170}
171
172std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFile(const std::string& name) {
173 return nullptr;
174}
175
176bool ReadOnlyVfsDirectory::DeleteSubdirectory(const std::string& name) {
177 return false;
178}
179
180bool ReadOnlyVfsDirectory::DeleteFile(const std::string& name) {
181 return false;
182}
183
184bool ReadOnlyVfsDirectory::Rename(const std::string& name) {
185 return false;
186}
187} // namespace FileSys