From 7d2216c289d6aef3573ae2bf2609f84532a2bb70 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 23 Oct 2024 21:20:23 +1000 Subject: [PATCH] GameList: Avoid double fopen/read of EXEs --- src/core/bus.cpp | 5 ++++- src/core/game_list.cpp | 16 +++++++++++++--- src/core/system.cpp | 8 ++++++-- src/core/system.h | 2 ++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/core/bus.cpp b/src/core/bus.cpp index fda412dd3..34cb8426c 100644 --- a/src/core/bus.cpp +++ b/src/core/bus.cpp @@ -1187,8 +1187,11 @@ bool Bus::SideloadEXE(const std::string& path, Error* error) return false; } + // Stupid Android... + std::string filename = FileSystem::GetDisplayNameFromPath(path); + bool okay = true; - if (StringUtil::EndsWithNoCase(path, ".cpe")) + if (StringUtil::EndsWithNoCase(filename, ".cpe")) { okay = InjectCPE(exe_data->cspan(), true, error); } diff --git a/src/core/game_list.cpp b/src/core/game_list.cpp index d5944a80f..3db8ec8ea 100644 --- a/src/core/game_list.cpp +++ b/src/core/game_list.cpp @@ -179,10 +179,13 @@ bool GameList::GetExeListEntry(const std::string& path, GameList::Entry* entry) if (entry->file_size < 0) return false; - entry->title = Path::GetFileTitle(FileSystem::GetDisplayNameFromPath(path)); + // Stupid Android... + const std::string filename = FileSystem::GetDisplayNameFromPath(path); + + entry->title = Path::GetFileTitle(filename); entry->type = EntryType::PSExe; - if (StringUtil::EndsWithNoCase(path, ".cpe")) + if (StringUtil::EndsWithNoCase(filename, ".cpe")) { u32 magic; if (std::fread(&magic, sizeof(magic), 1, fp.get()) != 1 || magic != BIOS::CPE_MAGIC) @@ -207,7 +210,14 @@ bool GameList::GetExeListEntry(const std::string& path, GameList::Entry* entry) entry->region = BIOS::GetPSExeDiscRegion(header); } - const GameHash hash = System::GetGameHashFromFile(path.c_str()); + const auto data = FileSystem::ReadBinaryFile(fp.get()); + if (!data.has_value()) + { + WARNING_LOG("Failed to read {}", path); + return false; + } + + const GameHash hash = System::GetGameHashFromBuffer(filename, data->cspan()); entry->serial = hash ? System::GetGameHashId(hash) : std::string(); return true; } diff --git a/src/core/system.cpp b/src/core/system.cpp index 1a0716025..029a78a82 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -997,8 +997,12 @@ GameHash System::GetGameHashFromFile(const char* path) if (!data) return 0; - const std::string display_name = FileSystem::GetDisplayNameFromPath(path); - return GetGameHashFromBuffer(display_name, data->cspan(), IsoReader::ISOPrimaryVolumeDescriptor{}, 0); + return GetGameHashFromBuffer(FileSystem::GetDisplayNameFromPath(path), data->cspan()); +} + +GameHash System::GetGameHashFromBuffer(const std::string_view filename, const std::span data) +{ + return GetGameHashFromBuffer(filename, data, IsoReader::ISOPrimaryVolumeDescriptor{}, 0); } std::string System::GetExecutableNameForImage(IsoReader& iso, bool strip_subdirectories) diff --git a/src/core/system.h b/src/core/system.h index 598dd0167..dfa730eae 100644 --- a/src/core/system.h +++ b/src/core/system.h @@ -10,6 +10,7 @@ #include #include +#include #include class ByteStream; @@ -143,6 +144,7 @@ bool ReadExecutableFromImage(CDImage* cdi, std::string* out_executable_name, std std::string GetGameHashId(GameHash hash); bool GetGameDetailsFromImage(CDImage* cdi, std::string* out_id, GameHash* out_hash); GameHash GetGameHashFromFile(const char* path); +GameHash GetGameHashFromBuffer(const std::string_view filename, const std::span data); DiscRegion GetRegionForSerial(const std::string_view serial); DiscRegion GetRegionFromSystemArea(CDImage* cdi); DiscRegion GetRegionForImage(CDImage* cdi);