summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/file_sys/vfs_real.cpp80
1 files changed, 48 insertions, 32 deletions
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
index 1dbf632c1..488687ba9 100644
--- a/src/core/file_sys/vfs_real.cpp
+++ b/src/core/file_sys/vfs_real.cpp
@@ -72,8 +72,10 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const {
72 72
73VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { 73VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
74 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); 74 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
75 if (cache.find(path) != cache.end()) { 75
76 auto weak = cache[path]; 76 if (const auto weak_iter = cache.find(path); weak_iter != cache.cend()) {
77 const auto& weak = weak_iter->second;
78
77 if (!weak.expired()) { 79 if (!weak.expired()) {
78 return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, weak.lock(), path, perms)); 80 return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, weak.lock(), path, perms));
79 } 81 }
@@ -84,7 +86,7 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
84 } 86 }
85 87
86 auto backing = std::make_shared<FS::IOFile>(path, ModeFlagsToString(perms).c_str()); 88 auto backing = std::make_shared<FS::IOFile>(path, ModeFlagsToString(perms).c_str());
87 cache[path] = backing; 89 cache.insert_or_assign(path, backing);
88 90
89 // Cannot use make_shared as RealVfsFile constructor is private 91 // Cannot use make_shared as RealVfsFile constructor is private
90 return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, backing, path, perms)); 92 return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, backing, path, perms));
@@ -116,11 +118,12 @@ VirtualFile RealVfsFilesystem::CopyFile(std::string_view old_path_, std::string_
116VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { 118VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) {
117 const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault); 119 const auto old_path = FS::SanitizePath(old_path_, FS::DirectorySeparator::PlatformDefault);
118 const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault); 120 const auto new_path = FS::SanitizePath(new_path_, FS::DirectorySeparator::PlatformDefault);
121 const auto cached_file_iter = cache.find(old_path);
119 122
120 if (cache.find(old_path) != cache.end()) { 123 if (cached_file_iter != cache.cend()) {
121 auto file = cache[old_path].lock(); 124 auto file = cached_file_iter->second.lock();
122 125
123 if (!cache[old_path].expired()) { 126 if (!cached_file_iter->second.expired()) {
124 file->Close(); 127 file->Close();
125 } 128 }
126 129
@@ -131,7 +134,7 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_
131 134
132 cache.erase(old_path); 135 cache.erase(old_path);
133 file->Open(new_path, "r+b"); 136 file->Open(new_path, "r+b");
134 cache[new_path] = file; 137 cache.insert_or_assign(new_path, std::move(file));
135 } else { 138 } else {
136 UNREACHABLE(); 139 UNREACHABLE();
137 return nullptr; 140 return nullptr;
@@ -142,12 +145,15 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_
142 145
143bool RealVfsFilesystem::DeleteFile(std::string_view path_) { 146bool RealVfsFilesystem::DeleteFile(std::string_view path_) {
144 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); 147 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
145 if (cache.find(path) != cache.end()) { 148 const auto cached_iter = cache.find(path);
146 if (!cache[path].expired()) { 149
147 cache[path].lock()->Close(); 150 if (cached_iter != cache.cend()) {
151 if (!cached_iter->second.expired()) {
152 cached_iter->second.lock()->Close();
148 } 153 }
149 cache.erase(path); 154 cache.erase(path);
150 } 155 }
156
151 return FS::Delete(path); 157 return FS::Delete(path);
152} 158}
153 159
@@ -192,21 +198,25 @@ VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_,
192 } 198 }
193 199
194 for (auto& kv : cache) { 200 for (auto& kv : cache) {
195 // Path in cache starts with old_path 201 // If the path in the cache doesn't start with old_path, then bail on this file.
196 if (kv.first.rfind(old_path, 0) == 0) { 202 if (kv.first.rfind(old_path, 0) != 0) {
197 const auto file_old_path = 203 continue;
198 FS::SanitizePath(kv.first, FS::DirectorySeparator::PlatformDefault); 204 }
199 const auto file_new_path = 205
200 FS::SanitizePath(new_path + DIR_SEP + kv.first.substr(old_path.size()), 206 const auto file_old_path =
201 FS::DirectorySeparator::PlatformDefault); 207 FS::SanitizePath(kv.first, FS::DirectorySeparator::PlatformDefault);
202 auto cached = cache[file_old_path]; 208 auto file_new_path = FS::SanitizePath(new_path + DIR_SEP + kv.first.substr(old_path.size()),
203 if (!cached.expired()) { 209 FS::DirectorySeparator::PlatformDefault);
204 auto file = cached.lock(); 210 const auto& cached = cache[file_old_path];
205 file->Open(file_new_path, "r+b"); 211
206 cache.erase(file_old_path); 212 if (cached.expired()) {
207 cache[file_new_path] = file; 213 continue;
208 }
209 } 214 }
215
216 auto file = cached.lock();
217 file->Open(file_new_path, "r+b");
218 cache.erase(file_old_path);
219 cache.insert_or_assign(std::move(file_new_path), std::move(file));
210 } 220 }
211 221
212 return OpenDirectory(new_path, Mode::ReadWrite); 222 return OpenDirectory(new_path, Mode::ReadWrite);
@@ -214,15 +224,21 @@ VirtualDir RealVfsFilesystem::MoveDirectory(std::string_view old_path_,
214 224
215bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) { 225bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) {
216 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); 226 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
227
217 for (auto& kv : cache) { 228 for (auto& kv : cache) {
218 // Path in cache starts with old_path 229 // If the path in the cache doesn't start with path, then bail on this file.
219 if (kv.first.rfind(path, 0) == 0) { 230 if (kv.first.rfind(path, 0) != 0) {
220 if (!cache[kv.first].expired()) { 231 continue;
221 cache[kv.first].lock()->Close();
222 }
223 cache.erase(kv.first);
224 } 232 }
233
234 const auto& entry = cache[kv.first];
235 if (!entry.expired()) {
236 entry.lock()->Close();
237 }
238
239 cache.erase(kv.first);
225 } 240 }
241
226 return FS::DeleteDirRecursively(path); 242 return FS::DeleteDirRecursively(path);
227} 243}
228 244
@@ -260,14 +276,14 @@ bool RealVfsFile::IsReadable() const {
260} 276}
261 277
262std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const { 278std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const {
263 if (!backing->Seek(offset, SEEK_SET)) { 279 if (!backing->Seek(static_cast<s64>(offset), SEEK_SET)) {
264 return 0; 280 return 0;
265 } 281 }
266 return backing->ReadBytes(data, length); 282 return backing->ReadBytes(data, length);
267} 283}
268 284
269std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) { 285std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) {
270 if (!backing->Seek(offset, SEEK_SET)) { 286 if (!backing->Seek(static_cast<s64>(offset), SEEK_SET)) {
271 return 0; 287 return 0;
272 } 288 }
273 return backing->WriteBytes(data, length); 289 return backing->WriteBytes(data, length);