From a2fb1a04d502ae4d9c79769aa96c094e0d0258b7 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 18 Jun 2018 11:37:39 -0400 Subject: [PATCH] Finish RealVfsFile and RealVfsDirectory --- src/core/file_sys/vfs.cpp | 10 ++-- src/core/file_sys/vfs_real.cpp | 91 +++++++++++++++++++++++++++++++++- src/core/file_sys/vfs_real.h | 10 ++-- 3 files changed, 103 insertions(+), 8 deletions(-) diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp index c0b394c33b..4b956f1fa9 100644 --- a/src/core/file_sys/vfs.cpp +++ b/src/core/file_sys/vfs.cpp @@ -35,23 +35,25 @@ VfsDirectory::operator bool() { std::shared_ptr VfsDirectory::GetFile(const std::string& name) { auto files = GetFiles(); auto iter = std::find_if(files.begin(), files.end(), - [&name](auto file1) { return name == file1.GetName(); }); + [&name](auto file1) { return name == file1->GetName(); }); return iter == files.end() ? nullptr : std::move(*iter); } std::shared_ptr VfsDirectory::GetSubdirectory(const std::string& name) { auto subs = GetSubdirectories(); auto iter = std::find_if(subs.begin(), subs.end(), - [&name](auto file1) { return name == file1.GetName(); }); + [&name](auto file1) { return name == file1->GetName(); }); return iter == subs.end() ? nullptr : std::move(*iter); } u64 VfsDirectory::GetSize() { auto files = GetFiles(); - auto file_total = std::accumulate(files.begin(), files.end(), 0); + auto file_total = std::accumulate(files.begin(), files.end(), 0ull, + [](auto f1, auto f2) { return f1 + f2->GetSize(); }); auto sub_dir = GetSubdirectories(); - auto subdir_total = std::accumulate(sub_dir.begin(), sub_dir.end(), 0); + auto subdir_total = std::accumulate(sub_dir.begin(), sub_dir.end(), 0ull, + [](auto f1, auto f2) { return f1 + f2->GetSize(); }); return file_total + subdir_total; } diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 3c30af618d..1a703d3848 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/common_paths.h" +#include "common/logging/log.h" #include "core/file_sys/vfs_real.h" namespace FileSys { @@ -38,7 +40,7 @@ bool RealVfsFile::Resize(u64 new_size) { std::shared_ptr RealVfsFile::GetContainingDirectory() { std::string part_path, name, extention; Common::SplitPath(path, &part_path, &name, &extention); - return std::make_unique(part_path); + return std::make_shared(part_path, mode.c_str()); } bool RealVfsFile::IsWritable() { @@ -69,4 +71,91 @@ bool RealVfsFile::Rename(const std::string& name) { return out; } +RealVfsDirectory::RealVfsDirectory(const std::string& path, const char openmode[]) + : path(path[path.size() - 1] == DIR_SEP_CHR ? path.substr(0, path.size() - 1) : path) { + FileUtil::FSTEntry entry; + if (0 != FileUtil::ScanDirectoryTree(path, entry)) + NGLOG_CRITICAL(Service_FS, "Failure to initialize file."); + for (FileUtil::FSTEntry child : entry.children) { + if (child.isDirectory) + subdirectories.emplace_back( + std::make_shared(child.physicalName, mode.c_str())); + else + files.emplace_back(std::make_shared(child.physicalName, mode.c_str())); + } +} + +bool RealVfsDirectory::IsReady() { + return FileUtil::IsDirectory(path); +} + +bool RealVfsDirectory::IsGood() { + return FileUtil::IsDirectory(path); +} + +void RealVfsDirectory::ResetState() {} + +std::vector> RealVfsDirectory::GetFiles() { + return std::vector>(files); +} + +std::vector> RealVfsDirectory::GetSubdirectories() { + return std::vector>(subdirectories); +} + +bool RealVfsDirectory::IsWritable() { + return mode.find('w') != std::string::npos; +} + +bool RealVfsDirectory::IsReadable() { + return mode.find('r') != std::string::npos; +} + +bool RealVfsDirectory::IsRoot() { + return path.empty() || (path.size() == 2 && path[1] == ':'); +} + +std::string RealVfsDirectory::GetName() { + size_t last = path.rfind(DIR_SEP_CHR); + return path.substr(last + 1); +} + +std::shared_ptr RealVfsDirectory::GetParentDirectory() { + size_t last = path.rfind(DIR_SEP_CHR); + if (last == path.size() - 1) + last = path.rfind(DIR_SEP_CHR, path.size() - 2); + + if (last == std::string::npos) + return nullptr; + + return std::make_shared(path.substr(0, last), mode.c_str()); +} + +std::shared_ptr RealVfsDirectory::CreateSubdirectory(const std::string& name) { + FileUtil::CreateDir(path + DIR_SEP + name); + subdirectories.emplace_back( + std::make_shared(path + DIR_SEP + name, mode.c_str())); + return subdirectories[subdirectories.size() - 1]; +} + +std::shared_ptr RealVfsDirectory::CreateFile(const std::string& name) { + FileUtil::CreateEmptyFile(path + DIR_SEP + name); + files.emplace_back(std::make_shared(path + DIR_SEP + name, mode.c_str())); + return files[files.size() - 1]; +} + +bool RealVfsDirectory::DeleteSubdirectory(const std::string& name) { + return FileUtil::DeleteDirRecursively(path + DIR_SEP + name); +} + +bool RealVfsDirectory::DeleteFile(const std::string& name) { + return FileUtil::Delete(path + DIR_SEP + name); +} + +bool RealVfsDirectory::Rename(const std::string& name) { + std::string part, o_name, extention; + Common::SplitPath(name, &part, &o_name, &extention); + return FileUtil::Rename(path, part + DIR_SEP + name); +} + } // namespace FileSys diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h index d34f1d7a17..4e52352b4b 100644 --- a/src/core/file_sys/vfs_real.h +++ b/src/core/file_sys/vfs_real.h @@ -31,7 +31,7 @@ private: }; struct RealVfsDirectory : public VfsDirectory { - explicit RealVfsDirectory(const std::string& name); + explicit RealVfsDirectory(const std::string& path, const char openmode[]); bool IsReady() override; bool IsGood() override; @@ -42,14 +42,18 @@ struct RealVfsDirectory : public VfsDirectory { bool IsReadable() override; bool IsRoot() override; std::string GetName() override; - u64 GetSize() override; std::shared_ptr GetParentDirectory() override; std::shared_ptr CreateSubdirectory(const std::string& name) override; std::shared_ptr CreateFile(const std::string& name) override; bool DeleteSubdirectory(const std::string& name) override; bool DeleteFile(const std::string& name) override; bool Rename(const std::string& name) override; - bool Copy(const std::string& src, const std::string& dest) override; + +private: + std::string path; + std::string mode; + std::vector> files; + std::vector> subdirectories; }; } // namespace FileSys