From cb49db1e82fea9a66f2f2cc1ab88b80c5170cfeb Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 24 Jun 2026 05:47:53 +0200 Subject: [PATCH] Use std::string_view in File --- Utilities/File.cpp | 191 +++++++++++++++++----------- Utilities/File.h | 77 +++++------ rpcs3/Emu/System.cpp | 12 +- rpcs3/Emu/System.h | 6 +- rpcs3/Loader/ISO.cpp | 48 +++---- rpcs3/Loader/ISO.h | 42 +++--- rpcs3/Loader/content_validation.cpp | 4 +- rpcs3/Loader/content_validation.h | 2 +- rpcs3/Loader/disc.cpp | 4 +- rpcs3/Loader/disc.h | 2 +- rpcs3/Loader/mself.cpp | 14 +- rpcs3/Loader/mself.hpp | 2 +- 12 files changed, 227 insertions(+), 177 deletions(-) diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 20e25794d2..fe5d019ae8 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -218,8 +218,8 @@ namespace fs std::unordered_map> m_map{}; public: - shared_ptr get_device(const std::string& path); - shared_ptr set_device(const std::string& name, shared_ptr); + shared_ptr get_device(std::string_view path); + shared_ptr set_device(std::string_view name, shared_ptr); }; static device_manager& get_device_manager() @@ -365,43 +365,43 @@ namespace fs { } - bool device_base::remove_dir(const std::string&) + bool device_base::remove_dir(std::string_view) { g_tls_error = error::readonly; return false; } - bool device_base::create_dir(const std::string&) + bool device_base::create_dir(std::string_view) { g_tls_error = error::readonly; return false; } - bool device_base::create_symlink(const std::string&) + bool device_base::create_symlink(std::string_view) { g_tls_error = error::readonly; return false; } - bool device_base::rename(const std::string&, const std::string&) + bool device_base::rename(std::string_view, std::string_view) { g_tls_error = error::readonly; return false; } - bool device_base::remove(const std::string&) + bool device_base::remove(std::string_view) { g_tls_error = error::readonly; return false; } - bool device_base::trunc(const std::string&, u64) + bool device_base::trunc(std::string_view, u64) { g_tls_error = error::readonly; return false; } - bool device_base::utime(const std::string&, s64, s64) + bool device_base::utime(std::string_view, s64, s64) { g_tls_error = error::readonly; return false; @@ -811,13 +811,14 @@ namespace fs #endif } -shared_ptr fs::device_manager::get_device(const std::string& path) +shared_ptr fs::device_manager::get_device(std::string_view path) { reader_lock lock(m_mutex); const usz prefix = path.find_first_of('_', 7) + 1; + const std::string suffix(path.substr(prefix, path.find_first_of('/', 1) - prefix)); - const auto found = m_map.find(path.substr(prefix, path.find_first_of('/', 1) - prefix)); + const auto found = m_map.find(suffix); if (found == m_map.end() || !path.starts_with(found->second->fs_prefix)) { @@ -827,14 +828,15 @@ shared_ptr fs::device_manager::get_device(const std::string& pa return found->second; } -shared_ptr fs::device_manager::set_device(const std::string& name, shared_ptr device) +shared_ptr fs::device_manager::set_device(std::string_view name, shared_ptr device) { + const std::string sname(name); std::lock_guard lock(m_mutex); if (device) { // Adding - if (auto [it, ok] = m_map.try_emplace(name, std::move(device)); ok) + if (auto [it, ok] = m_map.try_emplace(sname, std::move(device)); ok) { return it->second; } @@ -844,7 +846,7 @@ shared_ptr fs::device_manager::set_device(const std::string& na else { // Removing - if (auto found = m_map.find(name); found != m_map.end()) + if (auto found = m_map.find(sname); found != m_map.end()) { device = std::move(found->second); m_map.erase(found); @@ -857,10 +859,10 @@ shared_ptr fs::device_manager::set_device(const std::string& na return null_ptr; } -shared_ptr fs::get_virtual_device(const std::string& path) +shared_ptr fs::get_virtual_device(std::string_view path) { // Every virtual device path must have specific name at the beginning - if (path.starts_with("/vfsv0_") && path.size() >= 8 + 22 && path[29] == '_' && path.find_first_of('/', 1) > 29) + if (path.size() >= 30 && path.starts_with("/vfsv0_") && path[29] == '_' && path.find_first_of('/', 1) > 29) { return get_device_manager().get_device(path); } @@ -868,7 +870,7 @@ shared_ptr fs::get_virtual_device(const std::string& path) return null_ptr; } -shared_ptr fs::set_virtual_device(const std::string& name, shared_ptr device) +shared_ptr fs::set_virtual_device(std::string_view name, shared_ptr device) { return get_device_manager().set_device(name, std::move(device)); } @@ -924,7 +926,7 @@ std::string_view fs::get_parent_dir_view(std::string_view path, u32 parent_level return result; } -std::string fs::get_path_if_dir(const std::string& path) +std::string fs::get_path_if_dir(std::string_view path) { if (path.empty() || !fs::is_dir(path)) { @@ -934,38 +936,42 @@ std::string fs::get_path_if_dir(const std::string& path) // If delimiters are already present at the end of the string then nothing else to do if (usz sz = path.find_last_of(delim); sz != umax && (sz + 1) == path.size()) { - return path; + return std::string(path); } - return path + '/'; + return fmt::format("%s/", path); } -bool fs::get_stat(const std::string& path, stat_t& info) +bool fs::get_stat(std::string_view path, stat_t& info) { // Ensure consistent information on failure info = {}; + if (path.empty()) + { + g_tls_error = fs::error::noent; + return false; + } + if (auto device = get_virtual_device(path)) { return device->stat(path, info); } #ifdef _WIN32 - std::string_view epath = path; - // '/' and '\\' Not allowed by FindFirstFileExW at the end of path but we should allow it - if (auto not_del = epath.find_last_not_of(delim); not_del != umax && not_del != epath.size() - 1) + if (auto not_del = path.find_last_not_of(delim); not_del != umax && not_del != path.size() - 1) { - epath.remove_suffix(epath.size() - 1 - not_del); + path.remove_suffix(path.size() - 1 - not_del); } // Handle drives specially - if (epath.find_first_of(delim) == umax && epath.ends_with(':')) + if (path.find_first_of(delim) == umax && path.ends_with(':')) { WIN32_FILE_ATTRIBUTE_DATA attrs{}; // Must end with a delimiter - if (!GetFileAttributesExW(to_wchar(std::string(epath) + '/').get(), GetFileExInfoStandard, &attrs)) + if (!GetFileAttributesExW(to_wchar(std::string(path) + '/').get(), GetFileExInfoStandard, &attrs)) { g_tls_error = to_error(GetLastError()); return false; @@ -985,7 +991,7 @@ bool fs::get_stat(const std::string& path, stat_t& info) } // Allowed by FindFirstFileExW but we should not allow it - if (epath.ends_with("*")) + if (path.ends_with("*")) { g_tls_error = fs::error::noent; return false; @@ -993,7 +999,7 @@ bool fs::get_stat(const std::string& path, stat_t& info) WIN32_FIND_DATA attrs{}; - const auto wchar_ptr = to_wchar(std::string(epath)); + const auto wchar_ptr = to_wchar(path); const std::wstring_view wpath_view = wchar_ptr.get(); const HANDLE handle = FindFirstFileExW(wpath_view.data(), FindExInfoStandard, &attrs, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_CASE_SENSITIVE); @@ -1034,7 +1040,7 @@ bool fs::get_stat(const std::string& path, stat_t& info) info.ctime = info.mtime; #else struct ::stat file_info; - if (::stat(path.c_str(), &file_info) != 0) + if (::stat(path.data(), &file_info) != 0) { g_tls_error = to_error(errno); return false; @@ -1055,13 +1061,13 @@ bool fs::get_stat(const std::string& path, stat_t& info) return true; } -bool fs::exists(const std::string& path) +bool fs::exists(std::string_view path) { fs::stat_t info{}; return fs::get_stat(path, info); } -bool fs::is_file(const std::string& path) +bool fs::is_file(std::string_view path) { fs::stat_t info{}; if (!fs::get_stat(path, info)) @@ -1078,7 +1084,7 @@ bool fs::is_file(const std::string& path) return true; } -bool fs::is_dir(const std::string& path) +bool fs::is_dir(std::string_view path) { fs::stat_t info{}; if (!fs::get_stat(path, info)) @@ -1095,7 +1101,7 @@ bool fs::is_dir(const std::string& path) return true; } -bool fs::is_symlink(const std::string& path) +bool fs::is_symlink(std::string_view path) { fs::stat_t info{}; if (!fs::get_stat(path, info)) @@ -1112,7 +1118,7 @@ bool fs::is_symlink(const std::string& path) return true; } -bool fs::is_optical_raw_device([[maybe_unused]] const std::string& path) +bool fs::is_optical_raw_device([[maybe_unused]] std::string_view path) { #ifdef _WIN32 if (path.starts_with("\\\\.\\")) @@ -1123,7 +1129,7 @@ bool fs::is_optical_raw_device([[maybe_unused]] const std::string& path) return false; } -bool fs::get_optical_raw_device(const std::string& path, std::string* raw_device) +bool fs::get_optical_raw_device(std::string_view path, std::string* raw_device) { if (fs::is_optical_raw_device(path)) { @@ -1145,7 +1151,7 @@ bool fs::get_optical_raw_device(const std::string& path, std::string* raw_device return false; } - const std::string drive_letter = path.substr(0, drive_delim_pos + 1); // e.g. "E:" + const std::string drive_letter(path.substr(0, drive_delim_pos + 1)); // e.g. "E:" const std::string drive_path = drive_letter + "\\"; // e.g. "E:\" if (GetDriveTypeA(drive_path.c_str()) == DRIVE_CDROM) @@ -1161,8 +1167,14 @@ bool fs::get_optical_raw_device(const std::string& path, std::string* raw_device return false; } -bool fs::statfs(const std::string& path, fs::device_stat& info) +bool fs::statfs(std::string_view path, fs::device_stat& info) { + if (path.empty()) + { + g_tls_error = fs::error::noent; + return false; + } + if (auto device = get_virtual_device(path)) { return device->statfs(path, info); @@ -1205,7 +1217,7 @@ bool fs::statfs(const std::string& path, fs::device_stat& info) info.avail_free = avail_free.QuadPart; #else struct ::statvfs buf; - if (::statvfs(path.c_str(), &buf) != 0) + if (::statvfs(path.data(), &buf) != 0) { g_tls_error = to_error(errno); return false; @@ -1220,8 +1232,14 @@ bool fs::statfs(const std::string& path, fs::device_stat& info) return true; } -bool fs::create_dir(const std::string& path) +bool fs::create_dir(std::string_view path) { + if (path.empty()) + { + g_tls_error = fs::error::noent; + return false; + } + if (auto device = get_virtual_device(path)) { return device->create_dir(path); @@ -1244,7 +1262,7 @@ bool fs::create_dir(const std::string& path) return true; #else - if (::mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) + if (::mkdir(path.data(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) { g_tls_error = to_error(errno); return false; @@ -1254,7 +1272,7 @@ bool fs::create_dir(const std::string& path) #endif } -bool fs::create_path(const std::string& path) +bool fs::create_path(std::string_view path) { const std::string parent = get_parent_dir(path); @@ -1276,7 +1294,7 @@ bool fs::create_path(const std::string& path) return true; } -bool fs::remove_dir(const std::string& path) +bool fs::remove_dir(std::string_view path) { if (path.empty()) { @@ -1297,7 +1315,7 @@ bool fs::remove_dir(const std::string& path) return false; } #else - if (::rmdir(path.c_str()) != 0) + if (::rmdir(path.data()) != 0) { g_tls_error = to_error(errno); return false; @@ -1307,8 +1325,14 @@ bool fs::remove_dir(const std::string& path) return true; } -bool fs::create_symlink(const std::string& path, const std::string& target) +bool fs::create_symlink(std::string_view path, std::string_view target) { + if (path.empty() || target.empty()) + { + g_tls_error = fs::error::noent; + return false; + } + if (auto device = get_virtual_device(path)) { return device->create_symlink(path); @@ -1324,7 +1348,7 @@ bool fs::create_symlink(const std::string& path, const std::string& target) return true; #else - if (::symlink(target.c_str(), path.c_str()) != 0) + if (::symlink(target.data(), path.data()) != 0) { g_tls_error = to_error(errno); return false; @@ -1334,7 +1358,7 @@ bool fs::create_symlink(const std::string& path, const std::string& target) #endif } -bool fs::rename(const std::string& from, const std::string& to, bool overwrite) +bool fs::rename(std::string_view from, std::string_view to, bool overwrite) { if (from.empty() || to.empty()) { @@ -1389,7 +1413,7 @@ bool fs::rename(const std::string& from, const std::string& to, bool overwrite) #else #ifdef __linux__ - if (syscall(SYS_renameat2, AT_FDCWD, from.c_str(), AT_FDCWD, to.c_str(), overwrite ? 0 : 1 /* RENAME_NOREPLACE */) == 0) + if (syscall(SYS_renameat2, AT_FDCWD, from.data(), AT_FDCWD, to.data(), overwrite ? 0 : 1 /* RENAME_NOREPLACE */) == 0) { return true; } @@ -1408,7 +1432,7 @@ bool fs::rename(const std::string& from, const std::string& to, bool overwrite) return false; } - if (::rename(from.c_str(), to.c_str()) != 0) + if (::rename(from.data(), to.data()) != 0) { g_tls_error = to_error(errno); return false; @@ -1418,8 +1442,14 @@ bool fs::rename(const std::string& from, const std::string& to, bool overwrite) #endif } -bool fs::copy_file(const std::string& from, const std::string& to, bool overwrite) +bool fs::copy_file(std::string_view from, std::string_view to, bool overwrite) { + if (from.empty() || to.empty()) + { + g_tls_error = fs::error::noent; + return false; + } + const auto device = get_virtual_device(from); if (device != get_virtual_device(to) || device) // TODO @@ -1438,14 +1468,14 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit #elif defined(__APPLE__) || defined(__linux__) || defined(__sun) /* Source: http://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c */ - const int input = ::open(from.c_str(), O_RDONLY); + const int input = ::open(from.data(), O_RDONLY); if (input == -1) { g_tls_error = to_error(errno); return false; } - const int output = ::open(to.c_str(), O_WRONLY | O_CREAT | (overwrite ? O_TRUNC : O_EXCL), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + const int output = ::open(to.data(), O_WRONLY | O_CREAT | (overwrite ? O_TRUNC : O_EXCL), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (output == -1) { const int err = errno; @@ -1518,8 +1548,14 @@ bool fs::copy_file(const std::string& from, const std::string& to, bool overwrit #endif } -bool fs::remove_file(const std::string& path) +bool fs::remove_file(std::string_view path) { + if (path.empty()) + { + g_tls_error = fs::error::noent; + return false; + } + if (auto device = get_virtual_device(path)) { return device->remove(path); @@ -1534,7 +1570,7 @@ bool fs::remove_file(const std::string& path) return true; #else - if (::unlink(path.c_str()) != 0) + if (::unlink(path.data()) != 0) { g_tls_error = to_error(errno); return false; @@ -1544,8 +1580,14 @@ bool fs::remove_file(const std::string& path) #endif } -bool fs::truncate_file(const std::string& path, u64 length) +bool fs::truncate_file(std::string_view path, u64 length) { + if (path.empty()) + { + g_tls_error = fs::error::noent; + return false; + } + if (auto device = get_virtual_device(path)) { return device->trunc(path, length); @@ -1573,7 +1615,7 @@ bool fs::truncate_file(const std::string& path, u64 length) CloseHandle(handle); return true; #else - if (::truncate(path.c_str(), length) != 0) + if (::truncate(path.data(), length) != 0) { g_tls_error = to_error(errno); return false; @@ -1583,8 +1625,14 @@ bool fs::truncate_file(const std::string& path, u64 length) #endif } -bool fs::utime(const std::string& path, s64 atime, s64 mtime) +bool fs::utime(std::string_view path, s64 atime, s64 mtime) { + if (path.empty()) + { + g_tls_error = fs::error::noent; + return false; + } + if (auto device = get_virtual_device(path)) { return device->utime(path, atime, mtime); @@ -1631,7 +1679,7 @@ bool fs::utime(const std::string& path, s64 atime, s64 mtime) buf.actime = atime; buf.modtime = mtime; - if (::utime(path.c_str(), &buf) != 0) + if (::utime(path.data(), &buf) != 0) { g_tls_error = to_error(errno); return false; @@ -1666,7 +1714,7 @@ void fs::sync() fmt::throw_exception("Stream overflow."); } -fs::file::file(const std::string& path, bs_t mode) +fs::file::file(std::string_view path, bs_t mode) { if (path.empty()) { @@ -1809,14 +1857,14 @@ fs::file::file(const std::string& path, bs_t mode) // Alternative to truncation for "unread" flag (TODO) if (mode & fs::create) { - ::unlink(path.c_str()); + ::unlink(path.data()); } } perm = 0; } - const int fd = ::open(path.c_str(), flags, perm); + const int fd = ::open(path.data(), flags, perm); if (fd == -1) { @@ -1847,8 +1895,6 @@ fs::file::file(const std::string& path, bs_t mode) #endif } - - fs::file fs::file::from_native_handle(native_handle handle) { fs::file result; @@ -1973,7 +2019,7 @@ fs::file_id fs::file::get_id() const return {}; } -bool fs::dir::open(const std::string& path) +bool fs::dir::open(std::string_view path) { m_dir.reset(); @@ -1997,7 +2043,7 @@ bool fs::dir::open(const std::string& path) #ifdef _WIN32 WIN32_FIND_DATAW found; - const auto handle = FindFirstFileExW(to_wchar(path + "/*").get(), FindExInfoBasic, &found, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_CASE_SENSITIVE | FIND_FIRST_EX_LARGE_FETCH); + const auto handle = FindFirstFileExW(to_wchar(fmt::format("%s/*", path)).get(), FindExInfoBasic, &found, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_CASE_SENSITIVE | FIND_FIRST_EX_LARGE_FETCH); if (handle == INVALID_HANDLE_VALUE) { @@ -2061,7 +2107,7 @@ bool fs::dir::open(const std::string& path) m_dir = std::make_unique(handle, found); #else - ::DIR* const ptr = ::opendir(path.c_str()); + ::DIR* const ptr = ::opendir(path.data()); if (!ptr) { @@ -2403,7 +2449,7 @@ const std::string& fs::get_temp_dir() return s_dir; } -bool fs::remove_all(const std::string& path, bool remove_root, bool is_no_dir_ok) +bool fs::remove_all(std::string_view path, bool remove_root, bool is_no_dir_ok) { if (const auto root_dir = dir(path)) { @@ -2443,7 +2489,7 @@ bool fs::remove_all(const std::string& path, bool remove_root, bool is_no_dir_ok return true; } -u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment, atomic_t* cancel_flag) +u64 fs::get_dir_size(std::string_view path, u64 rounding_alignment, atomic_t* cancel_flag) { u64 result = 0; @@ -2758,10 +2804,11 @@ bool fs::pending_file::commit(bool overwrite) while (true) { - if (link_name_buffer.c_str() != ws1_sv) + // Note: link_name_buffer is a buffer which may contain zeroes so truncate it + if (std::wstring link_name_buffer_trunc = link_name_buffer.c_str(); + link_name_buffer_trunc != ws1_sv) { - // Note: link_name_buffer is a buffer which may contain zeroes so truncate it - hardlink_paths.push_back(link_name_buffer.c_str()); + hardlink_paths.push_back(std::move(link_name_buffer_trunc)); } buffer_size = static_cast(link_name_buffer.size() - 1); @@ -2857,7 +2904,7 @@ bool fs::pending_file::commit(bool overwrite) return false; } -stx::generator fs::list_dir_recursively(const std::string& path) +stx::generator fs::list_dir_recursively(std::string_view path) { for (auto& entry : fs::dir(path)) { diff --git a/Utilities/File.h b/Utilities/File.h index 778bfacd48..87488b62b1 100644 --- a/Utilities/File.h +++ b/Utilities/File.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -160,18 +161,18 @@ namespace fs device_base(); virtual ~device_base(); - virtual bool stat(const std::string& path, stat_t& info) = 0; - virtual bool statfs(const std::string& path, device_stat& info) = 0; - virtual bool remove_dir(const std::string& path); - virtual bool create_dir(const std::string& path); - virtual bool create_symlink(const std::string& path); - virtual bool rename(const std::string& from, const std::string& to); - virtual bool remove(const std::string& path); - virtual bool trunc(const std::string& path, u64 length); - virtual bool utime(const std::string& path, s64 atime, s64 mtime); + virtual bool stat(std::string_view path, stat_t& info) = 0; + virtual bool statfs(std::string_view path, device_stat& info) = 0; + virtual bool remove_dir(std::string_view path); + virtual bool create_dir(std::string_view path); + virtual bool create_symlink(std::string_view path); + virtual bool rename(std::string_view from, std::string_view to); + virtual bool remove(std::string_view path); + virtual bool trunc(std::string_view path, u64 length); + virtual bool utime(std::string_view path, s64 atime, s64 mtime); - virtual std::unique_ptr open(const std::string& path, bs_t mode) = 0; - virtual std::unique_ptr open_dir(const std::string& path) = 0; + virtual std::unique_ptr open(std::string_view path, bs_t mode) = 0; + virtual std::unique_ptr open_dir(std::string_view path) = 0; }; [[noreturn]] void xnull(std::source_location); @@ -181,10 +182,10 @@ namespace fs constexpr struct pod_tag_t{} pod_tag; // Get virtual device for specified path (nullptr for real path) - shared_ptr get_virtual_device(const std::string& path); + shared_ptr get_virtual_device(std::string_view path); // Set virtual device with specified name (nullptr for deletion) - shared_ptr set_virtual_device(const std::string& name, shared_ptr device); + shared_ptr set_virtual_device(std::string_view name, shared_ptr device); // Try to get parent directory std::string_view get_parent_dir_view(std::string_view path, u32 parent_level = 1); @@ -196,58 +197,58 @@ namespace fs } // Return "path" plus an ending delimiter (if missing) if "path" is an existing directory. Otherwise, an empty string - std::string get_path_if_dir(const std::string& path); + std::string get_path_if_dir(std::string_view path); // Get file information - bool get_stat(const std::string& path, stat_t& info); + bool get_stat(std::string_view path, stat_t& info); // Check whether a file or a directory exists (not recommended, use is_file() or is_dir() instead) - bool exists(const std::string& path); + bool exists(std::string_view path); // Check whether the file exists and is NOT a directory - bool is_file(const std::string& path); + bool is_file(std::string_view path); // Check whether the directory exists and is NOT a file - bool is_dir(const std::string& path); + bool is_dir(std::string_view path); // Check whether the path points to an existing symlink - bool is_symlink(const std::string& path); + bool is_symlink(std::string_view path); // Check whether the path points to a raw device - bool is_optical_raw_device(const std::string& path); + bool is_optical_raw_device(std::string_view path); // Check whether the path points to an optical drive. If so, provide the raw device in "raw_device" if requested - bool get_optical_raw_device(const std::string& path, std::string* raw_device = nullptr); + bool get_optical_raw_device(std::string_view path, std::string* raw_device = nullptr); // Get filesystem information - bool statfs(const std::string& path, device_stat& info); + bool statfs(std::string_view path, device_stat& info); // Delete empty directory - bool remove_dir(const std::string& path); + bool remove_dir(std::string_view path); // Create directory - bool create_dir(const std::string& path); + bool create_dir(std::string_view path); // Create directories - bool create_path(const std::string& path); + bool create_path(std::string_view path); // Create symbolic link - bool create_symlink(const std::string& path, const std::string& target); + bool create_symlink(std::string_view path, std::string_view target); // Rename (move) file or directory - bool rename(const std::string& from, const std::string& to, bool overwrite); + bool rename(std::string_view from, std::string_view to, bool overwrite); // Copy file contents - bool copy_file(const std::string& from, const std::string& to, bool overwrite); + bool copy_file(std::string_view from, std::string_view to, bool overwrite); // Delete file - bool remove_file(const std::string& path); + bool remove_file(std::string_view path); // Change file size (possibly appending zeros) - bool truncate_file(const std::string& path, u64 length); + bool truncate_file(std::string_view path, u64 length); // Set file access/modification time - bool utime(const std::string& path, s64 atime, s64 mtime); + bool utime(std::string_view path, s64 atime, s64 mtime); // Synchronize filesystems (TODO) void sync(); @@ -261,7 +262,7 @@ namespace fs file() = default; // Open file with specified mode - explicit file(const std::string& path, bs_t mode = ::fs::read); + explicit file(std::string_view path, bs_t mode = ::fs::read); file(std::unique_ptr&& ptr) : m_file(std::move(ptr)) {} @@ -504,13 +505,13 @@ namespace fs dir() = default; // Open dir handle - explicit dir(const std::string& path) noexcept + explicit dir(std::string_view path) noexcept { open(path); } // Open specified directory - bool open(const std::string& path); + bool open(std::string_view path); // Check whether the handle is valid (opened directory) explicit operator bool() const noexcept @@ -673,10 +674,10 @@ namespace fs }; // Delete directory and all its contents recursively - bool remove_all(const std::string& path, bool remove_root = true, bool is_no_dir_ok = false); + bool remove_all(std::string_view path, bool remove_root = true, bool is_no_dir_ok = false); // Get size of all files recursively - u64 get_dir_size(const std::string& path, u64 rounding_alignment = 1, atomic_t* cancel_flag = nullptr); + u64 get_dir_size(std::string_view path, u64 rounding_alignment = 1, atomic_t* cancel_flag = nullptr); enum class error : uint { @@ -848,7 +849,7 @@ namespace fs } template - bool write_file(const std::string& path, bs_t mode, const Args&... args) + bool write_file(std::string_view path, bs_t mode, const Args&... args) { // Always use write flag, remove read flag if (fs::file f{path, mode + fs::write - fs::read}) @@ -877,5 +878,5 @@ namespace fs file make_gather(std::vector); - stx::generator list_dir_recursively(const std::string& path); + stx::generator list_dir_recursively(std::string_view path); } diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 8f36b9a899..90c66e6ff4 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -426,7 +426,7 @@ void Emulator::Init() jit_runtime::initialize(); const std::string emu_dir = rpcs3::utils::get_emu_dir(); - auto make_path_verbose = [&](const std::string& path, bool must_exist_outside_emu_dir) + auto make_path_verbose = [&](std::string_view path, bool must_exist_outside_emu_dir) { if (fs::is_dir(path)) { @@ -937,7 +937,7 @@ bool Emulator::BootRsxCapture(const std::string& path) return true; } -game_boot_result Emulator::GetElfPathFromDir(std::string& elf_path, const std::string& path) +game_boot_result Emulator::GetElfPathFromDir(std::string& elf_path, std::string_view path) { if (!fs::is_dir(path)) { @@ -954,7 +954,7 @@ game_boot_result Emulator::GetElfPathFromDir(std::string& elf_path, const std::s for (std::string elf : boot_list) { - elf = path + elf; + elf = fmt::format("%s%s", path, elf); if (fs::is_file(elf)) { @@ -4665,7 +4665,7 @@ const std::string Emulator::GetSfoDir(bool prefer_disc_sfo) const return m_sfo_dir; } -void Emulator::GetBdvdDir(std::string& bdvd_dir, std::string& sfb_dir, std::string& game_dir, const std::string& elf_dir) +void Emulator::GetBdvdDir(std::string& bdvd_dir, std::string& sfb_dir, std::string& game_dir, std::string_view elf_dir) { // Find disc directory by searching a valid PS3_DISC.SFB closest to root directory std::string main_dir; @@ -4673,7 +4673,7 @@ void Emulator::GetBdvdDir(std::string& bdvd_dir, std::string& sfb_dir, std::stri std::string parent_dir; - for (std::string search_dir = elf_dir.substr(0, elf_dir.find_last_not_of(fs::delim) + 1);; search_dir = std::move(parent_dir)) + for (std::string search_dir = std::string(elf_dir.substr(0, elf_dir.find_last_not_of(fs::delim) + 1));; search_dir = std::move(parent_dir)) { parent_dir = fs::get_parent_dir(search_dir); @@ -4831,7 +4831,7 @@ bool Emulator::IsVsh() return g_ps3_process_info.self_info.valid && (g_ps3_process_info.self_info.prog_id_hdr.program_authority_id >> 36 == 0x1070000); // Not only VSH but also most CoreOS LV2 SELFs need the special treatment } -bool Emulator::IsValidSfb(const std::string& path) +bool Emulator::IsValidSfb(std::string_view path) { fs::file sfb_file{path, fs::read + fs::isfile}; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 9a9b00c865..0f6fe50c8a 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -503,12 +503,12 @@ public: void EjectDisc(); game_boot_result InsertDisc(const std::string& path); - static game_boot_result GetElfPathFromDir(std::string& elf_path, const std::string& path); - static void GetBdvdDir(std::string& bdvd_dir, std::string& sfb_dir, std::string& game_dir, const std::string& elf_dir); + static game_boot_result GetElfPathFromDir(std::string& elf_path, std::string_view path); + static void GetBdvdDir(std::string& bdvd_dir, std::string& sfb_dir, std::string& game_dir, std::string_view elf_dir); friend void init_fxo_for_exec(utils::serial*, bool); static bool IsVsh(); - static bool IsValidSfb(const std::string& path); + static bool IsValidSfb(std::string_view path); static void SaveSettings(std::string_view settings, const std::string& title_id); }; diff --git a/rpcs3/Loader/ISO.cpp b/rpcs3/Loader/ISO.cpp index 4bd2050638..8938d8da7e 100644 --- a/rpcs3/Loader/ISO.cpp +++ b/rpcs3/Loader/ISO.cpp @@ -75,14 +75,14 @@ static bool is_iso_file(iso_file& file, u64* size = nullptr) return ret; } -bool is_iso_file(const std::string& path, u64* size, bool* is_raw_device) +bool is_iso_file(std::string_view path, u64* size, bool* is_raw_device) { if (path.empty()) { return false; } - std::string new_path = path; + std::string new_path(path); // "new_path" is updated with the raw device path in case "path" points to a BD drive const bool raw_device = fs::get_optical_raw_device(path, &new_path); @@ -203,7 +203,7 @@ static bool decrypt_data(aes_context& aes, u64 offset, const unsigned char* buff return true; } -iso_type_status iso_file_decryption::get_key(const std::string& key_path, aes_context* aes_ctx) +iso_type_status iso_file_decryption::get_key(std::string_view key_path, aes_context* aes_ctx) { fs::file key_file(key_path); @@ -344,7 +344,7 @@ iso_type_status iso_file_decryption::retrieve_key(iso_archive& archive, std::str return iso_type_status::ERROR_OPENING_KEY; } -iso_type_status iso_file_decryption::check_type(const std::string& path, std::string* key_path, aes_context* aes_ctx) +iso_type_status iso_file_decryption::check_type(std::string_view path, std::string* key_path, aes_context* aes_ctx) { if (!is_iso_file(path)) { @@ -353,7 +353,7 @@ iso_type_status iso_file_decryption::check_type(const std::string& path, std::st // Remove file extension from file path const usz ext_pos = path.rfind('.'); - const std::string name_path = ext_pos == umax ? path : path.substr(0, ext_pos); + const std::string name_path(ext_pos == umax ? path : path.substr(0, ext_pos)); // Detect file name (with no parent folder and no file extension) const usz name_pos = name_path.rfind('/'); @@ -382,7 +382,7 @@ iso_type_status iso_file_decryption::check_type(const std::string& path, std::st return iso_type_status::ERROR_OPENING_KEY; } -bool iso_file_decryption::init(const std::string& path, iso_archive* archive) +bool iso_file_decryption::init(std::string_view path, iso_archive* archive) { // Reset attributes first m_enc_type = iso_encryption_type::NONE; @@ -547,7 +547,7 @@ bool iso_file_decryption::init(const std::string& path, iso_archive* archive) return true; } -bool iso_file_decryption::decrypt(u64 offset, void* buffer, u64 size, const std::string& name) +bool iso_file_decryption::decrypt(u64 offset, void* buffer, u64 size, std::string_view name) { // If it's a non-encrypted type, nothing more to do if (m_enc_type == iso_encryption_type::NONE) @@ -602,7 +602,7 @@ bool iso_file_decryption::decrypt(u64 offset, void* buffer, u64 size, const std: return true; } -iso_file_encrypted::iso_file_encrypted(const std::string& path, bs_t mode, const iso_fs_node& node, std::shared_ptr dec) +iso_file_encrypted::iso_file_encrypted(std::string_view path, bs_t mode, const iso_fs_node& node, std::shared_ptr dec) : iso_file(path, mode, node), m_dec(dec) { } @@ -909,7 +909,7 @@ static std::optional iso_read_directory_entry(fs::file& entry, }; } -static void iso_form_hierarchy(fs::file& file, iso_fs_node& node, bool use_ucs2_decoding = false, const std::string& parent_path = "") +static void iso_form_hierarchy(fs::file& file, iso_fs_node& node, bool use_ucs2_decoding = false, std::string_view parent_path = ""sv) { if (!node.metadata.is_directory) { @@ -973,7 +973,7 @@ static void iso_form_hierarchy(fs::file& file, iso_fs_node& node, bool use_ucs2_ { if (child_node->metadata.name != "." && child_node->metadata.name != "..") { - iso_form_hierarchy(file, *child_node, use_ucs2_decoding, parent_path + "/" + node.metadata.name); + iso_form_hierarchy(file, *child_node, use_ucs2_decoding, fmt::format("%s/%s", parent_path, node.metadata.name)); } } } @@ -990,7 +990,7 @@ u64 iso_fs_metadata::size() const return total_size; } -iso_archive::iso_archive(const std::string& path) +iso_archive::iso_archive(std::string_view path) { m_path = path; @@ -1050,7 +1050,7 @@ iso_archive::iso_archive(const std::string& path) } } -iso_fs_node* iso_archive::retrieve(const std::string& passed_path) +iso_fs_node* iso_archive::retrieve(std::string_view passed_path) { if (passed_path.empty()) { @@ -1127,12 +1127,12 @@ iso_fs_node* iso_archive::retrieve(const std::string& passed_path) return search_stack.top(); } -bool iso_archive::exists(const std::string& path) +bool iso_archive::exists(std::string_view path) { return retrieve(path) != nullptr; } -bool iso_archive::is_file(const std::string& path) +bool iso_archive::is_file(std::string_view path) { const auto file_node = retrieve(path); @@ -1144,7 +1144,7 @@ bool iso_archive::is_file(const std::string& path) return !file_node->metadata.is_directory; } -std::unique_ptr iso_archive::get_iso_file(const std::string& path, bs_t mode, const iso_fs_node& node) +std::unique_ptr iso_archive::get_iso_file(std::string_view path, bs_t mode, const iso_fs_node& node) { if (m_dec->get_enc_type() == iso_encryption_type::NONE) { @@ -1154,12 +1154,12 @@ std::unique_ptr iso_archive::get_iso_file(const std::string& path return std::make_unique(path, mode, node, m_dec); } -std::unique_ptr iso_archive::open(const std::string& path) +std::unique_ptr iso_archive::open(std::string_view path) { return get_iso_file(m_path, fs::read, *ensure(retrieve(path))); } -psf::registry iso_archive::open_psf(const std::string& path) +psf::registry iso_archive::open_psf(std::string_view path) { const auto node = retrieve(path); @@ -1173,7 +1173,7 @@ psf::registry iso_archive::open_psf(const std::string& path) return psf::load_object(psf_file, path); } -iso_file::iso_file(const std::string& path, bs_t mode) +iso_file::iso_file(std::string_view path, bs_t mode) { m_file = fs::file(path, mode); @@ -1192,7 +1192,7 @@ iso_file::iso_file(const std::string& path, bs_t mode) m_raw_device = fs::is_optical_raw_device(path); } -iso_file::iso_file(const std::string& path, bs_t mode, const iso_fs_node& node) +iso_file::iso_file(std::string_view path, bs_t mode, const iso_fs_node& node) : m_meta(node.metadata) { m_file = fs::file(path, mode); @@ -1490,7 +1490,7 @@ void iso_dir::rewind() m_pos = 0; } -bool iso_device::stat(const std::string& path, fs::stat_t& info) +bool iso_device::stat(std::string_view path, fs::stat_t& info) { const auto relative_path = std::filesystem::relative(std::filesystem::path(path), std::filesystem::path(fs_prefix)).string(); @@ -1518,7 +1518,7 @@ bool iso_device::stat(const std::string& path, fs::stat_t& info) return true; } -bool iso_device::statfs(const std::string& path, fs::device_stat& info) +bool iso_device::statfs(std::string_view path, fs::device_stat& info) { const auto relative_path = std::filesystem::relative(std::filesystem::path(path), std::filesystem::path(fs_prefix)).string(); @@ -1543,7 +1543,7 @@ bool iso_device::statfs(const std::string& path, fs::device_stat& info) return true; } -std::unique_ptr iso_device::open(const std::string& path, bs_t mode) +std::unique_ptr iso_device::open(std::string_view path, bs_t mode) { const auto relative_path = std::filesystem::relative(std::filesystem::path(path), std::filesystem::path(fs_prefix)).string(); @@ -1564,7 +1564,7 @@ std::unique_ptr iso_device::open(const std::string& path, bs_t iso_device::open_dir(const std::string& path) +std::unique_ptr iso_device::open_dir(std::string_view path) { const auto relative_path = std::filesystem::relative(std::filesystem::path(path), std::filesystem::path(fs_prefix)).string(); @@ -1586,7 +1586,7 @@ std::unique_ptr iso_device::open_dir(const std::string& path) return std::make_unique(*node); } -void load_iso(const std::string& path) +void load_iso(std::string_view path) { sys_log.notice("Loading ISO '%s'", path); diff --git a/rpcs3/Loader/ISO.h b/rpcs3/Loader/ISO.h index 0caf53f6a9..52a2300c83 100644 --- a/rpcs3/Loader/ISO.h +++ b/rpcs3/Loader/ISO.h @@ -6,9 +6,9 @@ #include "util/types.hpp" #include "Crypto/aes.h" -bool is_iso_file(const std::string& path, u64* size = nullptr, bool* is_raw_device = nullptr); +bool is_iso_file(std::string_view path, u64* size = nullptr, bool* is_raw_device = nullptr); -void load_iso(const std::string& path); +void load_iso(std::string_view path); void unload_iso(); constexpr u64 ISO_SECTOR_SIZE = 2048; @@ -67,16 +67,16 @@ private: iso_encryption_type m_enc_type = iso_encryption_type::NONE; std::vector m_region_info; - static iso_type_status get_key(const std::string& key_path, aes_context* aes_ctx = nullptr); + static iso_type_status get_key(std::string_view key_path, aes_context* aes_ctx = nullptr); static iso_type_status retrieve_key(iso_archive& archive, std::string& key_path, aes_context& aes_ctx); public: - static iso_type_status check_type(const std::string& path, std::string* key_path = nullptr, aes_context* aes_ctx = nullptr); + static iso_type_status check_type(std::string_view path, std::string* key_path = nullptr, aes_context* aes_ctx = nullptr); iso_encryption_type get_enc_type() const { return m_enc_type; } - bool init(const std::string& path, iso_archive* archive = nullptr); - bool decrypt(u64 offset, void* buffer, u64 size, const std::string& name); + bool init(std::string_view path, iso_archive* archive = nullptr); + bool decrypt(u64 offset, void* buffer, u64 size, std::string_view name); }; struct iso_extent_info @@ -116,8 +116,8 @@ protected: u64 file_offset(u64 pos) const; public: - iso_file(const std::string& path, bs_t mode = fs::read); - iso_file(const std::string& path, bs_t mode, const iso_fs_node& node); + iso_file(std::string_view path, bs_t mode = fs::read); + iso_file(std::string_view path, bs_t mode, const iso_fs_node& node); explicit operator bool() const { return m_file.operator bool(); } @@ -140,7 +140,7 @@ private: std::shared_ptr m_dec; public: - iso_file_encrypted(const std::string& path, bs_t mode, const iso_fs_node& node, std::shared_ptr dec); + iso_file_encrypted(std::string_view path, bs_t mode, const iso_fs_node& node, std::shared_ptr dec); u64 read_at(u64 offset, void* buffer, u64 size) override; }; @@ -169,18 +169,18 @@ private: std::shared_ptr m_dec; public: - iso_archive(const std::string& path); + iso_archive(std::string_view path); const std::string& path() const { return m_path; } const iso_fs_node& root() const { return m_root; } - iso_fs_node* retrieve(const std::string& path); - bool exists(const std::string& path); - bool is_file(const std::string& path); + iso_fs_node* retrieve(std::string_view path); + bool exists(std::string_view path); + bool is_file(std::string_view path); - std::unique_ptr get_iso_file(const std::string& path, bs_t mode, const iso_fs_node& node); - std::unique_ptr open(const std::string& path); - psf::registry open_psf(const std::string& path); + std::unique_ptr get_iso_file(std::string_view path, bs_t mode, const iso_fs_node& node); + std::unique_ptr open(std::string_view path); + psf::registry open_psf(std::string_view path); friend class iso_file; }; @@ -194,7 +194,7 @@ private: public: inline static std::string virtual_device_name = "/vfsv0_virtual_iso_overlay_fs_dev"; - iso_device(const std::string& iso_path, const std::string& device_name = virtual_device_name) + iso_device(std::string_view iso_path, std::string_view device_name = virtual_device_name) : m_path(iso_path), m_archive(iso_path) { fs_prefix = device_name; @@ -204,9 +204,9 @@ public: const std::string& get_loaded_iso() const { return m_path; } - bool stat(const std::string& path, fs::stat_t& info) override; - bool statfs(const std::string& path, fs::device_stat& info) override; + bool stat(std::string_view path, fs::stat_t& info) override; + bool statfs(std::string_view path, fs::device_stat& info) override; - std::unique_ptr open(const std::string& path, bs_t mode) override; - std::unique_ptr open_dir(const std::string& path) override; + std::unique_ptr open(std::string_view path, bs_t mode) override; + std::unique_ptr open_dir(std::string_view path) override; }; diff --git a/rpcs3/Loader/content_validation.cpp b/rpcs3/Loader/content_validation.cpp index 773ee276be..944b55e505 100644 --- a/rpcs3/Loader/content_validation.cpp +++ b/rpcs3/Loader/content_validation.cpp @@ -107,9 +107,9 @@ content_integrity_status content_validation::check_integrity(content_file_type f return content_integrity_status::NO_MATCH; } -bool content_validation::init_hash(const std::string& path) +bool content_validation::init_hash(std::string_view path) { - std::string new_path = path; + std::string new_path(path); fs::get_optical_raw_device(path, &new_path); diff --git a/rpcs3/Loader/content_validation.h b/rpcs3/Loader/content_validation.h index dc5d4ac5d9..f3a440ba1e 100644 --- a/rpcs3/Loader/content_validation.h +++ b/rpcs3/Loader/content_validation.h @@ -52,6 +52,6 @@ public: void set_count(u16 count) { m_count = count; } void abort_hash() { m_status = content_hash_status::ABORTED; } - bool init_hash(const std::string& path); + bool init_hash(std::string_view path); content_hash_status calculate_hash(std::string& hash); }; diff --git a/rpcs3/Loader/disc.cpp b/rpcs3/Loader/disc.cpp index 9ae33e42e0..f1259022ea 100644 --- a/rpcs3/Loader/disc.cpp +++ b/rpcs3/Loader/disc.cpp @@ -10,7 +10,7 @@ LOG_CHANNEL(disc_log, "DISC"); namespace disc { - disc_type get_disc_type(const std::string& path, std::string& disc_root, std::string& ps3_game_dir) + disc_type get_disc_type(std::string_view path, std::string& disc_root, std::string& ps3_game_dir) { disc_type type = disc_type::unknown; @@ -73,7 +73,7 @@ namespace disc std::vector lines; // Try to find SYSTEM.CNF - for (std::string search_dir = path;;) + for (std::string search_dir(path);;) { if (fs::file file(search_dir + "/SYSTEM.CNF"); file) { diff --git a/rpcs3/Loader/disc.h b/rpcs3/Loader/disc.h index 25123afbec..deeefa6e15 100644 --- a/rpcs3/Loader/disc.h +++ b/rpcs3/Loader/disc.h @@ -11,5 +11,5 @@ namespace disc ps3 }; - disc_type get_disc_type(const std::string& path, std::string& disc_root, std::string& ps3_game_dir); + disc_type get_disc_type(std::string_view path, std::string& disc_root, std::string& ps3_game_dir); } diff --git a/rpcs3/Loader/mself.cpp b/rpcs3/Loader/mself.cpp index 0437cb4d13..e4709642f9 100644 --- a/rpcs3/Loader/mself.cpp +++ b/rpcs3/Loader/mself.cpp @@ -8,7 +8,7 @@ LOG_CHANNEL(mself_log, "MSELF"); -bool extract_mself(const std::string& file, const std::string& extract_to) +bool extract_mself(std::string_view file, const std::string& extract_to) { fs::file mself(file); @@ -63,19 +63,21 @@ bool extract_mself(const std::string& file, const std::string& extract_to) mself.seek(pos); mself.read(buffer.data(), rec.size); - if (!fs::create_path(fs::get_parent_dir(extract_to + name))) + const std::string path = extract_to + name; + + if (!fs::create_path(fs::get_parent_dir(path))) { - mself_log.error("Error creating directory %s (%s)", fs::get_parent_dir(extract_to + name), fs::g_tls_error); + mself_log.error("Error creating directory %s (%s)", fs::get_parent_dir(path), fs::g_tls_error); return false; } - if (!fs::write_file(extract_to + name, fs::rewrite, buffer)) + if (!fs::write_file(path, fs::rewrite, buffer)) { - mself_log.error("Error creating %s (%s)", extract_to + name, fs::g_tls_error); + mself_log.error("Error creating %s (%s)", path, fs::g_tls_error); return false; } - mself_log.success("Extracted '%s' to '%s'", name, extract_to + name); + mself_log.success("Extracted '%s' to '%s'", name, path); } mself_log.success("Extraction complete!"); diff --git a/rpcs3/Loader/mself.hpp b/rpcs3/Loader/mself.hpp index 5d2bf0691b..1b4fa585d8 100644 --- a/rpcs3/Loader/mself.hpp +++ b/rpcs3/Loader/mself.hpp @@ -43,4 +43,4 @@ CHECK_SIZE(mself_header, 0x40); CHECK_SIZE(mself_record, 0x40); -bool extract_mself(const std::string& file, const std::string& extract_to); +bool extract_mself(std::string_view file, const std::string& extract_to);