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.
This commit is contained in:
Functionable 2025-12-13 13:17:13 +00:00 committed by Elad
parent 2533aa02d0
commit 257043529a

View File

@ -6,6 +6,7 @@
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <filesystem> #include <filesystem>
#include <stack>
bool is_file_iso(const std::string& path) 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); auto entry = iso_read_directory_entry(file, use_ucs2_decoding);
if (!entry) if (!entry)
{ {
float block_size = ISO_BLOCK_SIZE; u64 new_sector = (file.pos() / ISO_BLOCK_SIZE) + 1;
float t = std::floor(file.pos() / block_size);
u64 new_sector = t+1;
file.seek(new_sector * ISO_BLOCK_SIZE); file.seek(new_sector * ISO_BLOCK_SIZE);
continue; continue;
} }
@ -253,8 +252,6 @@ iso_archive::iso_archive(const std::string& path)
{ {
.metadata = iso_read_directory_entry(m_file, use_ucs2_decoding).value(), .metadata = iso_read_directory_entry(m_file, use_ucs2_decoding).value(),
}; };
m_file.seek(descriptor_start);
} }
m_file.seek(descriptor_start + ISO_BLOCK_SIZE); 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) 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 start = 0;
size_t end = path.find_first_of(fs::delim); size_t end = path.find_first_of(fs::delim);
auto dir_entry = &m_root; std::stack<iso_fs_node*> search_stack;
search_stack.push(&m_root);
do do
{ {
if (search_stack.empty()) return nullptr;
auto* top_entry = search_stack.top();
if (end == std::string::npos) if (end == std::string::npos)
{ {
end = path.size(); 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); auto path_component = path.substr(start, end-start);
bool found = false; 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; if (path_component == ".")
end = path.find_first_of(fs::delim, start); {
found = true; found = true;
break; }
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) if (!found) return nullptr;
{
return nullptr; start = end + 1;
} end = path.find_first_of(fs::delim, start);
} }
while(start < path.size()); 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) 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) u64 iso_file::read_at(u64 offset, void* buffer, u64 size)
{ {
const u64 bad_res = -1;
u64 local_remaining = local_extent_remaining(offset); u64 local_remaining = local_extent_remaining(offset);
u64 total_read = m_file.read_at(file_offset(offset), buffer, std::min(size, local_remaining)); 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(); auto total_size = this->size();
@ -408,8 +420,6 @@ u64 iso_file::read_at(u64 offset, void* buffer, u64 size)
size - total_read size - total_read
); );
if (second_total_read == bad_res) return -1;
return total_read + second_total_read; return total_read + second_total_read;
} }