summaryrefslogtreecommitdiffstats
path: root/src/core/file_sys/vfs_real.cpp
diff options
context:
space:
mode:
authorZach Hilman <DarkLordZach@users.noreply.github.com>2018-07-19 03:07:11 +0200
committerbunnei <bunneidev@gmail.com>2018-07-19 03:07:11 +0200
commit29aff8d5ab46c8d0199aa4bfa7eeff5d4fa2d7ef (patch)
tree3202e2ce55ab6387a4ca366a509eccdd963434c3 /src/core/file_sys/vfs_real.cpp
parentMerge pull request #683 from DarkLordZach/touch (diff)
downloadyuzu-29aff8d5ab46c8d0199aa4bfa7eeff5d4fa2d7ef.tar
yuzu-29aff8d5ab46c8d0199aa4bfa7eeff5d4fa2d7ef.tar.gz
yuzu-29aff8d5ab46c8d0199aa4bfa7eeff5d4fa2d7ef.tar.bz2
yuzu-29aff8d5ab46c8d0199aa4bfa7eeff5d4fa2d7ef.tar.lz
yuzu-29aff8d5ab46c8d0199aa4bfa7eeff5d4fa2d7ef.tar.xz
yuzu-29aff8d5ab46c8d0199aa4bfa7eeff5d4fa2d7ef.tar.zst
yuzu-29aff8d5ab46c8d0199aa4bfa7eeff5d4fa2d7ef.zip
Diffstat (limited to 'src/core/file_sys/vfs_real.cpp')
-rw-r--r--src/core/file_sys/vfs_real.cpp177
1 files changed, 177 insertions, 0 deletions
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
new file mode 100644
index 000000000..22c858e0d
--- /dev/null
+++ b/src/core/file_sys/vfs_real.cpp
@@ -0,0 +1,177 @@
+// Copyright 2018 yuzu emulator team
+// 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 {
+
+static std::string PermissionsToCharArray(Mode perms) {
+ std::string out;
+ switch (perms) {
+ case Mode::Read:
+ out += "r";
+ break;
+ case Mode::Write:
+ out += "r+";
+ break;
+ case Mode::Append:
+ out += "a";
+ break;
+ }
+ return out + "b";
+}
+
+RealVfsFile::RealVfsFile(const std::string& path_, Mode perms_)
+ : backing(path_, PermissionsToCharArray(perms_).c_str()), path(path_),
+ parent_path(FileUtil::GetParentPath(path_)),
+ path_components(FileUtil::SplitPathComponents(path_)),
+ parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)),
+ perms(perms_) {}
+
+std::string RealVfsFile::GetName() const {
+ return path_components.back();
+}
+
+size_t RealVfsFile::GetSize() const {
+ return backing.GetSize();
+}
+
+bool RealVfsFile::Resize(size_t new_size) {
+ return backing.Resize(new_size);
+}
+
+std::shared_ptr<VfsDirectory> RealVfsFile::GetContainingDirectory() const {
+ return std::make_shared<RealVfsDirectory>(parent_path, perms);
+}
+
+bool RealVfsFile::IsWritable() const {
+ return perms == Mode::Append || perms == Mode::Write;
+}
+
+bool RealVfsFile::IsReadable() const {
+ return perms == Mode::Read || perms == Mode::Write;
+}
+
+size_t RealVfsFile::Read(u8* data, size_t length, size_t offset) const {
+ if (!backing.Seek(offset, SEEK_SET))
+ return 0;
+ return backing.ReadBytes(data, length);
+}
+
+size_t RealVfsFile::Write(const u8* data, size_t length, size_t offset) {
+ if (!backing.Seek(offset, SEEK_SET))
+ return 0;
+ return backing.WriteBytes(data, length);
+}
+
+bool RealVfsFile::Rename(const std::string& name) {
+ const auto out = FileUtil::Rename(GetName(), name);
+ path = parent_path + DIR_SEP + name;
+ path_components = parent_components;
+ path_components.push_back(name);
+ backing = FileUtil::IOFile(path, PermissionsToCharArray(perms).c_str());
+ return out;
+}
+
+bool RealVfsFile::Close() {
+ return backing.Close();
+}
+
+RealVfsDirectory::RealVfsDirectory(const std::string& path_, Mode perms_)
+ : path(FileUtil::RemoveTrailingSlash(path_)), parent_path(FileUtil::GetParentPath(path)),
+ path_components(FileUtil::SplitPathComponents(path)),
+ parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)),
+ perms(perms_) {
+ if (!FileUtil::Exists(path) && (perms == Mode::Write || perms == Mode::Append))
+ FileUtil::CreateDir(path);
+ unsigned size;
+ if (perms == Mode::Append)
+ return;
+
+ FileUtil::ForeachDirectoryEntry(
+ &size, path,
+ [this](unsigned* entries_out, const std::string& directory, const std::string& filename) {
+ std::string full_path = directory + DIR_SEP + filename;
+ if (FileUtil::IsDirectory(full_path))
+ subdirectories.emplace_back(std::make_shared<RealVfsDirectory>(full_path, perms));
+ else
+ files.emplace_back(std::make_shared<RealVfsFile>(full_path, perms));
+ return true;
+ });
+}
+
+std::vector<std::shared_ptr<VfsFile>> RealVfsDirectory::GetFiles() const {
+ return std::vector<std::shared_ptr<VfsFile>>(files);
+}
+
+std::vector<std::shared_ptr<VfsDirectory>> RealVfsDirectory::GetSubdirectories() const {
+ return std::vector<std::shared_ptr<VfsDirectory>>(subdirectories);
+}
+
+bool RealVfsDirectory::IsWritable() const {
+ return perms == Mode::Write || perms == Mode::Append;
+}
+
+bool RealVfsDirectory::IsReadable() const {
+ return perms == Mode::Read || perms == Mode::Write;
+}
+
+std::string RealVfsDirectory::GetName() const {
+ return path_components.back();
+}
+
+std::shared_ptr<VfsDirectory> RealVfsDirectory::GetParentDirectory() const {
+ if (path_components.size() <= 1)
+ return nullptr;
+
+ return std::make_shared<RealVfsDirectory>(parent_path, perms);
+}
+
+std::shared_ptr<VfsDirectory> RealVfsDirectory::CreateSubdirectory(const std::string& name) {
+ if (!FileUtil::CreateDir(path + DIR_SEP + name))
+ return nullptr;
+ subdirectories.emplace_back(std::make_shared<RealVfsDirectory>(path + DIR_SEP + name, perms));
+ return subdirectories.back();
+}
+
+std::shared_ptr<VfsFile> RealVfsDirectory::CreateFile(const std::string& name) {
+ if (!FileUtil::CreateEmptyFile(path + DIR_SEP + name))
+ return nullptr;
+ files.emplace_back(std::make_shared<RealVfsFile>(path + DIR_SEP + name, perms));
+ return files.back();
+}
+
+bool RealVfsDirectory::DeleteSubdirectory(const std::string& name) {
+ return FileUtil::DeleteDirRecursively(path + DIR_SEP + name);
+}
+
+bool RealVfsDirectory::DeleteFile(const std::string& name) {
+ auto file = GetFile(name);
+ if (file == nullptr)
+ return false;
+ files.erase(std::find(files.begin(), files.end(), file));
+ auto real_file = std::static_pointer_cast<RealVfsFile>(file);
+ real_file->Close();
+ return FileUtil::Delete(path + DIR_SEP + name);
+}
+
+bool RealVfsDirectory::Rename(const std::string& name) {
+ return FileUtil::Rename(path, parent_path + DIR_SEP + name);
+}
+
+bool RealVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
+ auto iter = std::find(files.begin(), files.end(), file);
+ if (iter == files.end())
+ return false;
+
+ files[iter - files.begin()] = files.back();
+ files.pop_back();
+
+ subdirectories.emplace_back(dir);
+
+ return true;
+}
+} // namespace FileSys