mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01: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(),
|
return std::equal(a.begin(),
|
||||||
a.end(),
|
a.end(),
|
||||||
b.begin(),
|
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;
|
? 0 : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,4 +133,35 @@ std::vector<std::string> fmt::split(const std::string& source, std::initializer_
|
|||||||
}
|
}
|
||||||
|
|
||||||
return std::move(result);
|
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> 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::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
|
#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::vector<std::string> simplify_path_blocks(const std::string& path)
|
||||||
{
|
{
|
||||||
std::string lower_path = path;
|
std::vector<std::string> path_blocks = std::move(fmt::split(fmt::tolower(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, { "/", "\\" }));
|
|
||||||
|
|
||||||
for (size_t i = 0; i < path_blocks.size(); ++i)
|
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)
|
if (is_dir)
|
||||||
{
|
{
|
||||||
for (auto &dir : path_blocks)
|
result = fmt::merge(path_blocks, "/");
|
||||||
{
|
|
||||||
result += dir + "/";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < path_blocks.size() - 1; ++i)
|
result = fmt::merge(std::vector<std::string>(path_blocks.begin(), path_blocks.end() - 1), "/") + path_blocks[path_blocks.size() - 1];
|
||||||
{
|
|
||||||
result += path_blocks[i] + "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
result += path_blocks[path_blocks.size() - 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -76,12 +54,6 @@ VFS::~VFS()
|
|||||||
UnMountAll();
|
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)
|
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);
|
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)
|
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)
|
void VFS::UnMount(const std::string& ps3_path)
|
||||||
{
|
{
|
||||||
std::string simpl_ps3_path = simplify_path(ps3_path, true);
|
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
|
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;
|
size_t max_eq = 0;
|
||||||
int max_i = -1;
|
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];
|
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;
|
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 res;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -415,6 +421,8 @@ void VFS::Init(const std::string& path)
|
|||||||
fmt::Replace(mpath, "$(GameDir)", cwd);
|
fmt::Replace(mpath, "$(GameDir)", cwd);
|
||||||
Mount(entry.mount, mpath, dev);
|
Mount(entry.mount, mpath, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Link("/app_home/", cwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VFS::SaveLoadDevices(std::vector<VFSManagerEntry>& res, bool is_load)
|
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_flash/", "/dev_flash/");
|
||||||
res.emplace_back(vfsDevice_LocalFile, "$(EmulatorDir)/dev_usb000/", "/dev_usb000/");
|
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, "$(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, "$(GameDir)/../", "/dev_bdvd/");
|
||||||
res.emplace_back(vfsDevice_LocalFile, "", "/host_root/");
|
res.emplace_back(vfsDevice_LocalFile, "", "/host_root/");
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <map>
|
||||||
|
|
||||||
class vfsDevice;
|
class vfsDevice;
|
||||||
struct vfsFileBase;
|
struct vfsFileBase;
|
||||||
@ -51,18 +52,30 @@ struct VFS
|
|||||||
|
|
||||||
std::string cwd;
|
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
|
//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.
|
//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.
|
// 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
|
// This will cause problems if other code stores the pointer returned by GetDevice/GetDeviceLocal
|
||||||
// and tries to use it after the device is unmounted.
|
// and tries to use it after the device is unmounted.
|
||||||
std::vector<vfsDevice *> m_devices;
|
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 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 UnMount(const std::string& ps3_path);
|
||||||
void UnMountAll();
|
void UnMountAll();
|
||||||
|
|
||||||
|
std::string GetLinked(std::string ps3_path) const;
|
||||||
|
|
||||||
vfsFileBase* OpenFile(const std::string& ps3_path, vfsOpenMode mode) const;
|
vfsFileBase* OpenFile(const std::string& ps3_path, vfsOpenMode mode) const;
|
||||||
vfsDirBase* OpenDir(const std::string& ps3_path) const;
|
vfsDirBase* OpenDir(const std::string& ps3_path) const;
|
||||||
bool CreateFile(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;
|
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());
|
auto blocks = simplify_path_blocks(GetPath());
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user