This commit is contained in:
Megamouse 2026-07-09 17:21:58 +05:30 committed by GitHub
commit 63b89ea421
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 227 additions and 177 deletions

View File

@ -218,8 +218,8 @@ namespace fs
std::unordered_map<std::string, shared_ptr<device_base>> m_map{};
public:
shared_ptr<device_base> get_device(const std::string& path);
shared_ptr<device_base> set_device(const std::string& name, shared_ptr<device_base>);
shared_ptr<device_base> get_device(std::string_view path);
shared_ptr<device_base> set_device(std::string_view name, shared_ptr<device_base>);
};
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_base> fs::device_manager::get_device(const std::string& path)
shared_ptr<fs::device_base> 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_base> fs::device_manager::get_device(const std::string& pa
return found->second;
}
shared_ptr<fs::device_base> fs::device_manager::set_device(const std::string& name, shared_ptr<device_base> device)
shared_ptr<fs::device_base> fs::device_manager::set_device(std::string_view name, shared_ptr<device_base> 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_base> 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_base> fs::device_manager::set_device(const std::string& na
return null_ptr;
}
shared_ptr<fs::device_base> fs::get_virtual_device(const std::string& path)
shared_ptr<fs::device_base> 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::device_base> fs::get_virtual_device(const std::string& path)
return null_ptr;
}
shared_ptr<fs::device_base> fs::set_virtual_device(const std::string& name, shared_ptr<device_base> device)
shared_ptr<fs::device_base> fs::set_virtual_device(std::string_view name, shared_ptr<device_base> 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<open_mode> mode)
fs::file::file(std::string_view path, bs_t<open_mode> mode)
{
if (path.empty())
{
@ -1809,14 +1857,14 @@ fs::file::file(const std::string& path, bs_t<open_mode> 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<open_mode> 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<windows_dir>(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<bool>* cancel_flag)
u64 fs::get_dir_size(std::string_view path, u64 rounding_alignment, atomic_t<bool>* 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<DWORD>(link_name_buffer.size() - 1);
@ -2857,7 +2904,7 @@ bool fs::pending_file::commit(bool overwrite)
return false;
}
stx::generator<fs::dir_entry&> fs::list_dir_recursively(const std::string& path)
stx::generator<fs::dir_entry&> fs::list_dir_recursively(std::string_view path)
{
for (auto& entry : fs::dir(path))
{

View File

@ -7,6 +7,7 @@
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include <algorithm>
@ -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<file_base> open(const std::string& path, bs_t<open_mode> mode) = 0;
virtual std::unique_ptr<dir_base> open_dir(const std::string& path) = 0;
virtual std::unique_ptr<file_base> open(std::string_view path, bs_t<open_mode> mode) = 0;
virtual std::unique_ptr<dir_base> 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<device_base> get_virtual_device(const std::string& path);
shared_ptr<device_base> get_virtual_device(std::string_view path);
// Set virtual device with specified name (nullptr for deletion)
shared_ptr<device_base> set_virtual_device(const std::string& name, shared_ptr<device_base> device);
shared_ptr<device_base> set_virtual_device(std::string_view name, shared_ptr<device_base> 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<open_mode> mode = ::fs::read);
explicit file(std::string_view path, bs_t<open_mode> mode = ::fs::read);
file(std::unique_ptr<file_base>&& 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<bool>* cancel_flag = nullptr);
u64 get_dir_size(std::string_view path, u64 rounding_alignment = 1, atomic_t<bool>* cancel_flag = nullptr);
enum class error : uint
{
@ -848,7 +849,7 @@ namespace fs
}
template <bool Flush = false, typename... Args>
bool write_file(const std::string& path, bs_t<fs::open_mode> mode, const Args&... args)
bool write_file(std::string_view path, bs_t<fs::open_mode> 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<file>);
stx::generator<dir_entry&> list_dir_recursively(const std::string& path);
stx::generator<dir_entry&> list_dir_recursively(std::string_view path);
}

View File

@ -440,7 +440,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))
{
@ -951,7 +951,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))
{
@ -968,7 +968,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))
{
@ -4679,7 +4679,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;
@ -4687,7 +4687,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);
@ -4845,7 +4845,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};

View File

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

View File

@ -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<fs::open_mode> mode, const iso_fs_node& node, std::shared_ptr<iso_file_decryption> dec)
iso_file_encrypted::iso_file_encrypted(std::string_view path, bs_t<fs::open_mode> mode, const iso_fs_node& node, std::shared_ptr<iso_file_decryption> dec)
: iso_file(path, mode, node), m_dec(dec)
{
}
@ -909,7 +909,7 @@ static std::optional<iso_fs_metadata> 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<fs::file_base> iso_archive::get_iso_file(const std::string& path, bs_t<fs::open_mode> mode, const iso_fs_node& node)
std::unique_ptr<fs::file_base> iso_archive::get_iso_file(std::string_view path, bs_t<fs::open_mode> mode, const iso_fs_node& node)
{
if (m_dec->get_enc_type() == iso_encryption_type::NONE)
{
@ -1154,12 +1154,12 @@ std::unique_ptr<fs::file_base> iso_archive::get_iso_file(const std::string& path
return std::make_unique<iso_file_encrypted>(path, mode, node, m_dec);
}
std::unique_ptr<fs::file_base> iso_archive::open(const std::string& path)
std::unique_ptr<fs::file_base> 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<fs::open_mode> mode)
iso_file::iso_file(std::string_view path, bs_t<fs::open_mode> mode)
{
m_file = fs::file(path, mode);
@ -1192,7 +1192,7 @@ iso_file::iso_file(const std::string& path, bs_t<fs::open_mode> mode)
m_raw_device = fs::is_optical_raw_device(path);
}
iso_file::iso_file(const std::string& path, bs_t<fs::open_mode> mode, const iso_fs_node& node)
iso_file::iso_file(std::string_view path, bs_t<fs::open_mode> 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<fs::file_base> iso_device::open(const std::string& path, bs_t<fs::open_mode> mode)
std::unique_ptr<fs::file_base> iso_device::open(std::string_view path, bs_t<fs::open_mode> 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<fs::file_base> iso_device::open(const std::string& path, bs_t<fs
return m_archive.get_iso_file(m_archive.path(), mode, *node);
}
std::unique_ptr<fs::dir_base> iso_device::open_dir(const std::string& path)
std::unique_ptr<fs::dir_base> 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<fs::dir_base> iso_device::open_dir(const std::string& path)
return std::make_unique<iso_dir>(*node);
}
void load_iso(const std::string& path)
void load_iso(std::string_view path)
{
sys_log.notice("Loading ISO '%s'", path);

View File

@ -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<iso_region_info> 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<fs::open_mode> mode = fs::read);
iso_file(const std::string& path, bs_t<fs::open_mode> mode, const iso_fs_node& node);
iso_file(std::string_view path, bs_t<fs::open_mode> mode = fs::read);
iso_file(std::string_view path, bs_t<fs::open_mode> mode, const iso_fs_node& node);
explicit operator bool() const { return m_file.operator bool(); }
@ -140,7 +140,7 @@ private:
std::shared_ptr<iso_file_decryption> m_dec;
public:
iso_file_encrypted(const std::string& path, bs_t<fs::open_mode> mode, const iso_fs_node& node, std::shared_ptr<iso_file_decryption> dec);
iso_file_encrypted(std::string_view path, bs_t<fs::open_mode> mode, const iso_fs_node& node, std::shared_ptr<iso_file_decryption> dec);
u64 read_at(u64 offset, void* buffer, u64 size) override;
};
@ -169,18 +169,18 @@ private:
std::shared_ptr<iso_file_decryption> 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<fs::file_base> get_iso_file(const std::string& path, bs_t<fs::open_mode> mode, const iso_fs_node& node);
std::unique_ptr<fs::file_base> open(const std::string& path);
psf::registry open_psf(const std::string& path);
std::unique_ptr<fs::file_base> get_iso_file(std::string_view path, bs_t<fs::open_mode> mode, const iso_fs_node& node);
std::unique_ptr<fs::file_base> 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<fs::file_base> open(const std::string& path, bs_t<fs::open_mode> mode) override;
std::unique_ptr<fs::dir_base> open_dir(const std::string& path) override;
std::unique_ptr<fs::file_base> open(std::string_view path, bs_t<fs::open_mode> mode) override;
std::unique_ptr<fs::dir_base> open_dir(std::string_view path) override;
};

View File

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

View File

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

View File

@ -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<std::string> 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)
{

View File

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

View File

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

View File

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