Finish abstract Vfs classes
This commit is contained in:
@@ -2,6 +2,62 @@
|
|||||||
// 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 <numeric>
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
|
|
||||||
namespace FileSys {}
|
namespace FileSys {
|
||||||
|
|
||||||
|
VfsFile::operator bool() {
|
||||||
|
return IsGood();
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<u8> VfsFile::ReadByte(u64 offset) {
|
||||||
|
auto vec = ReadBytes(offset, 1);
|
||||||
|
if (vec.empty())
|
||||||
|
return boost::none;
|
||||||
|
return vec[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u8> VfsFile::ReadAllBytes() {
|
||||||
|
return ReadBytes(0, GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 VfsFile::ReplaceBytes(const std::vector<u8>& data) {
|
||||||
|
if (!Resize(data.size()))
|
||||||
|
return 0;
|
||||||
|
return WriteBytes(data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<VfsFile> 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(); });
|
||||||
|
return iter == files.end() ? boost::none : boost::make_optional(*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<VfsDirectory> 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(); });
|
||||||
|
return iter == subs.end() ? boost::none : boost::make_optional(*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 VfsDirectory::GetSize() {
|
||||||
|
auto files = GetFiles();
|
||||||
|
auto file_total = std::accumulate(files.begin(), files.end(), 0);
|
||||||
|
|
||||||
|
auto sub_dir = GetSubdirectories();
|
||||||
|
auto subdir_total = std::accumulate(sub_dir.begin(), sub_dir.end(), 0);
|
||||||
|
|
||||||
|
return file_total + subdir_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VfsDirectory::Copy(const std::string& src, const std::string& dest) {
|
||||||
|
auto f1 = CreateFile(src), f2 = CreateFile(dest);
|
||||||
|
if (f1 == boost::none || f2 == boost::none)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return f2->ReplaceBytes(f1->ReadAllBytes()) == f1->GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys
|
||||||
|
|||||||
@@ -4,69 +4,93 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boost/optional.hpp"
|
|
||||||
#include "common/common_types.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "boost/optional.hpp"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace FileSys
|
namespace FileSys {
|
||||||
{
|
struct VfsDirectory;
|
||||||
struct VfsDirectory;
|
|
||||||
|
|
||||||
struct VfsFile : NonCopyable
|
struct VfsFile : NonCopyable {
|
||||||
{
|
virtual bool IsReady() = 0;
|
||||||
bool IsReady();
|
virtual bool IsGood() = 0;
|
||||||
bool IsGood();
|
virtual operator bool();
|
||||||
operator bool();
|
virtual void ResetState() = 0;
|
||||||
void ResetState();
|
|
||||||
|
|
||||||
std::string GetName();
|
virtual std::string GetName() = 0;
|
||||||
u64 GetSize();
|
virtual u64 GetSize() = 0;
|
||||||
bool Resize(u64 new_size);
|
virtual bool Resize(u64 new_size) = 0;
|
||||||
boost::optional<VfsDirectory> GetContainingDirectory();
|
virtual boost::optional<VfsDirectory> GetContainingDirectory() = 0;
|
||||||
|
|
||||||
bool IsWritable();
|
virtual bool IsWritable() = 0;
|
||||||
bool IsReadable();
|
virtual bool IsReadable() = 0;
|
||||||
|
|
||||||
std::vector<u8> ReadBytes(u64 offset, u64 length);
|
virtual boost::optional<u8> ReadByte(u64 offset);
|
||||||
template <typename T> u64 ReadBytes(T* data, u64 offset, u64 length);
|
virtual std::vector<u8> ReadBytes(u64 offset, u64 length) = 0;
|
||||||
|
|
||||||
template <typename T> std::vector<T> ReadArray(u64 offset, u64 number_elements);
|
template <typename T>
|
||||||
template <typename T> u64 ReadArray(T* data, u64 offset, u64 number_elements);
|
u64 ReadBytes(T* data, u64 offset, u64 length) {
|
||||||
|
static_assert(std::is_trivially_copyable<T>(),
|
||||||
|
"Given array does not consist of trivially copyable objects");
|
||||||
|
return ReadArray<u8>(reinterpret_cast<u8*>(data), offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<u8> ReadAllBytes();
|
template <typename T>
|
||||||
|
std::vector<T> ReadArray(u64 offset, u64 number_elements) {
|
||||||
|
static_assert(std::is_trivially_copyable<T>(),
|
||||||
|
"Given array does not consist of trivially copyable objects");
|
||||||
|
|
||||||
void WriteBytes(const std::vector<u8>& data, u64 offset);
|
auto vec = ReadBytes(offset, number_elements * sizeof(T));
|
||||||
void ReplaceBytes(const std::vector<u8>& data);
|
std::vector<T> out_vec(number_elements);
|
||||||
|
memcpy(out_vec.data(), vec.data(), vec.size());
|
||||||
|
return out_vec;
|
||||||
|
}
|
||||||
|
|
||||||
bool Rename(const std::string& name);
|
template <typename T>
|
||||||
};
|
u64 ReadArray(T* data, u64 offset, u64 number_elements) {
|
||||||
|
static_assert(std::is_trivially_copyable<T>(),
|
||||||
|
"Given array does not consist of trivially copyable objects");
|
||||||
|
|
||||||
struct VfsDirectory : NonCopyable
|
std::vector<T> vec = ReadArray<T>(offset, number_elements);
|
||||||
{
|
for (size_t i = 0; i < vec.size(); ++i)
|
||||||
std::vector<VfsFile> GetFiles();
|
data[i] = vec[i];
|
||||||
boost::optional<VfsFile> GetFile(const std::string& name);
|
|
||||||
|
|
||||||
std::vector<VfsDirectory> GetSubdirectories();
|
return vec.size();
|
||||||
boost::optional<VfsFile> GetSubdirectory(const std::string& name);
|
}
|
||||||
|
|
||||||
bool IsWritable();
|
virtual std::vector<u8> ReadAllBytes();
|
||||||
bool IsReadable();
|
|
||||||
|
|
||||||
bool IsRoot();
|
virtual u64 WriteBytes(const std::vector<u8>& data, u64 offset) = 0;
|
||||||
|
virtual u64 ReplaceBytes(const std::vector<u8>& data);
|
||||||
|
|
||||||
std::string GetName();
|
virtual bool Rename(const std::string& name) = 0;
|
||||||
u64 GetSize();
|
};
|
||||||
boost::optional<VfsDirectory> GetParentDirectory();
|
|
||||||
|
|
||||||
boost::optional<VfsDirectory> CreateSubdirectory(const std::string& name);
|
struct VfsDirectory : NonCopyable {
|
||||||
boost::optional<VfsFile> CreateFile(const std::string& name);
|
virtual std::vector<VfsFile> GetFiles() = 0;
|
||||||
|
virtual boost::optional<VfsFile> GetFile(const std::string& name);
|
||||||
|
|
||||||
bool DeleteSubdirectory(const std::string& name);
|
virtual std::vector<VfsDirectory> GetSubdirectories() = 0;
|
||||||
bool DeleteFile(const std::string& name);
|
virtual boost::optional<VfsDirectory> GetSubdirectory(const std::string& name);
|
||||||
|
|
||||||
bool Rename(const std::string& name);
|
virtual bool IsWritable() = 0;
|
||||||
|
virtual bool IsReadable() = 0;
|
||||||
|
|
||||||
bool Copy(const std::string& src, const std::string& dest);
|
virtual bool IsRoot() = 0;
|
||||||
};
|
|
||||||
}
|
virtual std::string GetName() = 0;
|
||||||
|
virtual u64 GetSize();
|
||||||
|
virtual boost::optional<VfsDirectory> GetParentDirectory() = 0;
|
||||||
|
|
||||||
|
virtual boost::optional<VfsDirectory> CreateSubdirectory(const std::string& name) = 0;
|
||||||
|
virtual boost::optional<VfsFile> CreateFile(const std::string& name) = 0;
|
||||||
|
|
||||||
|
virtual bool DeleteSubdirectory(const std::string& name) = 0;
|
||||||
|
virtual bool DeleteFile(const std::string& name) = 0;
|
||||||
|
|
||||||
|
virtual bool Rename(const std::string& name) = 0;
|
||||||
|
|
||||||
|
virtual bool Copy(const std::string& src, const std::string& dest);
|
||||||
|
};
|
||||||
|
} // namespace FileSys
|
||||||
|
|||||||
Reference in New Issue
Block a user