mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-16 23:17:29 +00:00
VFS fixes
- using /app_home/ as local link Implemented fmt::merge & fmt::tolower
This commit is contained in:
parent
ebae8dad0a
commit
a58c5f5a4c
@ -57,7 +57,7 @@ int fmt::CmpNoCase(const std::string& a, const std::string& b)
|
||||
return std::equal(a.begin(),
|
||||
a.end(),
|
||||
b.begin(),
|
||||
[](const char& a, const char& b){return tolower(a) == tolower(b); })
|
||||
[](const char& a, const char& b){return ::tolower(a) == ::tolower(b); })
|
||||
? 0 : -1;
|
||||
}
|
||||
}
|
||||
@ -133,4 +133,35 @@ std::vector<std::string> fmt::split(const std::string& source, std::initializer_
|
||||
}
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
std::string fmt::merge(std::vector<std::string> source, const std::string& separator)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
for (auto &s : source)
|
||||
{
|
||||
result += s + separator;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string fmt::merge(std::initializer_list<std::vector<std::string>> sources, const std::string& separator)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
for (auto &v : sources)
|
||||
{
|
||||
result += fmt::merge(v, separator);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string fmt::tolower(std::string source)
|
||||
{
|
||||
std::transform(source.begin(), source.end(), source.begin(), ::tolower);
|
||||
|
||||
return source;
|
||||
}
|
@ -194,4 +194,7 @@ namespace fmt{
|
||||
std::vector<std::string> rSplit(const std::string& source, const std::string& delim);
|
||||
|
||||
std::vector<std::string> split(const std::string& source, std::initializer_list<std::string> separators, bool is_skip_empty = true);
|
||||
std::string merge(std::vector<std::string> source, const std::string& separator);
|
||||
std::string merge(std::initializer_list<std::vector<std::string>> sources, const std::string& separator);
|
||||
std::string tolower(std::string source);
|
||||
}
|
||||
|
@ -8,23 +8,9 @@
|
||||
|
||||
#undef CreateFile
|
||||
|
||||
int sort_devices(const void* _a, const void* _b)
|
||||
{
|
||||
const vfsDevice& a = **(const vfsDevice**)_a;
|
||||
const vfsDevice& b = **(const vfsDevice**)_b;
|
||||
|
||||
if (a.GetPs3Path().length() > b.GetPs3Path().length()) return 1;
|
||||
if (a.GetPs3Path().length() < b.GetPs3Path().length()) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> simplify_path_blocks(const std::string& path)
|
||||
{
|
||||
std::string lower_path = path;
|
||||
std::transform(lower_path.begin(), lower_path.end(), lower_path.begin(), ::tolower);
|
||||
|
||||
std::vector<std::string> path_blocks = std::move(fmt::split(lower_path, { "/", "\\" }));
|
||||
std::vector<std::string> path_blocks = std::move(fmt::split(fmt::tolower(path), { "/", "\\" }));
|
||||
|
||||
for (size_t i = 0; i < path_blocks.size(); ++i)
|
||||
{
|
||||
@ -53,19 +39,11 @@ std::string simplify_path(const std::string& path, bool is_dir)
|
||||
|
||||
if (is_dir)
|
||||
{
|
||||
for (auto &dir : path_blocks)
|
||||
{
|
||||
result += dir + "/";
|
||||
}
|
||||
result = fmt::merge(path_blocks, "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < path_blocks.size() - 1; ++i)
|
||||
{
|
||||
result += path_blocks[i] + "/";
|
||||
}
|
||||
|
||||
result += path_blocks[path_blocks.size() - 1];
|
||||
result = fmt::merge(std::vector<std::string>(path_blocks.begin(), path_blocks.end() - 1), "/") + path_blocks[path_blocks.size() - 1];
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -76,12 +54,6 @@ VFS::~VFS()
|
||||
UnMountAll();
|
||||
}
|
||||
|
||||
std::string VFS::FindEntry(const std::string &path)
|
||||
{
|
||||
return path;
|
||||
return cwd + "/" + path;
|
||||
}
|
||||
|
||||
void VFS::Mount(const std::string& ps3_path, const std::string& local_path, vfsDevice* device)
|
||||
{
|
||||
std::string simpl_ps3_path = simplify_path(ps3_path, true);
|
||||
@ -93,10 +65,43 @@ void VFS::Mount(const std::string& ps3_path, const std::string& local_path, vfsD
|
||||
|
||||
if (m_devices.size() > 1)
|
||||
{
|
||||
//std::qsort(m_devices.GetPtr(), m_devices.GetCount(), sizeof(vfsDevice*), sort_devices);
|
||||
std::sort(m_devices.begin(), m_devices.end(), [](vfsDevice *a, vfsDevice *b) { return b->GetPs3Path().length() < a->GetPs3Path().length(); });
|
||||
}
|
||||
}
|
||||
|
||||
void VFS::Link(const std::string& mount_point, const std::string& ps3_path)
|
||||
{
|
||||
links[simplify_path_blocks(mount_point)] = simplify_path_blocks(ps3_path);
|
||||
}
|
||||
|
||||
std::string VFS::GetLinked(std::string ps3_path) const
|
||||
{
|
||||
ps3_path = fmt::tolower(ps3_path);
|
||||
auto path_blocks = fmt::split(ps3_path, { "/", "\\" });
|
||||
|
||||
for (auto link : links)
|
||||
{
|
||||
if (path_blocks.size() < link.first.size())
|
||||
continue;
|
||||
|
||||
bool is_ok = true;
|
||||
|
||||
for (size_t i = 0; i < link.first.size(); ++i)
|
||||
{
|
||||
if (link.first[i] != path_blocks[i])
|
||||
{
|
||||
is_ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_ok)
|
||||
return fmt::merge({ link.second, std::vector<std::string>(path_blocks.begin() + link.first.size(), path_blocks.end()) }, "/");
|
||||
}
|
||||
|
||||
return ps3_path;
|
||||
}
|
||||
|
||||
void VFS::UnMount(const std::string& ps3_path)
|
||||
{
|
||||
std::string simpl_ps3_path = simplify_path(ps3_path, true);
|
||||
@ -285,8 +290,9 @@ bool VFS::RenameDir(const std::string& ps3_path_from, const std::string& ps3_pat
|
||||
|
||||
vfsDevice* VFS::GetDevice(const std::string& ps3_path, std::string& path) const
|
||||
{
|
||||
auto try_get_device = [this, &path](const std::vector<std::string>& ps3_path_blocks) -> vfsDevice*
|
||||
auto try_get_device = [this, &path](const std::string& ps3_path) -> vfsDevice*
|
||||
{
|
||||
std::vector<std::string> ps3_path_blocks = simplify_path_blocks(ps3_path);
|
||||
size_t max_eq = 0;
|
||||
int max_i = -1;
|
||||
|
||||
@ -328,10 +334,10 @@ vfsDevice* VFS::GetDevice(const std::string& ps3_path, std::string& path) const
|
||||
return m_devices[max_i];
|
||||
};
|
||||
|
||||
if (auto res = try_get_device(simplify_path_blocks(ps3_path)))
|
||||
if (auto res = try_get_device(GetLinked(ps3_path)))
|
||||
return res;
|
||||
|
||||
if (auto res = try_get_device(simplify_path_blocks(cwd + ps3_path)))
|
||||
if (auto res = try_get_device(GetLinked(cwd + ps3_path)))
|
||||
return res;
|
||||
|
||||
return nullptr;
|
||||
@ -415,6 +421,8 @@ void VFS::Init(const std::string& path)
|
||||
fmt::Replace(mpath, "$(GameDir)", cwd);
|
||||
Mount(entry.mount, mpath, dev);
|
||||
}
|
||||
|
||||
Link("/app_home/", cwd);
|
||||
}
|
||||
|
||||
void VFS::SaveLoadDevices(std::vector<VFSManagerEntry>& res, bool is_load)
|
||||
@ -434,7 +442,6 @@ void VFS::SaveLoadDevices(std::vector<VFSManagerEntry>& res, bool is_load)
|
||||
res.emplace_back(vfsDevice_LocalFile, "$(EmulatorDir)/dev_flash/", "/dev_flash/");
|
||||
res.emplace_back(vfsDevice_LocalFile, "$(EmulatorDir)/dev_usb000/", "/dev_usb000/");
|
||||
res.emplace_back(vfsDevice_LocalFile, "$(EmulatorDir)/dev_usb000/", "/dev_usb/");
|
||||
res.emplace_back(vfsDevice_LocalFile, "$(GameDir)", "/app_home/");
|
||||
res.emplace_back(vfsDevice_LocalFile, "$(GameDir)/../", "/dev_bdvd/");
|
||||
res.emplace_back(vfsDevice_LocalFile, "", "/host_root/");
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
|
||||
class vfsDevice;
|
||||
struct vfsFileBase;
|
||||
@ -51,18 +52,30 @@ struct VFS
|
||||
|
||||
std::string cwd;
|
||||
|
||||
std::string FindEntry(const std::string &path);
|
||||
|
||||
//TODO: find out where these are supposed to be deleted or just make it shared_ptr
|
||||
//and also make GetDevice and GetDeviceLocal return shared_ptr then.
|
||||
// A vfsDevice will be deleted when they're unmounted or the VFS struct is destroyed.
|
||||
// This will cause problems if other code stores the pointer returned by GetDevice/GetDeviceLocal
|
||||
// and tries to use it after the device is unmounted.
|
||||
std::vector<vfsDevice *> m_devices;
|
||||
|
||||
struct links_sorter
|
||||
{
|
||||
bool operator()(const std::vector<std::string>& a, const std::vector<std::string>& b)
|
||||
{
|
||||
return b.size() < a.size();
|
||||
}
|
||||
};
|
||||
|
||||
std::map<std::vector<std::string>, std::vector<std::string>, links_sorter> links;
|
||||
|
||||
void Mount(const std::string& ps3_path, const std::string& local_path, vfsDevice* device);
|
||||
void Link(const std::string& mount_point, const std::string& ps3_path);
|
||||
void UnMount(const std::string& ps3_path);
|
||||
void UnMountAll();
|
||||
|
||||
std::string GetLinked(std::string ps3_path) const;
|
||||
|
||||
vfsFileBase* OpenFile(const std::string& ps3_path, vfsOpenMode mode) const;
|
||||
vfsDirBase* OpenDir(const std::string& ps3_path) const;
|
||||
bool CreateFile(const std::string& ps3_path) const;
|
||||
|
@ -29,7 +29,7 @@ bool vfsDir::Open(const std::string& path)
|
||||
|
||||
DirEntryInfo info;
|
||||
|
||||
m_cwd = simplify_path(0 && m_stream && m_stream->IsOpened() ? m_stream->GetPath() : path, true);
|
||||
m_cwd = simplify_path(Emu.GetVFS().GetLinked(0 && m_stream && m_stream->IsOpened() ? m_stream->GetPath() : path), true);
|
||||
|
||||
auto blocks = simplify_path_blocks(GetPath());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user