From 257043529ae264fa2f4815aa3aace83199ebd6a7 Mon Sep 17 00:00:00 2001 From: Functionable <40835042+Functionable@users.noreply.github.com> Date: Sat, 13 Dec 2025 13:17:13 +0000 Subject: [PATCH] ISO: Loader improvements - Don't use floating point when advancing sectors - Remove redudndant seek in iso_archive constructor - Drop error code checks in iso_file::read_at - Don't use lexically_normal for handling path in iso_archive::retrieve. More complete directory search implementation. --- rpcs3/Loader/ISO.cpp | 60 ++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/rpcs3/Loader/ISO.cpp b/rpcs3/Loader/ISO.cpp index 4ba55fae78..f97d7fd026 100644 --- a/rpcs3/Loader/ISO.cpp +++ b/rpcs3/Loader/ISO.cpp @@ -6,6 +6,7 @@ #include #include #include +#include bool is_file_iso(const std::string& path) { @@ -166,9 +167,7 @@ void iso_form_hierarchy(fs::file& file, iso_fs_node& node, auto entry = iso_read_directory_entry(file, use_ucs2_decoding); if (!entry) { - float block_size = ISO_BLOCK_SIZE; - float t = std::floor(file.pos() / block_size); - u64 new_sector = t+1; + u64 new_sector = (file.pos() / ISO_BLOCK_SIZE) + 1; file.seek(new_sector * ISO_BLOCK_SIZE); continue; } @@ -253,8 +252,6 @@ iso_archive::iso_archive(const std::string& path) { .metadata = iso_read_directory_entry(m_file, use_ucs2_decoding).value(), }; - - m_file.seek(descriptor_start); } m_file.seek(descriptor_start + ISO_BLOCK_SIZE); @@ -266,15 +263,19 @@ iso_archive::iso_archive(const std::string& path) iso_fs_node* iso_archive::retrieve(const std::string& passed_path) { - std::string path = std::filesystem::path(passed_path).lexically_normal().string(); + std::string path = std::filesystem::path(passed_path).string(); size_t start = 0; size_t end = path.find_first_of(fs::delim); - auto dir_entry = &m_root; + std::stack search_stack; + search_stack.push(&m_root); do { + if (search_stack.empty()) return nullptr; + auto* top_entry = search_stack.top(); + if (end == std::string::npos) { end = path.size(); @@ -283,27 +284,40 @@ iso_fs_node* iso_archive::retrieve(const std::string& passed_path) auto path_component = path.substr(start, end-start); bool found = false; - for (const auto& entry : dir_entry->children) - { - if (entry->metadata.name.compare(path_component) == 0) - { - dir_entry = entry.get(); - start = end + 1; - end = path.find_first_of(fs::delim, start); - found = true; - break; + if (path_component == ".") + { + found = true; + } + else if (path_component == "..") + { + search_stack.pop(); + found = true; + } + else + { + for (const auto& entry : top_entry->children) + { + if (entry->metadata.name.compare(path_component) == 0) + { + search_stack.push(entry.get()); + + found = true; + break; + } } } - if (!found) - { - return nullptr; - } + if (!found) return nullptr; + + start = end + 1; + end = path.find_first_of(fs::delim, start); } while(start < path.size()); - return dir_entry; + if (search_stack.empty()) return nullptr; + + return search_stack.top(); } bool iso_archive::exists(const std::string& path) @@ -393,11 +407,9 @@ u64 iso_file::read(void* buffer, u64 size) u64 iso_file::read_at(u64 offset, void* buffer, u64 size) { - const u64 bad_res = -1; u64 local_remaining = local_extent_remaining(offset); u64 total_read = m_file.read_at(file_offset(offset), buffer, std::min(size, local_remaining)); - if (total_read == bad_res) return -1; auto total_size = this->size(); @@ -408,8 +420,6 @@ u64 iso_file::read_at(u64 offset, void* buffer, u64 size) size - total_read ); - if (second_total_read == bad_res) return -1; - return total_read + second_total_read; }