summaryrefslogtreecommitdiff
path: root/src/core/file_sys/vfs.cpp
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-08-03 11:46:30 -0400
committerGravatar Zach Hilman2018-08-08 21:18:45 -0400
commit3bf488ce520a81811bf6e949e2153aabf4b713ea (patch)
tree1fc1ee9346bf0ccec8fdf5b3c07b53fd4efb7b8d /src/core/file_sys/vfs.cpp
parentfilesystem: Remove unnecessary if conditions (diff)
downloadyuzu-3bf488ce520a81811bf6e949e2153aabf4b713ea.tar.gz
yuzu-3bf488ce520a81811bf6e949e2153aabf4b713ea.tar.xz
yuzu-3bf488ce520a81811bf6e949e2153aabf4b713ea.zip
vfs: Add VfsFilesystem interface and default implementation
Diffstat (limited to 'src/core/file_sys/vfs.cpp')
-rw-r--r--src/core/file_sys/vfs.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp
index dae1c16ef..24e158962 100644
--- a/src/core/file_sys/vfs.cpp
+++ b/src/core/file_sys/vfs.cpp
@@ -4,12 +4,160 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <numeric> 6#include <numeric>
7#include <string>
8#include "common/common_paths.h"
7#include "common/file_util.h" 9#include "common/file_util.h"
8#include "common/logging/backend.h" 10#include "common/logging/backend.h"
9#include "core/file_sys/vfs.h" 11#include "core/file_sys/vfs.h"
10 12
11namespace FileSys { 13namespace FileSys {
12 14
15VfsFilesystem::VfsFilesystem(VirtualDir root_) : root(std::move(root_)) {}
16
17VfsFilesystem::~VfsFilesystem() = default;
18
19std::string VfsFilesystem::GetName() const {
20 return root->GetName();
21}
22
23bool VfsFilesystem::IsReadable() const {
24 return root->IsReadable();
25}
26
27bool VfsFilesystem::IsWritable() const {
28 return root->IsWritable();
29}
30
31VfsEntryType VfsFilesystem::GetEntryType(std::string_view path_) const {
32 const auto path = FileUtil::SanitizePath(path_);
33 if (root->GetFileRelative(path) != nullptr)
34 return VfsEntryType::File;
35 if (root->GetDirectoryRelative(path) != nullptr)
36 return VfsEntryType::Directory;
37
38 return VfsEntryType::None;
39}
40
41VirtualFile VfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
42 const auto path = FileUtil::SanitizePath(path_);
43 return root->GetFileRelative(path);
44}
45
46VirtualFile VfsFilesystem::CreateFile(std::string_view path_, Mode perms) {
47 const auto path = FileUtil::SanitizePath(path_);
48 return root->CreateFileRelative(path);
49}
50
51VirtualFile VfsFilesystem::CopyFile(std::string_view old_path_, std::string_view new_path_) {
52 const auto old_path = FileUtil::SanitizePath(old_path_);
53 const auto new_path = FileUtil::SanitizePath(new_path_);
54
55 // VfsDirectory impls are only required to implement copy across the current directory.
56 if (FileUtil::GetParentPath(old_path) == FileUtil::GetParentPath(new_path)) {
57 if (!root->Copy(FileUtil::GetFilename(old_path), FileUtil::GetFilename(new_path)))
58 return nullptr;
59 return OpenFile(new_path, Mode::ReadWrite);
60 }
61
62 // Do it using RawCopy. Non-default impls are encouraged to optimize this.
63 const auto old_file = OpenFile(old_path, Mode::Read);
64 if (old_file == nullptr)
65 return nullptr;
66 auto new_file = OpenFile(new_path, Mode::Read);
67 if (new_file != nullptr)
68 return nullptr;
69 new_file = CreateFile(new_path, Mode::Write);
70 if (new_file == nullptr)
71 return nullptr;
72 if (!VfsRawCopy(old_file, new_file))
73 return nullptr;
74 return new_file;
75}
76
77VirtualFile VfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) {
78 const auto old_path = FileUtil::SanitizePath(old_path_);
79 const auto new_path = FileUtil::SanitizePath(new_path_);
80
81 // Again, non-default impls are highly encouraged to provide a more optimized version of this.
82 auto out = CopyFile(old_path_, new_path_);
83 if (out == nullptr)
84 return nullptr;
85 if (DeleteFile(old_path))
86 return out;
87 return nullptr;
88}
89
90bool VfsFilesystem::DeleteFile(std::string_view path_) {
91 const auto path = FileUtil::SanitizePath(path_);
92 auto parent = OpenDirectory(FileUtil::GetParentPath(path), Mode::Write);
93 if (parent == nullptr)
94 return false;
95 return parent->DeleteFile(FileUtil::GetFilename(path));
96}
97
98VirtualDir VfsFilesystem::OpenDirectory(std::string_view path_, Mode perms) {
99 const auto path = FileUtil::SanitizePath(path_);
100 return root->GetDirectoryRelative(path);
101}
102
103VirtualDir VfsFilesystem::CreateDirectory(std::string_view path_, Mode perms) {
104 const auto path = FileUtil::SanitizePath(path_);
105 return root->CreateDirectoryRelative(path);
106}
107
108VirtualDir VfsFilesystem::CopyDirectory(std::string_view old_path_, std::string_view new_path_) {
109 const auto old_path = FileUtil::SanitizePath(old_path_);
110 const auto new_path = FileUtil::SanitizePath(new_path_);
111
112 // Non-default impls are highly encouraged to provide a more optimized version of this.
113 auto old_dir = OpenDirectory(old_path, Mode::Read);
114 if (old_dir == nullptr)
115 return nullptr;
116 auto new_dir = OpenDirectory(new_path, Mode::Read);
117 if (new_dir != nullptr)
118 return nullptr;
119 new_dir = CreateDirectory(new_path, Mode::Write);
120 if (new_dir == nullptr)
121 return nullptr;
122
123 for (const auto& file : old_dir->GetFiles()) {
124 const auto x =
125 CopyFile(old_path + DIR_SEP + file->GetName(), new_path + DIR_SEP + file->GetName());
126 if (x == nullptr)
127 return nullptr;
128 }
129
130 for (const auto& dir : old_dir->GetSubdirectories()) {
131 const auto x =
132 CopyDirectory(old_path + DIR_SEP + dir->GetName(), new_path + DIR_SEP + dir->GetName());
133 if (x == nullptr)
134 return nullptr;
135 }
136
137 return new_dir;
138}
139
140VirtualDir VfsFilesystem::MoveDirectory(std::string_view old_path_, std::string_view new_path_) {
141 const auto old_path = FileUtil::SanitizePath(old_path_);
142 const auto new_path = FileUtil::SanitizePath(new_path_);
143
144 // Non-default impls are highly encouraged to provide a more optimized version of this.
145 auto out = CopyDirectory(old_path_, new_path_);
146 if (out == nullptr)
147 return nullptr;
148 if (DeleteDirectory(old_path))
149 return out;
150 return nullptr;
151}
152
153bool VfsFilesystem::DeleteDirectory(std::string_view path_) {
154 const auto path = FileUtil::SanitizePath(path_);
155 auto parent = OpenDirectory(FileUtil::GetParentPath(path), Mode::Write);
156 if (parent == nullptr)
157 return false;
158 return parent->DeleteSubdirectoryRecursive(FileUtil::GetFilename(path));
159}
160
13VfsFile::~VfsFile() = default; 161VfsFile::~VfsFile() = default;
14 162
15std::string VfsFile::GetExtension() const { 163std::string VfsFile::GetExtension() const {