summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/fs/fs.cpp8
-rw-r--r--src/common/fs/fs_types.h2
-rw-r--r--src/core/file_sys/vfs_real.cpp44
-rw-r--r--src/core/file_sys/vfs_real.h11
4 files changed, 41 insertions, 24 deletions
diff --git a/src/common/fs/fs.cpp b/src/common/fs/fs.cpp
index 6d66c926d..1baf6d746 100644
--- a/src/common/fs/fs.cpp
+++ b/src/common/fs/fs.cpp
@@ -436,7 +436,7 @@ void IterateDirEntries(const std::filesystem::path& path, const DirEntryCallable
436 436
437 if (True(filter & DirEntryFilter::File) && 437 if (True(filter & DirEntryFilter::File) &&
438 entry.status().type() == fs::file_type::regular) { 438 entry.status().type() == fs::file_type::regular) {
439 if (!callback(entry.path())) { 439 if (!callback(entry)) {
440 callback_error = true; 440 callback_error = true;
441 break; 441 break;
442 } 442 }
@@ -444,7 +444,7 @@ void IterateDirEntries(const std::filesystem::path& path, const DirEntryCallable
444 444
445 if (True(filter & DirEntryFilter::Directory) && 445 if (True(filter & DirEntryFilter::Directory) &&
446 entry.status().type() == fs::file_type::directory) { 446 entry.status().type() == fs::file_type::directory) {
447 if (!callback(entry.path())) { 447 if (!callback(entry)) {
448 callback_error = true; 448 callback_error = true;
449 break; 449 break;
450 } 450 }
@@ -493,7 +493,7 @@ void IterateDirEntriesRecursively(const std::filesystem::path& path,
493 493
494 if (True(filter & DirEntryFilter::File) && 494 if (True(filter & DirEntryFilter::File) &&
495 entry.status().type() == fs::file_type::regular) { 495 entry.status().type() == fs::file_type::regular) {
496 if (!callback(entry.path())) { 496 if (!callback(entry)) {
497 callback_error = true; 497 callback_error = true;
498 break; 498 break;
499 } 499 }
@@ -501,7 +501,7 @@ void IterateDirEntriesRecursively(const std::filesystem::path& path,
501 501
502 if (True(filter & DirEntryFilter::Directory) && 502 if (True(filter & DirEntryFilter::Directory) &&
503 entry.status().type() == fs::file_type::directory) { 503 entry.status().type() == fs::file_type::directory) {
504 if (!callback(entry.path())) { 504 if (!callback(entry)) {
505 callback_error = true; 505 callback_error = true;
506 break; 506 break;
507 } 507 }
diff --git a/src/common/fs/fs_types.h b/src/common/fs/fs_types.h
index 5a4090c19..900f85d24 100644
--- a/src/common/fs/fs_types.h
+++ b/src/common/fs/fs_types.h
@@ -66,6 +66,6 @@ DECLARE_ENUM_FLAG_OPERATORS(DirEntryFilter);
66 * @returns A boolean value. 66 * @returns A boolean value.
67 * Return true to indicate whether the callback is successful, false otherwise. 67 * Return true to indicate whether the callback is successful, false otherwise.
68 */ 68 */
69using DirEntryCallable = std::function<bool(const std::filesystem::path& path)>; 69using DirEntryCallable = std::function<bool(const std::filesystem::directory_entry& entry)>;
70 70
71} // namespace Common::FS 71} // namespace Common::FS
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
index 7a15d8438..a8fdc8f3e 100644
--- a/src/core/file_sys/vfs_real.cpp
+++ b/src/core/file_sys/vfs_real.cpp
@@ -10,6 +10,7 @@
10#include "common/fs/fs.h" 10#include "common/fs/fs.h"
11#include "common/fs/path_util.h" 11#include "common/fs/path_util.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13#include "core/file_sys/vfs.h"
13#include "core/file_sys/vfs_real.h" 14#include "core/file_sys/vfs_real.h"
14 15
15// For FileTimeStampRaw 16// For FileTimeStampRaw
@@ -72,7 +73,8 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const {
72 return VfsEntryType::File; 73 return VfsEntryType::File;
73} 74}
74 75
75VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) { 76VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::optional<u64> size,
77 Mode perms) {
76 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); 78 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
77 79
78 if (auto it = cache.find(path); it != cache.end()) { 80 if (auto it = cache.find(path); it != cache.end()) {
@@ -81,20 +83,24 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
81 } 83 }
82 } 84 }
83 85
84 if (!FS::Exists(path) || !FS::IsFile(path)) { 86 if (!size && !FS::IsFile(path)) {
85 return nullptr; 87 return nullptr;
86 } 88 }
87 89
88 auto reference = std::make_unique<FileReference>(); 90 auto reference = std::make_unique<FileReference>();
89 this->InsertReferenceIntoList(*reference); 91 this->InsertReferenceIntoList(*reference);
90 92
91 auto file = 93 auto file = std::shared_ptr<RealVfsFile>(
92 std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, std::move(reference), path, perms)); 94 new RealVfsFile(*this, std::move(reference), path, perms, size));
93 cache[path] = file; 95 cache[path] = file;
94 96
95 return file; 97 return file;
96} 98}
97 99
100VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
101 return OpenFileFromEntry(path_, {}, perms);
102}
103
98VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) { 104VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, Mode perms) {
99 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault); 105 const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
100 cache.erase(path); 106 cache.erase(path);
@@ -243,10 +249,10 @@ void RealVfsFilesystem::RemoveReferenceFromList(FileReference& reference) {
243} 249}
244 250
245RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_, 251RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_,
246 const std::string& path_, Mode perms_) 252 const std::string& path_, Mode perms_, std::optional<u64> size_)
247 : base(base_), reference(std::move(reference_)), path(path_), 253 : base(base_), reference(std::move(reference_)), path(path_),
248 parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponents(path_)), 254 parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponents(path_)),
249 perms(perms_) {} 255 size(size_), perms(perms_) {}
250 256
251RealVfsFile::~RealVfsFile() { 257RealVfsFile::~RealVfsFile() {
252 base.DropReference(std::move(reference)); 258 base.DropReference(std::move(reference));
@@ -257,8 +263,10 @@ std::string RealVfsFile::GetName() const {
257} 263}
258 264
259std::size_t RealVfsFile::GetSize() const { 265std::size_t RealVfsFile::GetSize() const {
260 base.RefreshReference(path, perms, *reference); 266 if (size) {
261 return reference->file ? reference->file->GetSize() : 0; 267 return *size;
268 }
269 return FS::GetSize(path);
262} 270}
263 271
264bool RealVfsFile::Resize(std::size_t new_size) { 272bool RealVfsFile::Resize(std::size_t new_size) {
@@ -309,10 +317,11 @@ std::vector<VirtualFile> RealVfsDirectory::IterateEntries<RealVfsFile, VfsFile>(
309 317
310 std::vector<VirtualFile> out; 318 std::vector<VirtualFile> out;
311 319
312 const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) { 320 const FS::DirEntryCallable callback = [this,
313 const auto full_path_string = FS::PathToUTF8String(full_path); 321 &out](const std::filesystem::directory_entry& entry) {
322 const auto full_path_string = FS::PathToUTF8String(entry.path());
314 323
315 out.emplace_back(base.OpenFile(full_path_string, perms)); 324 out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), perms));
316 325
317 return true; 326 return true;
318 }; 327 };
@@ -330,8 +339,9 @@ std::vector<VirtualDir> RealVfsDirectory::IterateEntries<RealVfsDirectory, VfsDi
330 339
331 std::vector<VirtualDir> out; 340 std::vector<VirtualDir> out;
332 341
333 const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) { 342 const FS::DirEntryCallable callback = [this,
334 const auto full_path_string = FS::PathToUTF8String(full_path); 343 &out](const std::filesystem::directory_entry& entry) {
344 const auto full_path_string = FS::PathToUTF8String(entry.path());
335 345
336 out.emplace_back(base.OpenDirectory(full_path_string, perms)); 346 out.emplace_back(base.OpenDirectory(full_path_string, perms));
337 347
@@ -483,12 +493,10 @@ std::map<std::string, VfsEntryType, std::less<>> RealVfsDirectory::GetEntries()
483 493
484 std::map<std::string, VfsEntryType, std::less<>> out; 494 std::map<std::string, VfsEntryType, std::less<>> out;
485 495
486 const FS::DirEntryCallable callback = [&out](const std::filesystem::path& full_path) { 496 const FS::DirEntryCallable callback = [&out](const std::filesystem::directory_entry& entry) {
487 const auto filename = FS::PathToUTF8String(full_path.filename()); 497 const auto filename = FS::PathToUTF8String(entry.path().filename());
488
489 out.insert_or_assign(filename, 498 out.insert_or_assign(filename,
490 FS::IsDir(full_path) ? VfsEntryType::Directory : VfsEntryType::File); 499 entry.is_directory() ? VfsEntryType::Directory : VfsEntryType::File);
491
492 return true; 500 return true;
493 }; 501 };
494 502
diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h
index d8c900e33..67f4c4422 100644
--- a/src/core/file_sys/vfs_real.h
+++ b/src/core/file_sys/vfs_real.h
@@ -4,6 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include <map> 6#include <map>
7#include <optional>
7#include <string_view> 8#include <string_view>
8#include "common/intrusive_list.h" 9#include "common/intrusive_list.h"
9#include "core/file_sys/mode.h" 10#include "core/file_sys/mode.h"
@@ -20,6 +21,8 @@ struct FileReference : public Common::IntrusiveListBaseNode<FileReference> {
20}; 21};
21 22
22class RealVfsFile; 23class RealVfsFile;
24class RealVfsDirectory;
25
23class RealVfsFilesystem : public VfsFilesystem { 26class RealVfsFilesystem : public VfsFilesystem {
24public: 27public:
25 RealVfsFilesystem(); 28 RealVfsFilesystem();
@@ -56,6 +59,11 @@ private:
56private: 59private:
57 void InsertReferenceIntoList(FileReference& reference); 60 void InsertReferenceIntoList(FileReference& reference);
58 void RemoveReferenceFromList(FileReference& reference); 61 void RemoveReferenceFromList(FileReference& reference);
62
63private:
64 friend class RealVfsDirectory;
65 VirtualFile OpenFileFromEntry(std::string_view path, std::optional<u64> size,
66 Mode perms = Mode::Read);
59}; 67};
60 68
61// An implementation of VfsFile that represents a file on the user's computer. 69// An implementation of VfsFile that represents a file on the user's computer.
@@ -78,13 +86,14 @@ public:
78 86
79private: 87private:
80 RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference, 88 RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
81 const std::string& path, Mode perms = Mode::Read); 89 const std::string& path, Mode perms = Mode::Read, std::optional<u64> size = {});
82 90
83 RealVfsFilesystem& base; 91 RealVfsFilesystem& base;
84 std::unique_ptr<FileReference> reference; 92 std::unique_ptr<FileReference> reference;
85 std::string path; 93 std::string path;
86 std::string parent_path; 94 std::string parent_path;
87 std::vector<std::string> path_components; 95 std::vector<std::string> path_components;
96 std::optional<u64> size;
88 Mode perms; 97 Mode perms;
89}; 98};
90 99