diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/file_sys/vfs_real.cpp | 80 |
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 | ||
| 73 | VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { | 73 | VirtualFile 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_ | |||
| 116 | VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { | 118 | VirtualFile 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 | ||
| 143 | bool RealVfsFilesystem::DeleteFile(std::string_view path_) { | 146 | bool 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 | ||
| 215 | bool RealVfsFilesystem::DeleteDirectory(std::string_view path_) { | 225 | bool 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 | ||
| 262 | std::size_t RealVfsFile::Read(u8* data, std::size_t length, std::size_t offset) const { | 278 | std::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 | ||
| 269 | std::size_t RealVfsFile::Write(const u8* data, std::size_t length, std::size_t offset) { | 285 | std::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); |