Major refactor
This commit is contained in:
@@ -750,7 +750,7 @@ size_t WriteStringToFile(bool text_file, const std::string& str, const char* fil
|
|||||||
size_t ReadFileToString(bool text_file, const char* filename, std::string& str) {
|
size_t ReadFileToString(bool text_file, const char* filename, std::string& str) {
|
||||||
IOFile file(filename, text_file ? "r" : "rb");
|
IOFile file(filename, text_file ? "r" : "rb");
|
||||||
|
|
||||||
if (!file)
|
if (!file.IsOpen())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
str.resize(static_cast<u32>(file.GetSize()));
|
str.resize(static_cast<u32>(file.GetSize()));
|
||||||
@@ -820,7 +820,6 @@ IOFile& IOFile::operator=(IOFile&& other) noexcept {
|
|||||||
|
|
||||||
void IOFile::Swap(IOFile& other) noexcept {
|
void IOFile::Swap(IOFile& other) noexcept {
|
||||||
std::swap(m_file, other.m_file);
|
std::swap(m_file, other.m_file);
|
||||||
std::swap(m_good, other.m_good);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::Open(const std::string& filename, const char openmode[], int flags) {
|
bool IOFile::Open(const std::string& filename, const char openmode[], int flags) {
|
||||||
@@ -837,16 +836,15 @@ bool IOFile::Open(const std::string& filename, const char openmode[], int flags)
|
|||||||
m_file = fopen(filename.c_str(), openmode);
|
m_file = fopen(filename.c_str(), openmode);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_good = IsOpen();
|
return IsOpen();
|
||||||
return m_good;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::Close() {
|
bool IOFile::Close() {
|
||||||
if (!IsOpen() || 0 != std::fclose(m_file))
|
if (!IsOpen() || 0 != std::fclose(m_file))
|
||||||
m_good = false;
|
return false;
|
||||||
|
|
||||||
m_file = nullptr;
|
m_file = nullptr;
|
||||||
return m_good;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 IOFile::GetSize() const {
|
u64 IOFile::GetSize() const {
|
||||||
@@ -856,11 +854,8 @@ u64 IOFile::GetSize() const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::Seek(s64 off, int origin) {
|
bool IOFile::Seek(s64 off, int origin) const {
|
||||||
if (!IsOpen() || 0 != fseeko(m_file, off, origin))
|
return IsOpen() && 0 == fseeko(m_file, off, origin);
|
||||||
m_good = false;
|
|
||||||
|
|
||||||
return m_good;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 IOFile::Tell() const {
|
u64 IOFile::Tell() const {
|
||||||
@@ -871,26 +866,20 @@ u64 IOFile::Tell() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::Flush() {
|
bool IOFile::Flush() {
|
||||||
if (!IsOpen() || 0 != std::fflush(m_file))
|
return IsOpen() && 0 == std::fflush(m_file);
|
||||||
m_good = false;
|
|
||||||
|
|
||||||
return m_good;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IOFile::Resize(u64 size) {
|
bool IOFile::Resize(u64 size) {
|
||||||
if (!IsOpen() || 0 !=
|
return IsOpen() && 0 ==
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// ector: _chsize sucks, not 64-bit safe
|
// ector: _chsize sucks, not 64-bit safe
|
||||||
// F|RES: changed to _chsize_s. i think it is 64-bit safe
|
// F|RES: changed to _chsize_s. i think it is 64-bit safe
|
||||||
_chsize_s(_fileno(m_file), size)
|
_chsize_s(_fileno(m_file), size)
|
||||||
#else
|
#else
|
||||||
// TODO: handle 64bit and growing
|
// TODO: handle 64bit and growing
|
||||||
ftruncate(fileno(m_file), size)
|
ftruncate(fileno(m_file), size)
|
||||||
#endif
|
#endif
|
||||||
)
|
;
|
||||||
m_good = false;
|
|
||||||
|
|
||||||
return m_good;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace FileUtil
|
} // namespace FileUtil
|
||||||
|
|||||||
@@ -172,41 +172,27 @@ public:
|
|||||||
bool Close();
|
bool Close();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t ReadArray(T* data, size_t length) {
|
size_t ReadArray(T* data, size_t length) const {
|
||||||
static_assert(std::is_trivially_copyable<T>(),
|
static_assert(std::is_trivially_copyable<T>(),
|
||||||
"Given array does not consist of trivially copyable objects");
|
"Given array does not consist of trivially copyable objects");
|
||||||
|
|
||||||
if (!IsOpen()) {
|
if (!IsOpen())
|
||||||
m_good = false;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
size_t items_read = std::fread(data, sizeof(T), length, m_file);
|
return std::fread(data, sizeof(T), length, m_file);
|
||||||
if (items_read != length)
|
|
||||||
m_good = false;
|
|
||||||
|
|
||||||
return items_read;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t WriteArray(const T* data, size_t length) {
|
size_t WriteArray(const T* data, size_t length) {
|
||||||
static_assert(std::is_trivially_copyable<T>(),
|
static_assert(std::is_trivially_copyable<T>(),
|
||||||
"Given array does not consist of trivially copyable objects");
|
"Given array does not consist of trivially copyable objects");
|
||||||
|
if (!IsOpen())
|
||||||
if (!IsOpen()) {
|
|
||||||
m_good = false;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
return std::fwrite(data, sizeof(T), length, m_file);
|
||||||
|
|
||||||
size_t items_written = std::fwrite(data, sizeof(T), length, m_file);
|
|
||||||
if (items_written != length)
|
|
||||||
m_good = false;
|
|
||||||
|
|
||||||
return items_written;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t ReadBytes(T* data, size_t length) {
|
size_t ReadBytes(T* data, size_t length) const {
|
||||||
static_assert(std::is_trivially_copyable<T>(), "T must be trivially copyable");
|
static_assert(std::is_trivially_copyable<T>(), "T must be trivially copyable");
|
||||||
return ReadArray(reinterpret_cast<char*>(data), length);
|
return ReadArray(reinterpret_cast<char*>(data), length);
|
||||||
}
|
}
|
||||||
@@ -227,19 +213,11 @@ public:
|
|||||||
return WriteArray(str.c_str(), str.length());
|
return WriteArray(str.c_str(), str.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsOpen() const {
|
bool IsOpen() const const {
|
||||||
return nullptr != m_file;
|
return nullptr != m_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_good is set to false when a read, write or other function fails
|
bool Seek(s64 off, int origin) const;
|
||||||
bool IsGood() const {
|
|
||||||
return m_good;
|
|
||||||
}
|
|
||||||
explicit operator bool() const {
|
|
||||||
return IsGood();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Seek(s64 off, int origin);
|
|
||||||
u64 Tell() const;
|
u64 Tell() const;
|
||||||
u64 GetSize() const;
|
u64 GetSize() const;
|
||||||
bool Resize(u64 size);
|
bool Resize(u64 size);
|
||||||
@@ -247,13 +225,11 @@ public:
|
|||||||
|
|
||||||
// clear error state
|
// clear error state
|
||||||
void Clear() {
|
void Clear() {
|
||||||
m_good = true;
|
|
||||||
std::clearerr(m_file);
|
std::clearerr(m_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::FILE* m_file = nullptr;
|
std::FILE* m_file = nullptr;
|
||||||
bool m_good = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FileUtil
|
} // namespace FileUtil
|
||||||
|
|||||||
@@ -2,72 +2,110 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
VfsFile::operator bool() {
|
VfsFile::~VfsFile() = default;
|
||||||
return IsGood();
|
|
||||||
|
VfsDirectory::~VfsDirectory() = default;
|
||||||
|
|
||||||
|
boost::optional<u8> VfsFile::ReadByte(size_t offset) const {
|
||||||
|
u8 out{};
|
||||||
|
size_t size = Read(&out, 1, offset);
|
||||||
|
if (size == 1)
|
||||||
|
return out;
|
||||||
|
|
||||||
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<u8> VfsFile::ReadByte(u64 offset) {
|
std::vector<u8> VfsFile::ReadBytes(size_t size, size_t offset) const {
|
||||||
auto vec = ReadBytes(offset, 1);
|
std::vector<u8> out(size);
|
||||||
if (vec.empty())
|
size_t read_size = Read(out.data(), size, offset);
|
||||||
return boost::none;
|
out.resize(read_size);
|
||||||
return vec[0];
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> VfsFile::ReadAllBytes() {
|
std::vector<u8> VfsFile::ReadAllBytes() const {
|
||||||
return ReadBytes(0, GetSize());
|
return ReadBytes(GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 VfsFile::ReplaceBytes(const std::vector<u8>& data) {
|
bool VfsFile::WriteByte(u8 data, size_t offset) {
|
||||||
if (!Resize(data.size()))
|
return 1 == Write(&data, 1, offset);
|
||||||
return 0;
|
|
||||||
return WriteBytes(data, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VfsDirectory::operator bool() {
|
size_t VfsFile::WriteBytes(std::vector<u8> data, size_t offset) {
|
||||||
return IsGood();
|
return Write(data.data(), data.size(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<VfsFile> VfsDirectory::GetFile(const std::string& name) {
|
std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(const std::filesystem::path& path) const {
|
||||||
auto files = GetFiles();
|
if (path.parent_path() == path.root_path())
|
||||||
auto iter = std::find_if(files.begin(), files.end(),
|
return GetFile(path.filename().string());
|
||||||
[&name](auto file1) { return name == file1->GetName(); });
|
|
||||||
return iter == files.end() ? nullptr : std::move(*iter);
|
auto parent = path.parent_path().string();
|
||||||
|
parent.replace(path.root_path().string().begin(), path.root_path().string().end(), "");
|
||||||
|
const auto index = parent.find_first_of('\\');
|
||||||
|
const auto first_dir = parent.substr(0, index), rest = parent.substr(index + 1);
|
||||||
|
const auto sub = GetSubdirectory(first_dir);
|
||||||
|
if (sub == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
return sub->GetFileRelative(path.root_path().string() + rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<VfsDirectory> VfsDirectory::GetSubdirectory(const std::string& name) {
|
std::shared_ptr<VfsFile> VfsDirectory::GetFileAbsolute(const std::filesystem::path& path) const {
|
||||||
auto subs = GetSubdirectories();
|
if (IsRoot())
|
||||||
auto iter = std::find_if(subs.begin(), subs.end(),
|
return GetFileRelative(path);
|
||||||
[&name](auto file1) { return name == file1->GetName(); });
|
|
||||||
|
return GetParentDirectory()->GetFileAbsolute(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsFile> VfsDirectory::GetFile(const std::string& name) const {
|
||||||
|
const auto& files = GetFiles();
|
||||||
|
const auto& iter = std::find_if(files.begin(), files.end(), [&name](const auto& file1) {
|
||||||
|
return name == file1->GetName();
|
||||||
|
});
|
||||||
|
return iter == files.end() ? nullptr : *iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsDirectory> VfsDirectory::GetSubdirectory(const std::string& name) const {
|
||||||
|
const auto& subs = GetSubdirectories();
|
||||||
|
const auto& iter = std::find_if(
|
||||||
|
subs.begin(), subs.end(), [&name](const auto& file1) { return name == file1->GetName(); });
|
||||||
return iter == subs.end() ? nullptr : std::move(*iter);
|
return iter == subs.end() ? nullptr : std::move(*iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 VfsDirectory::GetSize() {
|
bool VfsDirectory::IsRoot() const {
|
||||||
auto files = GetFiles();
|
return GetParentDirectory() == nullptr;
|
||||||
auto file_total = std::accumulate(files.begin(), files.end(), 0ull,
|
}
|
||||||
[](auto f1, auto f2) { return f1 + f2->GetSize(); });
|
|
||||||
|
|
||||||
auto sub_dir = GetSubdirectories();
|
size_t VfsDirectory::GetSize() const {
|
||||||
auto subdir_total = std::accumulate(sub_dir.begin(), sub_dir.end(), 0ull,
|
const auto& files = GetFiles();
|
||||||
[](auto f1, auto f2) { return f1 + f2->GetSize(); });
|
const auto file_total =
|
||||||
|
std::accumulate(files.begin(), files.end(), 0ull,
|
||||||
|
[](const auto& f1, const auto& f2) { return f1 + f2->GetSize(); });
|
||||||
|
|
||||||
|
const auto& sub_dir = GetSubdirectories();
|
||||||
|
const auto subdir_total =
|
||||||
|
std::accumulate(sub_dir.begin(), sub_dir.end(), 0ull,
|
||||||
|
[](const auto& f1, const auto& f2) { return f1 + f2->GetSize(); });
|
||||||
|
|
||||||
return file_total + subdir_total;
|
return file_total + subdir_total;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VfsDirectory::Copy(const std::string& src, const std::string& dest) {
|
bool VfsDirectory::Copy(const std::string& src, const std::string& dest) {
|
||||||
auto f1 = CreateFile(src), f2 = CreateFile(dest);
|
const auto f1 = CreateFile(src);
|
||||||
|
auto f2 = CreateFile(dest);
|
||||||
if (f1 == nullptr || f2 == nullptr)
|
if (f1 == nullptr || f2 == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return f2->ReplaceBytes(f1->ReadAllBytes()) == f1->GetSize();
|
if (!f2->Resize(f1->GetSize())) {
|
||||||
|
DeleteFile(dest);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return f2->WriteBytes(f1->ReadAllBytes()) == f1->GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
VfsFile::~VfsFile() {}
|
|
||||||
|
|
||||||
VfsDirectory::~VfsDirectory() {}
|
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "boost/optional.hpp"
|
#include "boost/optional.hpp"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
@@ -13,82 +15,93 @@ namespace FileSys {
|
|||||||
struct VfsDirectory;
|
struct VfsDirectory;
|
||||||
|
|
||||||
struct VfsFile : NonCopyable {
|
struct VfsFile : NonCopyable {
|
||||||
virtual bool IsReady() = 0;
|
virtual ~VfsFile();
|
||||||
virtual bool IsGood() = 0;
|
|
||||||
virtual operator bool();
|
|
||||||
virtual void ResetState() = 0;
|
|
||||||
|
|
||||||
virtual std::string GetName() = 0;
|
virtual std::string GetName() const = 0;
|
||||||
virtual u64 GetSize() = 0;
|
virtual size_t GetSize() const = 0;
|
||||||
virtual bool Resize(u64 new_size) = 0;
|
virtual bool Resize(size_t new_size) = 0;
|
||||||
virtual std::shared_ptr<VfsDirectory> GetContainingDirectory() = 0;
|
virtual std::shared_ptr<VfsDirectory> GetContainingDirectory() const = 0;
|
||||||
|
|
||||||
virtual bool IsWritable() = 0;
|
virtual bool IsWritable() const = 0;
|
||||||
virtual bool IsReadable() = 0;
|
virtual bool IsReadable() const = 0;
|
||||||
|
|
||||||
virtual boost::optional<u8> ReadByte(u64 offset);
|
virtual size_t Read(u8* data, size_t length, size_t offset = 0) const = 0;
|
||||||
virtual std::vector<u8> ReadBytes(u64 offset, u64 length) = 0;
|
virtual size_t Write(const u8* data, size_t length, size_t offset = 0) = 0;
|
||||||
|
|
||||||
|
virtual boost::optional<u8> ReadByte(size_t offset = 0) const;
|
||||||
|
virtual std::vector<u8> ReadBytes(size_t size, size_t offset = 0) const;
|
||||||
|
virtual std::vector<u8> ReadAllBytes() const;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
u64 ReadBytes(T* data, u64 offset, u64 length) {
|
size_t ReadArray(T* data, size_t number_elements, size_t offset = 0) const {
|
||||||
static_assert(std::is_trivially_copyable<T>(),
|
static_assert(std::is_trivially_copyable<T>::value,
|
||||||
"Given array does not consist of trivially copyable objects");
|
"Data type must be trivially copyable.");
|
||||||
return ReadArray<u8>(reinterpret_cast<u8*>(data), offset, length);
|
|
||||||
|
return Read(data, number_elements * sizeof(T), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<T> ReadArray(u64 offset, u64 number_elements) {
|
size_t ReadBytes(T* data, size_t size, size_t offset = 0) const {
|
||||||
static_assert(std::is_trivially_copyable<T>(),
|
static_assert(std::is_trivially_copyable<T>::value,
|
||||||
"Given array does not consist of trivially copyable objects");
|
"Data type must be trivially copyable.");
|
||||||
|
return Read(reinterpret_cast<u8*>(data), size, offset);
|
||||||
auto vec = ReadBytes(offset, number_elements * sizeof(T));
|
|
||||||
std::vector<T> out_vec(number_elements);
|
|
||||||
memcpy(out_vec.data(), vec.data(), vec.size());
|
|
||||||
return out_vec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
u64 ReadArray(T* data, u64 offset, u64 number_elements) {
|
size_t ReadObject(T& data, size_t offset = 0) const {
|
||||||
static_assert(std::is_trivially_copyable<T>(),
|
static_assert(std::is_trivially_copyable<T>::value,
|
||||||
"Given array does not consist of trivially copyable objects");
|
"Data type must be trivially copyable.");
|
||||||
|
return Read(&data, sizeof(T), offset);
|
||||||
std::vector<T> vec = ReadArray<T>(offset, number_elements);
|
|
||||||
for (size_t i = 0; i < vec.size(); ++i)
|
|
||||||
data[i] = vec[i];
|
|
||||||
|
|
||||||
return vec.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::vector<u8> ReadAllBytes();
|
virtual bool WriteByte(u8 data, size_t offset = 0);
|
||||||
|
virtual size_t WriteBytes(std::vector<u8> data, size_t offset = 0);
|
||||||
|
|
||||||
virtual u64 WriteBytes(const std::vector<u8>& data, u64 offset) = 0;
|
template <typename T>
|
||||||
virtual u64 ReplaceBytes(const std::vector<u8>& data);
|
size_t WriteArray(T* data, size_t number_elements, size_t offset = 0) {
|
||||||
|
static_assert(std::is_trivially_copyable<T>::value,
|
||||||
|
"Data type must be trivially copyable.");
|
||||||
|
|
||||||
|
return Write(data, number_elements * sizeof(T), offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t WriteBytes(T* data, size_t size, size_t offset = 0) {
|
||||||
|
static_assert(std::is_trivially_copyable<T>::value,
|
||||||
|
"Data type must be trivially copyable.");
|
||||||
|
return Write(reinterpret_cast<u8*>(data), size, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t WriteObject(T& data, size_t offset = 0) {
|
||||||
|
static_assert(std::is_trivially_copyable<T>::value,
|
||||||
|
"Data type must be trivially copyable.");
|
||||||
|
return Write(&data, sizeof(T), offset);
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool Rename(const std::string& name) = 0;
|
virtual bool Rename(const std::string& name) = 0;
|
||||||
|
|
||||||
~VfsFile();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VfsDirectory : NonCopyable {
|
struct VfsDirectory : NonCopyable {
|
||||||
virtual bool IsReady() = 0;
|
virtual ~VfsDirectory();
|
||||||
virtual bool IsGood() = 0;
|
|
||||||
virtual operator bool();
|
|
||||||
virtual void ResetState() = 0;
|
|
||||||
|
|
||||||
virtual std::vector<std::shared_ptr<VfsFile>> GetFiles() = 0;
|
virtual std::shared_ptr<VfsFile> GetFileRelative(const std::filesystem::path& path) const;
|
||||||
virtual std::shared_ptr<VfsFile> GetFile(const std::string& name);
|
virtual std::shared_ptr<VfsFile> GetFileAbsolute(const std::filesystem::path& path) const;
|
||||||
|
|
||||||
virtual std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() = 0;
|
virtual std::vector<std::shared_ptr<VfsFile>> GetFiles() const = 0;
|
||||||
virtual std::shared_ptr<VfsDirectory> GetSubdirectory(const std::string& name);
|
virtual std::shared_ptr<VfsFile> GetFile(const std::string& name) const;
|
||||||
|
|
||||||
virtual bool IsWritable() = 0;
|
virtual std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const = 0;
|
||||||
virtual bool IsReadable() = 0;
|
virtual std::shared_ptr<VfsDirectory> GetSubdirectory(const std::string& name) const;
|
||||||
|
|
||||||
virtual bool IsRoot() = 0;
|
virtual bool IsWritable() const = 0;
|
||||||
|
virtual bool IsReadable() const = 0;
|
||||||
|
|
||||||
virtual std::string GetName() = 0;
|
virtual bool IsRoot() const;
|
||||||
virtual u64 GetSize();
|
|
||||||
virtual std::shared_ptr<VfsDirectory> GetParentDirectory() = 0;
|
virtual std::string GetName() const = 0;
|
||||||
|
virtual size_t GetSize() const;
|
||||||
|
virtual std::shared_ptr<VfsDirectory> GetParentDirectory() const = 0;
|
||||||
|
|
||||||
virtual std::shared_ptr<VfsDirectory> CreateSubdirectory(const std::string& name) = 0;
|
virtual std::shared_ptr<VfsDirectory> CreateSubdirectory(const std::string& name) = 0;
|
||||||
virtual std::shared_ptr<VfsFile> CreateFile(const std::string& name) = 0;
|
virtual std::shared_ptr<VfsFile> CreateFile(const std::string& name) = 0;
|
||||||
@@ -99,7 +112,5 @@ struct VfsDirectory : NonCopyable {
|
|||||||
virtual bool Rename(const std::string& name) = 0;
|
virtual bool Rename(const std::string& name) = 0;
|
||||||
|
|
||||||
virtual bool Copy(const std::string& src, const std::string& dest);
|
virtual bool Copy(const std::string& src, const std::string& dest);
|
||||||
|
|
||||||
~VfsDirectory();
|
|
||||||
};
|
};
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|||||||
@@ -6,26 +6,14 @@
|
|||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
OffsetVfsFile::OffsetVfsFile(std::unique_ptr<VfsFile>&& file, u64 offset, u64 size)
|
OffsetVfsFile::OffsetVfsFile(std::unique_ptr<VfsFile>&& file_, u64 offset_, u64 size_)
|
||||||
: file(std::move(file)), offset(offset), size(size) {}
|
: file(std::move(file_)), offset(offset_), size(size_) {}
|
||||||
|
|
||||||
bool OffsetVfsFile::IsReady() {
|
std::string OffsetVfsFile::GetName() const {
|
||||||
return file->IsReady();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OffsetVfsFile::IsGood() {
|
|
||||||
return file->IsGood();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OffsetVfsFile::ResetState() {
|
|
||||||
file->ResetState();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string OffsetVfsFile::GetName() {
|
|
||||||
return file->GetName();
|
return file->GetName();
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 OffsetVfsFile::GetSize() {
|
u64 OffsetVfsFile::GetSize() const {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,32 +26,58 @@ bool OffsetVfsFile::Resize(u64 new_size) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<VfsDirectory> OffsetVfsFile::GetContainingDirectory() {
|
std::shared_ptr<VfsDirectory> OffsetVfsFile::GetContainingDirectory() const {
|
||||||
return file->GetContainingDirectory();
|
return file->GetContainingDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OffsetVfsFile::IsWritable() {
|
bool OffsetVfsFile::IsWritable() const {
|
||||||
return file->IsWritable();
|
return file->IsWritable();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OffsetVfsFile::IsReadable() {
|
bool OffsetVfsFile::IsReadable() const {
|
||||||
return file->IsReadable();
|
return file->IsReadable();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> OffsetVfsFile::ReadBytes(u64 r_offset, u64 r_length) {
|
size_t OffsetVfsFile::Read(u8* data, size_t length, size_t r_offset) const {
|
||||||
return file->ReadBytes(offset + r_offset, std::min(r_offset + r_length, size));
|
return file->Read(data, TrimToFit(length, r_offset), offset + r_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 OffsetVfsFile::WriteBytes(const std::vector<u8>& data, u64 r_offset) {
|
size_t OffsetVfsFile::Write(const u8* data, size_t length, size_t r_offset) {
|
||||||
auto end = data.end();
|
return file->Write(data, TrimToFit(length, r_offset), offset + r_offset);
|
||||||
if (data.size() + r_offset > size)
|
}
|
||||||
end = data.begin() + size - r_offset;
|
|
||||||
|
|
||||||
return file->WriteBytes(std::vector<u8>(data.begin(), end), r_offset + offset);
|
boost::optional<u8> OffsetVfsFile::ReadByte(size_t r_offset) const {
|
||||||
|
if (r_offset < size)
|
||||||
|
return file->ReadByte(offset + r_offset);
|
||||||
|
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u8> OffsetVfsFile::ReadBytes(size_t r_size, size_t r_offset) const {
|
||||||
|
return file->ReadBytes(TrimToFit(r_size, r_offset), offset + r_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u8> OffsetVfsFile::ReadAllBytes() const {
|
||||||
|
return file->ReadBytes(size, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OffsetVfsFile::WriteByte(u8 data, size_t r_offset) {
|
||||||
|
if (r_offset < size)
|
||||||
|
return file->WriteByte(data, offset + r_offset);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t OffsetVfsFile::WriteBytes(std::vector<u8> data, size_t r_offset) {
|
||||||
|
return file->Write(data.data(), TrimToFit(data.size(), r_offset), offset + r_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OffsetVfsFile::Rename(const std::string& name) {
|
bool OffsetVfsFile::Rename(const std::string& name) {
|
||||||
return file->Rename(name);
|
return file->Rename(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t OffsetVfsFile::TrimToFit(size_t r_size, size_t r_offset) const {
|
||||||
|
return std::max(std::min(size - r_offset, r_size), 0ull);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|||||||
@@ -3,30 +3,36 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
struct OffsetVfsFile : public VfsFile {
|
struct OffsetVfsFile : public VfsFile {
|
||||||
OffsetVfsFile(std::unique_ptr<VfsFile>&& file, u64 offset, u64 size);
|
OffsetVfsFile(std::unique_ptr<VfsFile>&& file, size_t offset, size_t size);
|
||||||
|
|
||||||
|
std::string GetName() const override;
|
||||||
|
size_t GetSize() const override;
|
||||||
|
bool Resize(size_t new_size) override;
|
||||||
|
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
|
||||||
|
bool IsWritable() const override;
|
||||||
|
bool IsReadable() const override;
|
||||||
|
size_t Read(u8* data, size_t length, size_t offset) const override;
|
||||||
|
size_t Write(const u8* data, size_t length, size_t offset) override;
|
||||||
|
boost::optional<u8> ReadByte(size_t offset) const override;
|
||||||
|
std::vector<u8> ReadBytes(size_t size, size_t offset) const override;
|
||||||
|
std::vector<u8> ReadAllBytes() const override;
|
||||||
|
bool WriteByte(u8 data, size_t offset) override;
|
||||||
|
size_t WriteBytes(std::vector<u8> data, size_t offset) override;
|
||||||
|
|
||||||
bool IsReady() override;
|
|
||||||
bool IsGood() override;
|
|
||||||
void ResetState() override;
|
|
||||||
std::string GetName() override;
|
|
||||||
u64 GetSize() override;
|
|
||||||
bool Resize(u64 new_size) override;
|
|
||||||
std::shared_ptr<VfsDirectory> GetContainingDirectory() override;
|
|
||||||
bool IsWritable() override;
|
|
||||||
bool IsReadable() override;
|
|
||||||
std::vector<u8> ReadBytes(u64 offset, u64 length) override;
|
|
||||||
u64 WriteBytes(const std::vector<u8>& data, u64 offset) override;
|
|
||||||
bool Rename(const std::string& name) override;
|
bool Rename(const std::string& name) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
size_t TrimToFit(size_t r_size, size_t r_offset) const;
|
||||||
|
|
||||||
std::unique_ptr<VfsFile> file;
|
std::unique_ptr<VfsFile> file;
|
||||||
u64 offset;
|
size_t offset;
|
||||||
u64 size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|||||||
@@ -2,160 +2,128 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/common_paths.h"
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/file_sys/vfs_real.h"
|
#include "core/file_sys/vfs_real.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
RealVfsFile::RealVfsFile(const std::string& path, const char openmode[])
|
static const char* PermissionsToCharArray(std::filesystem::perms perms) {
|
||||||
: backing(path, openmode), path(path), mode(openmode) {}
|
std::string out;
|
||||||
|
if ((perms & std::filesystem::perms::owner_read) != std::filesystem::perms::none)
|
||||||
bool RealVfsFile::IsReady() {
|
out += "r";
|
||||||
return backing.IsOpen();
|
if ((perms & std::filesystem::perms::owner_write) != std::filesystem::perms::none)
|
||||||
|
out += "w";
|
||||||
|
return out.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsFile::IsGood() {
|
RealVfsFile::RealVfsFile(const std::filesystem::path& path_, std::filesystem::perms perms_)
|
||||||
return backing.IsGood();
|
: backing(path_.string(), PermissionsToCharArray(perms_)), path(path_), perms(perms_) {}
|
||||||
|
|
||||||
|
std::string RealVfsFile::GetName() const {
|
||||||
|
return path.filename().string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RealVfsFile::ResetState() {
|
size_t RealVfsFile::GetSize() const {
|
||||||
backing.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string RealVfsFile::GetName() {
|
|
||||||
std::string part_path, name, extention;
|
|
||||||
Common::SplitPath(path, &part_path, &name, &extention);
|
|
||||||
return name + "." + extention;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 RealVfsFile::GetSize() {
|
|
||||||
return backing.GetSize();
|
return backing.GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsFile::Resize(u64 new_size) {
|
bool RealVfsFile::Resize(size_t new_size) {
|
||||||
return backing.Resize(new_size);
|
return backing.Resize(new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<VfsDirectory> RealVfsFile::GetContainingDirectory() {
|
std::shared_ptr<VfsDirectory> RealVfsFile::GetContainingDirectory() const {
|
||||||
std::string part_path, name, extention;
|
return std::make_shared<RealVfsDirectory>(path.parent_path(), perms);
|
||||||
Common::SplitPath(path, &part_path, &name, &extention);
|
|
||||||
return std::make_shared<RealVfsDirectory>(part_path, mode.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsFile::IsWritable() {
|
bool RealVfsFile::IsWritable() const {
|
||||||
return mode.find('w') != std::string::npos;
|
return (perms & std::filesystem::perms::owner_write) != std::filesystem::perms::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsFile::IsReadable() {
|
bool RealVfsFile::IsReadable() const {
|
||||||
return mode.find('r') != std::string::npos;
|
return (perms & std::filesystem::perms::owner_read) != std::filesystem::perms::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> RealVfsFile::ReadBytes(u64 offset, u64 length) {
|
size_t RealVfsFile::Read(u8* data, size_t length, size_t offset) const {
|
||||||
backing.Seek(offset, SEEK_SET);
|
if (!backing.Seek(offset, SEEK_SET))
|
||||||
std::vector<u8> out(length);
|
return 0;
|
||||||
backing.ReadBytes(out.data(), length);
|
return backing.ReadBytes(data, length);
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 RealVfsFile::WriteBytes(const std::vector<u8>& data, u64 offset) {
|
size_t RealVfsFile::Write(const u8* data, size_t length, size_t offset) {
|
||||||
backing.Seek(offset, SEEK_SET);
|
if (!backing.Seek(offset, SEEK_SET))
|
||||||
return backing.WriteBytes(data.data(), data.size());
|
return 0;
|
||||||
|
return backing.WriteBytes(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsFile::Rename(const std::string& name) {
|
bool RealVfsFile::Rename(const std::string& name) {
|
||||||
auto out = FileUtil::Rename(GetName(), name);
|
const auto out = FileUtil::Rename(GetName(), name);
|
||||||
std::string part_path, o_name, extention;
|
path = path.parent_path() / name;
|
||||||
Common::SplitPath(path, &part_path, &o_name, &extention);
|
backing = FileUtil::IOFile(path.string(), PermissionsToCharArray(perms));
|
||||||
backing = FileUtil::IOFile(part_path + name, mode.c_str());
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
RealVfsDirectory::RealVfsDirectory(const std::string& path, const char openmode[])
|
RealVfsDirectory::RealVfsDirectory(const std::filesystem::path& path_,
|
||||||
: path(path[path.size() - 1] == DIR_SEP_CHR ? path.substr(0, path.size() - 1) : path) {
|
std::filesystem::perms perms_)
|
||||||
FileUtil::FSTEntry entry;
|
: path(path_), perms(perms_) {
|
||||||
if (0 != FileUtil::ScanDirectoryTree(path, entry))
|
for (const auto& entry : std::filesystem::directory_iterator(path)) {
|
||||||
NGLOG_CRITICAL(Service_FS, "Failure to initialize file.");
|
if (std::filesystem::is_directory(entry.path()))
|
||||||
for (FileUtil::FSTEntry child : entry.children) {
|
subdirectories.emplace_back(std::make_shared<RealVfsDirectory>(entry.path(), perms));
|
||||||
if (child.isDirectory)
|
else if (std::filesystem::is_regular_file(entry.path()))
|
||||||
subdirectories.emplace_back(
|
files.emplace_back(std::make_shared<RealVfsFile>(entry.path(), perms));
|
||||||
std::make_shared<RealVfsDirectory>(child.physicalName, mode.c_str()));
|
|
||||||
else
|
|
||||||
files.emplace_back(std::make_shared<RealVfsFile>(child.physicalName, mode.c_str()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsDirectory::IsReady() {
|
std::vector<std::shared_ptr<VfsFile>> RealVfsDirectory::GetFiles() const {
|
||||||
return FileUtil::IsDirectory(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RealVfsDirectory::IsGood() {
|
|
||||||
return FileUtil::IsDirectory(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RealVfsDirectory::ResetState() {}
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<VfsFile>> RealVfsDirectory::GetFiles() {
|
|
||||||
return std::vector<std::shared_ptr<VfsFile>>(files);
|
return std::vector<std::shared_ptr<VfsFile>>(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<VfsDirectory>> RealVfsDirectory::GetSubdirectories() {
|
std::vector<std::shared_ptr<VfsDirectory>> RealVfsDirectory::GetSubdirectories() const {
|
||||||
return std::vector<std::shared_ptr<VfsDirectory>>(subdirectories);
|
return std::vector<std::shared_ptr<VfsDirectory>>(subdirectories);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsDirectory::IsWritable() {
|
bool RealVfsDirectory::IsWritable() const {
|
||||||
return mode.find('w') != std::string::npos;
|
return (perms & std::filesystem::perms::owner_write) != std::filesystem::perms::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsDirectory::IsReadable() {
|
bool RealVfsDirectory::IsReadable() const {
|
||||||
return mode.find('r') != std::string::npos;
|
return (perms & std::filesystem::perms::owner_read) != std::filesystem::perms::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsDirectory::IsRoot() {
|
std::string RealVfsDirectory::GetName() const {
|
||||||
return path.empty() || (path.size() == 2 && path[1] == ':');
|
return path.filename().string();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RealVfsDirectory::GetName() {
|
std::shared_ptr<VfsDirectory> RealVfsDirectory::GetParentDirectory() const {
|
||||||
size_t last = path.rfind(DIR_SEP_CHR);
|
if (path.parent_path() == path.root_path())
|
||||||
return path.substr(last + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<VfsDirectory> 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 nullptr;
|
||||||
|
|
||||||
return std::make_shared<RealVfsDirectory>(path.substr(0, last), mode.c_str());
|
return std::make_shared<RealVfsDirectory>(path.parent_path(), perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<VfsDirectory> RealVfsDirectory::CreateSubdirectory(const std::string& name) {
|
std::shared_ptr<VfsDirectory> RealVfsDirectory::CreateSubdirectory(const std::string& name) {
|
||||||
FileUtil::CreateDir(path + DIR_SEP + name);
|
if (!FileUtil::CreateDir((path / name).string()))
|
||||||
subdirectories.emplace_back(
|
return nullptr;
|
||||||
std::make_shared<RealVfsDirectory>(path + DIR_SEP + name, mode.c_str()));
|
subdirectories.emplace_back(std::make_shared<RealVfsDirectory>(path / name, perms));
|
||||||
return subdirectories[subdirectories.size() - 1];
|
return subdirectories.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<VfsFile> RealVfsDirectory::CreateFile(const std::string& name) {
|
std::shared_ptr<VfsFile> RealVfsDirectory::CreateFile(const std::string& name) {
|
||||||
FileUtil::CreateEmptyFile(path + DIR_SEP + name);
|
if (!FileUtil::CreateEmptyFile((path / name).string()))
|
||||||
files.emplace_back(std::make_shared<RealVfsFile>(path + DIR_SEP + name, mode.c_str()));
|
return nullptr;
|
||||||
return files[files.size() - 1];
|
files.emplace_back(std::make_shared<RealVfsFile>(path / name, perms));
|
||||||
|
return files.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsDirectory::DeleteSubdirectory(const std::string& name) {
|
bool RealVfsDirectory::DeleteSubdirectory(const std::string& name) {
|
||||||
return FileUtil::DeleteDirRecursively(path + DIR_SEP + name);
|
return FileUtil::DeleteDirRecursively((path / name).string());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsDirectory::DeleteFile(const std::string& name) {
|
bool RealVfsDirectory::DeleteFile(const std::string& name) {
|
||||||
return FileUtil::Delete(path + DIR_SEP + name);
|
return FileUtil::Delete((path / name).string());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RealVfsDirectory::Rename(const std::string& name) {
|
bool RealVfsDirectory::Rename(const std::string& name) {
|
||||||
std::string part, o_name, extention;
|
return FileUtil::Rename(path.string(), (path / name).string());
|
||||||
Common::SplitPath(name, &part, &o_name, &extention);
|
|
||||||
return FileUtil::Rename(path, part + DIR_SEP + name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|||||||
@@ -3,46 +3,42 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
struct RealVfsFile : public VfsFile {
|
struct RealVfsFile : public VfsFile {
|
||||||
RealVfsFile(const std::string& name, const char openmode[]);
|
RealVfsFile(const std::filesystem::path& name, std::filesystem::perms perms);
|
||||||
|
|
||||||
bool IsReady() override;
|
std::string GetName() const override;
|
||||||
bool IsGood() override;
|
size_t GetSize() const override;
|
||||||
void ResetState() override;
|
bool Resize(size_t new_size) override;
|
||||||
std::string GetName() override;
|
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
|
||||||
u64 GetSize() override;
|
bool IsWritable() const override;
|
||||||
bool Resize(u64 new_size) override;
|
bool IsReadable() const override;
|
||||||
std::shared_ptr<VfsDirectory> GetContainingDirectory() override;
|
size_t Read(u8* data, size_t length, size_t offset) const override;
|
||||||
bool IsWritable() override;
|
size_t Write(const u8* data, size_t length, size_t offset) override;
|
||||||
bool IsReadable() override;
|
|
||||||
std::vector<u8> ReadBytes(u64 offset, u64 length) override;
|
|
||||||
u64 WriteBytes(const std::vector<u8>& data, u64 offset) override;
|
|
||||||
bool Rename(const std::string& name) override;
|
bool Rename(const std::string& name) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileUtil::IOFile backing;
|
FileUtil::IOFile backing;
|
||||||
std::string path;
|
std::filesystem::path path;
|
||||||
std::string mode;
|
std::filesystem::perms perms;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RealVfsDirectory : public VfsDirectory {
|
struct RealVfsDirectory : public VfsDirectory {
|
||||||
RealVfsDirectory(const std::string& path, const char openmode[]);
|
RealVfsDirectory(const std::filesystem::path& path, std::filesystem::perms perms);
|
||||||
|
|
||||||
bool IsReady() override;
|
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
|
||||||
bool IsGood() override;
|
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
|
||||||
void ResetState() override;
|
bool IsWritable() const override;
|
||||||
std::vector<std::shared_ptr<VfsFile>> GetFiles() override;
|
bool IsReadable() const override;
|
||||||
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() override;
|
bool IsRoot() const override;
|
||||||
bool IsWritable() override;
|
std::string GetName() const override;
|
||||||
bool IsReadable() override;
|
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
|
||||||
bool IsRoot() override;
|
|
||||||
std::string GetName() override;
|
|
||||||
std::shared_ptr<VfsDirectory> GetParentDirectory() override;
|
|
||||||
std::shared_ptr<VfsDirectory> CreateSubdirectory(const std::string& name) override;
|
std::shared_ptr<VfsDirectory> CreateSubdirectory(const std::string& name) override;
|
||||||
std::shared_ptr<VfsFile> CreateFile(const std::string& name) override;
|
std::shared_ptr<VfsFile> CreateFile(const std::string& name) override;
|
||||||
bool DeleteSubdirectory(const std::string& name) override;
|
bool DeleteSubdirectory(const std::string& name) override;
|
||||||
@@ -50,8 +46,8 @@ struct RealVfsDirectory : public VfsDirectory {
|
|||||||
bool Rename(const std::string& name) override;
|
bool Rename(const std::string& name) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string path;
|
std::filesystem::path path;
|
||||||
std::string mode;
|
std::filesystem::perms perms;
|
||||||
std::vector<std::shared_ptr<VfsFile>> files;
|
std::vector<std::shared_ptr<VfsFile>> files;
|
||||||
std::vector<std::shared_ptr<VfsDirectory>> subdirectories;
|
std::vector<std::shared_ptr<VfsDirectory>> subdirectories;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user