1
0
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:
DHrpcs3 2014-11-30 13:18:17 +02:00
parent ebae8dad0a
commit a58c5f5a4c
5 changed files with 94 additions and 40 deletions

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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/");

View File

@ -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;

View File

@ -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());