mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
sys_fs: Implemented get_normalized_path()
This commit is contained in:
parent
09f83e48ff
commit
cf4ae38699
@ -3,7 +3,6 @@
|
|||||||
#include "StrFmt.h"
|
#include "StrFmt.h"
|
||||||
#include "Crypto/sha1.h"
|
#include "Crypto/sha1.h"
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "Emu/system_utils.hpp"
|
#include "Emu/system_utils.hpp"
|
||||||
#include "Emu/Cell/lv2/sys_process.h"
|
#include "Emu/Cell/lv2/sys_process.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
LOG_CHANNEL(sys_fs);
|
LOG_CHANNEL(sys_fs);
|
||||||
@ -163,13 +164,14 @@ const lv2_fs_mount_info& lv2_fs_mount_info_map::lookup(std::string_view path, bo
|
|||||||
if (path.starts_with("/"sv))
|
if (path.starts_with("/"sv))
|
||||||
{
|
{
|
||||||
constexpr std::string_view cell_fs_path = "CELL_FS_PATH:"sv;
|
constexpr std::string_view cell_fs_path = "CELL_FS_PATH:"sv;
|
||||||
std::string path_dir;
|
const std::string normalized_path = lv2_fs_object::get_normalized_path(path);
|
||||||
|
std::string_view parent_dir;
|
||||||
u32 parent_level = 0;
|
u32 parent_level = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
path_dir = fs::get_parent_dir(path, parent_level++);
|
parent_dir = fs::get_parent_dir_view(normalized_path, parent_level++);
|
||||||
if (const auto iterator = map.find(path_dir); iterator != map.end())
|
if (const auto iterator = map.find(parent_dir); iterator != map.end())
|
||||||
{
|
{
|
||||||
if (iterator->second == &g_mp_sys_dev_root && parent_level > 1)
|
if (iterator->second == &g_mp_sys_dev_root && parent_level > 1)
|
||||||
break;
|
break;
|
||||||
@ -177,7 +179,7 @@ const lv2_fs_mount_info& lv2_fs_mount_info_map::lookup(std::string_view path, bo
|
|||||||
return lookup(iterator->second.device.substr(cell_fs_path.size()), no_cell_fs_path); // Recursively look up the parent mount info
|
return lookup(iterator->second.device.substr(cell_fs_path.size()), no_cell_fs_path); // Recursively look up the parent mount info
|
||||||
return iterator->second;
|
return iterator->second;
|
||||||
}
|
}
|
||||||
} while (path_dir.length() > 1); // Exit the loop when path_dir == "/" or empty
|
} while (parent_dir.length() > 1); // Exit the loop when parent_dir == "/" or empty
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_mi_sys_not_found;
|
return g_mi_sys_not_found;
|
||||||
@ -247,22 +249,34 @@ bool lv2_fs_mount_info_map::vfs_unmount(std::string_view vpath, bool remove_from
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string lv2_fs_object::get_device_root(std::string_view filename)
|
std::string lv2_fs_object::get_normalized_path(std::string_view path)
|
||||||
{
|
{
|
||||||
if (filename.starts_with("/"sv))
|
std::string normalized_path = std::filesystem::u8path(path).lexically_normal().string();
|
||||||
{
|
|
||||||
std::string path_dir;
|
|
||||||
u32 parent_level = 0;
|
|
||||||
|
|
||||||
do
|
#ifdef _WIN32
|
||||||
{
|
std::replace(normalized_path.begin(), normalized_path.end(), '\\', '/');
|
||||||
path_dir = fs::get_parent_dir(filename, parent_level++);
|
#endif
|
||||||
if (path_dir.find_last_of("/") == 0)
|
|
||||||
return path_dir;
|
if (normalized_path.ends_with('/'))
|
||||||
} while (path_dir.length() > 1); // Exit the loop when path_dir == "/" or empty
|
normalized_path.pop_back();
|
||||||
|
|
||||||
|
return normalized_path.empty() ? "/" : normalized_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view lv2_fs_object::get_device_root(std::string_view path)
|
||||||
|
{
|
||||||
|
if (const auto first = path.find_first_not_of("/"sv); first != umax)
|
||||||
|
{
|
||||||
|
if (const auto pos = path.substr(first).find_first_of("/"sv); pos != umax)
|
||||||
|
path = path.substr(0, first + pos);
|
||||||
|
path.remove_prefix(std::max<usz>(0, first - 1)); // Remove duplicate leading '/' while keeping only one
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = path.substr(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::string(filename);
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv2_fs_mount_point* lv2_fs_object::get_mp(std::string_view filename, std::string* vfs_path)
|
lv2_fs_mount_point* lv2_fs_object::get_mp(std::string_view filename, std::string* vfs_path)
|
||||||
@ -273,8 +287,8 @@ lv2_fs_mount_point* lv2_fs_object::get_mp(std::string_view filename, std::string
|
|||||||
if (is_cell_fs_path)
|
if (is_cell_fs_path)
|
||||||
filename.remove_prefix(cell_fs_path.size());
|
filename.remove_prefix(cell_fs_path.size());
|
||||||
|
|
||||||
const bool is_path = filename.starts_with('/');
|
const bool is_path = filename.starts_with("/"sv);
|
||||||
std::string mp_name = get_device_root(filename);
|
std::string mp_name = std::string(is_path ? get_device_root(filename) : filename);
|
||||||
|
|
||||||
const auto check_mp = [&]()
|
const auto check_mp = [&]()
|
||||||
{
|
{
|
||||||
@ -3115,7 +3129,7 @@ error_code sys_fs_mount(ppu_thread& ppu, vm::cptr<char> dev_name, vm::cptr<char>
|
|||||||
return {path_error, path_sv};
|
return {path_error, path_sv};
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string vpath = fs::get_parent_dir(path_sv, 0); // Just normalize the path
|
const std::string vpath = lv2_fs_object::get_normalized_path(path_sv);
|
||||||
|
|
||||||
std::string vfs_path;
|
std::string vfs_path;
|
||||||
const auto mp = lv2_fs_object::get_mp(device_name, &vfs_path);
|
const auto mp = lv2_fs_object::get_mp(device_name, &vfs_path);
|
||||||
|
@ -245,7 +245,11 @@ public:
|
|||||||
|
|
||||||
lv2_fs_object& operator=(const lv2_fs_object&) = delete;
|
lv2_fs_object& operator=(const lv2_fs_object&) = delete;
|
||||||
|
|
||||||
static std::string get_device_root(std::string_view filename);
|
// Normalize a virtual path
|
||||||
|
static std::string get_normalized_path(std::string_view path);
|
||||||
|
|
||||||
|
// Get the device's root path (e.g. "/dev_hdd0") from a given path
|
||||||
|
static std::string_view get_device_root(std::string_view path);
|
||||||
|
|
||||||
// Filename can be either a path starting with '/' or a CELL_FS device name
|
// Filename can be either a path starting with '/' or a CELL_FS device name
|
||||||
// This should be used only when handling devices that are not mounted
|
// This should be used only when handling devices that are not mounted
|
||||||
|
Loading…
Reference in New Issue
Block a user