Virtual Filesystem (#597)

* Add VfsFile and VfsDirectory classes

* Finish abstract Vfs classes

* Implement RealVfsFile (computer fs backend)

* Finish RealVfsFile and RealVfsDirectory

* Finished OffsetVfsFile

* More changes

* Fix import paths

* Major refactor

* Remove double const

* Use experimental/filesystem or filesystem depending on compiler

* Port partition_filesystem

* More changes

* More Overhaul

* FSP_SRV fixes

* Fixes and testing

* Try to get filesystem to compile

* Filesystem on linux

* Remove std::filesystem and document/test

* Compile fixes

* Missing include

* Bug fixes

* Fixes

* Rename v_file and v_dir

* clang-format fix

* Rename NGLOG_* to LOG_*

* Most review changes

* Fix TODO

* Guess 'main' to be Directory by filename
This commit is contained in:
Zach Hilman 2018-07-06 10:51:32 -04:00 committed by bunnei
parent 0ea724e06b
commit 12e9522b32
45 changed files with 1796 additions and 1688 deletions

View file

@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <sstream>
#include "common/assert.h"
#include "common/common_funcs.h"
#include "common/common_paths.h"
@ -386,7 +387,7 @@ u64 GetSize(FILE* f) {
bool CreateEmptyFile(const std::string& filename) {
LOG_TRACE(Common_Filesystem, "{}", filename);
if (!FileUtil::IOFile(filename, "wb")) {
if (!FileUtil::IOFile(filename, "wb").IsOpen()) {
LOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg());
return false;
}
@ -750,7 +751,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) {
IOFile file(filename, text_file ? "r" : "rb");
if (!file)
if (!file.IsOpen())
return false;
str.resize(static_cast<u32>(file.GetSize()));
@ -799,6 +800,57 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
}
}
std::vector<std::string> SplitPathComponents(const std::string& filename) {
auto copy(filename);
std::replace(copy.begin(), copy.end(), '\\', '/');
std::vector<std::string> out;
std::stringstream stream(filename);
std::string item;
while (std::getline(stream, item, '/'))
out.push_back(std::move(item));
return out;
}
std::string GetParentPath(const std::string& path) {
auto out = path;
const auto name_bck_index = out.find_last_of('\\');
const auto name_fwd_index = out.find_last_of('/');
size_t name_index;
if (name_bck_index == std::string::npos || name_fwd_index == std::string::npos)
name_index = std::min<size_t>(name_bck_index, name_fwd_index);
else
name_index = std::max<size_t>(name_bck_index, name_fwd_index);
return out.erase(name_index);
}
std::string GetFilename(std::string path) {
std::replace(path.begin(), path.end(), '\\', '/');
auto name_index = path.find_last_of('/');
if (name_index == std::string::npos)
return "";
return path.substr(name_index + 1);
}
std::string GetExtensionFromFilename(const std::string& name) {
size_t index = name.find_last_of('.');
if (index == std::string::npos)
return "";
return name.substr(index + 1);
}
std::string RemoveTrailingSlash(const std::string& path) {
if (path.empty())
return path;
if (path.back() == '\\' || path.back() == '/')
return path.substr(0, path.size() - 1);
return path;
}
IOFile::IOFile() {}
IOFile::IOFile(const std::string& filename, const char openmode[], int flags) {
@ -820,7 +872,6 @@ IOFile& IOFile::operator=(IOFile&& other) noexcept {
void IOFile::Swap(IOFile& other) noexcept {
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) {
@ -837,16 +888,15 @@ bool IOFile::Open(const std::string& filename, const char openmode[], int flags)
m_file = fopen(filename.c_str(), openmode);
#endif
m_good = IsOpen();
return m_good;
return IsOpen();
}
bool IOFile::Close() {
if (!IsOpen() || 0 != std::fclose(m_file))
m_good = false;
return false;
m_file = nullptr;
return m_good;
return true;
}
u64 IOFile::GetSize() const {
@ -856,11 +906,8 @@ u64 IOFile::GetSize() const {
return 0;
}
bool IOFile::Seek(s64 off, int origin) {
if (!IsOpen() || 0 != fseeko(m_file, off, origin))
m_good = false;
return m_good;
bool IOFile::Seek(s64 off, int origin) const {
return IsOpen() && 0 == fseeko(m_file, off, origin);
}
u64 IOFile::Tell() const {
@ -871,26 +918,20 @@ u64 IOFile::Tell() const {
}
bool IOFile::Flush() {
if (!IsOpen() || 0 != std::fflush(m_file))
m_good = false;
return m_good;
return IsOpen() && 0 == std::fflush(m_file);
}
bool IOFile::Resize(u64 size) {
if (!IsOpen() || 0 !=
return IsOpen() && 0 ==
#ifdef _WIN32
// ector: _chsize sucks, not 64-bit safe
// F|RES: changed to _chsize_s. i think it is 64-bit safe
_chsize_s(_fileno(m_file), size)
// ector: _chsize sucks, not 64-bit safe
// F|RES: changed to _chsize_s. i think it is 64-bit safe
_chsize_s(_fileno(m_file), size)
#else
// TODO: handle 64bit and growing
ftruncate(fileno(m_file), size)
// TODO: handle 64bit and growing
ftruncate(fileno(m_file), size)
#endif
)
m_good = false;
return m_good;
;
}
} // namespace FileUtil