From fc44261dd1304c7dd1f38999a13ef9734c23b69a Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 19 Mar 2018 22:57:34 -0500 Subject: FS: Support the file Append open mode. --- src/core/file_sys/disk_filesystem.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/core/file_sys/disk_filesystem.cpp') diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp index 22b17ba04..9d456e0bf 100644 --- a/src/core/file_sys/disk_filesystem.cpp +++ b/src/core/file_sys/disk_filesystem.cpp @@ -17,10 +17,30 @@ std::string Disk_FileSystem::GetName() const { ResultVal> Disk_FileSystem::OpenFile(const std::string& path, Mode mode) const { - ASSERT_MSG(mode == Mode::Read || mode == Mode::Write, "Other file modes are not supported"); + + std::string mode_str = ""; + u32 mode_flags = static_cast(mode); + + // Calculate the correct open mode for the file. + if ((mode_flags & static_cast(Mode::Read)) && + (mode_flags & static_cast(Mode::Write))) { + if (mode_flags & static_cast(Mode::Append)) + mode_str = "a+"; + else + mode_str = "r+"; + } else { + if (mode_flags & static_cast(Mode::Read)) + mode_str = "r"; + else if (mode_flags & static_cast(Mode::Append)) + mode_str = "a"; + else if (mode_flags & static_cast(Mode::Write)) + mode_str = "w"; + } + + mode_str += "b"; std::string full_path = base_directory + path; - auto file = std::make_shared(full_path, mode == Mode::Read ? "rb" : "wb"); + auto file = std::make_shared(full_path, mode_str.c_str()); if (!file->IsOpen()) { return ERROR_PATH_NOT_FOUND; -- cgit v1.2.3 From a9ba2c2000d9f2e4c6018aa6fc1e754eca82f72c Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 19 Mar 2018 22:58:55 -0500 Subject: FS: Updated the Directory Entry structure to match the Switch. --- src/core/file_sys/disk_filesystem.cpp | 48 ++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'src/core/file_sys/disk_filesystem.cpp') diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp index 9d456e0bf..e2092b9df 100644 --- a/src/core/file_sys/disk_filesystem.cpp +++ b/src/core/file_sys/disk_filesystem.cpp @@ -153,14 +153,50 @@ bool Disk_Storage::SetSize(const u64 size) const { return false; } -u32 Disk_Directory::Read(const u32 count, Entry* entries) { - LOG_WARNING(Service_FS, "(STUBBED) called"); - return 0; +Disk_Directory::Disk_Directory(const std::string& path) : directory() { + unsigned size = FileUtil::ScanDirectoryTree(path, directory); + directory.size = size; + directory.isDirectory = true; + children_iterator = directory.children.begin(); +} + +u64 Disk_Directory::Read(const u64 count, Entry* entries) { + u64 entries_read = 0; + + while (entries_read < count && children_iterator != directory.children.cend()) { + const FileUtil::FSTEntry& file = *children_iterator; + const std::string& filename = file.virtualName; + Entry& entry = entries[entries_read]; + + LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size, + file.isDirectory); + + // TODO(Link Mauve): use a proper conversion to UTF-16. + for (size_t j = 0; j < FILENAME_LENGTH; ++j) { + entry.filename[j] = filename[j]; + if (!filename[j]) + break; + } + + if (file.isDirectory) { + entry.file_size = 0; + entry.type = EntryType::Directory; + } else { + entry.file_size = file.size; + entry.type = EntryType::File; + } + + ++entries_read; + ++children_iterator; + } + return entries_read; } -bool Disk_Directory::Close() const { - LOG_WARNING(Service_FS, "(STUBBED) called"); - return true; +u64 Disk_Directory::GetEntryCount() const { + // We convert the children iterator into a const_iterator to allow template argument deduction + // in std::distance. + std::vector::const_iterator current = children_iterator; + return std::distance(current, directory.children.end()); } } // namespace FileSys -- cgit v1.2.3 From e1d7b9fc2c8780552b40e8415104b4205efe2de7 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 19 Mar 2018 22:59:38 -0500 Subject: FS: Implement DiskFileSystem::GetEntryType for existing files/directories. --- src/core/file_sys/disk_filesystem.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/core/file_sys/disk_filesystem.cpp') diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp index e2092b9df..e02b20faf 100644 --- a/src/core/file_sys/disk_filesystem.cpp +++ b/src/core/file_sys/disk_filesystem.cpp @@ -123,8 +123,10 @@ ResultVal Disk_FileSystem::GetEntryType(const std::string& p return ERROR_PATH_NOT_FOUND; } - // TODO(Subv): Find out the EntryType values - UNIMPLEMENTED_MSG("Unimplemented GetEntryType"); + if (FileUtil::IsDirectory(full_path)) + return MakeResult(EntryType::Directory); + + return MakeResult(EntryType::File); } ResultVal Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const { -- cgit v1.2.3 From 6d90d99d12c6a1e7ec27831d93052a30c0e689b5 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 19 Mar 2018 23:00:37 -0500 Subject: FS: Implement DiskFileSystem's OpenDirectory interface. --- src/core/file_sys/disk_filesystem.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/core/file_sys/disk_filesystem.cpp') diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp index e02b20faf..f620b7961 100644 --- a/src/core/file_sys/disk_filesystem.cpp +++ b/src/core/file_sys/disk_filesystem.cpp @@ -108,8 +108,17 @@ ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& de } ResultVal> Disk_FileSystem::OpenDirectory( - const Path& path) const { - return MakeResult>(std::make_unique()); + const std::string& path) const { + + std::string full_path = base_directory + path; + + if (!FileUtil::IsDirectory(full_path)) { + // TODO(Subv): Find the correct error code for this. + return ResultCode(-1); + } + + auto directory = std::make_unique(full_path); + return MakeResult>(std::move(directory)); } u64 Disk_FileSystem::GetFreeSpaceSize() const { -- cgit v1.2.3 From eff3f60b73343365ad65638f55591965df6f7e25 Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 21 Mar 2018 09:36:26 -0500 Subject: FS: Implemented IFileSystem::CreateDirectory. --- src/core/file_sys/disk_filesystem.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/core/file_sys/disk_filesystem.cpp') diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp index f620b7961..9383bf856 100644 --- a/src/core/file_sys/disk_filesystem.cpp +++ b/src/core/file_sys/disk_filesystem.cpp @@ -18,7 +18,7 @@ std::string Disk_FileSystem::GetName() const { ResultVal> Disk_FileSystem::OpenFile(const std::string& path, Mode mode) const { - std::string mode_str = ""; + std::string mode_str; u32 mode_flags = static_cast(mode); // Calculate the correct open mode for the file. @@ -95,8 +95,15 @@ ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const return ResultCode(-1); } -ResultCode Disk_FileSystem::CreateDirectory(const Path& path) const { - LOG_WARNING(Service_FS, "(STUBBED) called"); +ResultCode Disk_FileSystem::CreateDirectory(const std::string& path) const { + // TODO(Subv): Perform path validation to prevent escaping the emulator sandbox. + std::string full_path = base_directory + path; + + if (FileUtil::CreateDir(full_path)) { + return RESULT_SUCCESS; + } + + LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating %s", full_path.c_str()); // TODO(wwylele): Use correct error code return ResultCode(-1); } -- cgit v1.2.3 From 4c06d55a81304d0e658adf441d8bdb90a32ba228 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 23 Mar 2018 11:09:09 -0500 Subject: FS: Move the file open mode calculation to a separate function. --- src/core/file_sys/disk_filesystem.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src/core/file_sys/disk_filesystem.cpp') diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp index 9383bf856..3a4b45721 100644 --- a/src/core/file_sys/disk_filesystem.cpp +++ b/src/core/file_sys/disk_filesystem.cpp @@ -11,13 +11,7 @@ namespace FileSys { -std::string Disk_FileSystem::GetName() const { - return "Disk"; -} - -ResultVal> Disk_FileSystem::OpenFile(const std::string& path, - Mode mode) const { - +static std::string ModeFlagsToString(Mode mode) { std::string mode_str; u32 mode_flags = static_cast(mode); @@ -39,6 +33,19 @@ ResultVal> Disk_FileSystem::OpenFile(const std:: mode_str += "b"; + return mode_str; +} + +std::string Disk_FileSystem::GetName() const { + return "Disk"; +} + +ResultVal> Disk_FileSystem::OpenFile(const std::string& path, + Mode mode) const { + + // Calculate the correct open mode for the file. + std::string mode_str = ModeFlagsToString(mode); + std::string full_path = base_directory + path; auto file = std::make_shared(full_path, mode_str.c_str()); -- cgit v1.2.3