From 5c02795af0cbe3ad95c7d3fb2de9891af77e98bb Mon Sep 17 00:00:00 2001 From: JosJuice Date: Wed, 21 Dec 2016 14:01:00 +0100 Subject: [PATCH] WbfsBlob: Only open each file once The first file used to be opened once by CreateBlobReader and once inside WbfsFileReader. --- Source/Core/DiscIO/Blob.cpp | 2 +- Source/Core/DiscIO/WbfsBlob.cpp | 63 ++++++++++++++++++--------------- Source/Core/DiscIO/WbfsBlob.h | 12 +++++-- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/Source/Core/DiscIO/Blob.cpp b/Source/Core/DiscIO/Blob.cpp index e40b530233..7d30cfe212 100644 --- a/Source/Core/DiscIO/Blob.cpp +++ b/Source/Core/DiscIO/Blob.cpp @@ -199,7 +199,7 @@ std::unique_ptr CreateBlobReader(const std::string& filename) case TGC_MAGIC: return TGCFileReader::Create(std::move(file)); case WBFS_MAGIC: - return WbfsFileReader::Create(filename); + return WbfsFileReader::Create(std::move(file), filename); default: return PlainFileReader::Create(std::move(file)); } diff --git a/Source/Core/DiscIO/WbfsBlob.cpp b/Source/Core/DiscIO/WbfsBlob.cpp index 58ec6fc4c7..1bc7013aed 100644 --- a/Source/Core/DiscIO/WbfsBlob.cpp +++ b/Source/Core/DiscIO/WbfsBlob.cpp @@ -7,9 +7,11 @@ #include #include #include +#include #include #include "Common/Align.h" +#include "Common/Assert.h" #include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" #include "Common/FileUtil.h" @@ -23,14 +25,15 @@ static const u64 WII_SECTOR_SIZE = 0x8000; static const u64 WII_SECTOR_COUNT = 143432 * 2; static const u64 WII_DISC_HEADER_SIZE = 256; -WbfsFileReader::WbfsFileReader(const std::string& filename) - : m_total_files(0), m_size(0), m_good(true) +WbfsFileReader::WbfsFileReader(File::IOFile file, const std::string& path) + : m_total_files(0), m_size(0), m_good(false) { - if (filename.length() < 4 || !OpenFiles(filename) || !ReadHeader()) - { - m_good = false; + if (!AddFileToList(std::move(file))) return; - } + OpenAdditionalFiles(path); + if (!ReadHeader()) + return; + m_good = true; // Grab disc info (assume slot 0, checked in ReadHeader()) m_wlba_table.resize(m_blocks_per_disc); @@ -50,38 +53,40 @@ u64 WbfsFileReader::GetDataSize() const return WII_SECTOR_COUNT * WII_SECTOR_SIZE; } -bool WbfsFileReader::OpenFiles(const std::string& filename) +void WbfsFileReader::OpenAdditionalFiles(const std::string& path) { - m_total_files = 0; + if (path.length() < 4) + return; + + _assert_(m_total_files > 0); // The code below gives .wbf0 for index 0, but it should be .wbfs while (true) { - auto new_entry = std::make_unique(); - // Replace last character with index (e.g. wbfs = wbf1) - std::string path = filename; - if (m_total_files != 0) - { - path[path.length() - 1] = '0' + m_total_files; - } - - if (!new_entry->file.Open(path, "rb")) - { - return m_total_files != 0; - } - - new_entry->base_address = m_size; - new_entry->size = new_entry->file.GetSize(); - m_size += new_entry->size; - - m_total_files++; - m_files.emplace_back(std::move(new_entry)); + std::string current_path = path; + current_path.back() = '0' + m_total_files; + if (!AddFileToList(File::IOFile(current_path, "rb"))) + return; } } +bool WbfsFileReader::AddFileToList(File::IOFile file) +{ + if (!file.IsOpen()) + return false; + + const u64 file_size = file.GetSize(); + m_files.emplace_back(std::make_unique(std::move(file), m_size, file_size)); + m_size += file_size; + m_total_files++; + + return true; +} + bool WbfsFileReader::ReadHeader() { // Read hd size info + m_files[0]->file.Seek(0, SEEK_SET); m_files[0]->file.ReadBytes(&m_header, sizeof(WbfsHeader)); if (m_header.magic != WBFS_MAGIC) return false; @@ -164,9 +169,9 @@ File::IOFile& WbfsFileReader::SeekToCluster(u64 offset, u64* available) return m_files[0]->file; } -std::unique_ptr WbfsFileReader::Create(const std::string& filename) +std::unique_ptr WbfsFileReader::Create(File::IOFile file, const std::string& path) { - auto reader = std::unique_ptr(new WbfsFileReader(filename)); + auto reader = std::unique_ptr(new WbfsFileReader(std::move(file), path)); if (!reader->IsGood()) reader.reset(); diff --git a/Source/Core/DiscIO/WbfsBlob.h b/Source/Core/DiscIO/WbfsBlob.h index 5012ccd174..fc55b3ae48 100644 --- a/Source/Core/DiscIO/WbfsBlob.h +++ b/Source/Core/DiscIO/WbfsBlob.h @@ -21,7 +21,7 @@ class WbfsFileReader : public IBlobReader public: ~WbfsFileReader(); - static std::unique_ptr Create(const std::string& filename); + static std::unique_ptr Create(File::IOFile file, const std::string& path); BlobType GetBlobType() const override { return BlobType::WBFS; } // The WBFS format does not save the original file size. @@ -33,15 +33,21 @@ public: bool Read(u64 offset, u64 nbytes, u8* out_ptr) override; private: - WbfsFileReader(const std::string& filename); + WbfsFileReader(File::IOFile file, const std::string& path); - bool OpenFiles(const std::string& filename); + void OpenAdditionalFiles(const std::string& path); + bool AddFileToList(File::IOFile file); bool ReadHeader(); File::IOFile& SeekToCluster(u64 offset, u64* available); bool IsGood() { return m_good; } struct file_entry { + file_entry(File::IOFile file_, u64 base_address_, u64 size_) + : file(std::move(file_)), base_address(base_address_), size(size_) + { + } + File::IOFile file; u64 base_address; u64 size;