mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 03:35:26 +00:00
WbfsBlob: Only open each file once
The first file used to be opened once by CreateBlobReader and once inside WbfsFileReader.
This commit is contained in:
parent
8d54bbc528
commit
5c02795af0
@ -199,7 +199,7 @@ std::unique_ptr<IBlobReader> 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));
|
||||
}
|
||||
|
@ -7,9 +7,11 @@
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#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<file_entry>();
|
||||
|
||||
// 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<file_entry>(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> WbfsFileReader::Create(const std::string& filename)
|
||||
std::unique_ptr<WbfsFileReader> WbfsFileReader::Create(File::IOFile file, const std::string& path)
|
||||
{
|
||||
auto reader = std::unique_ptr<WbfsFileReader>(new WbfsFileReader(filename));
|
||||
auto reader = std::unique_ptr<WbfsFileReader>(new WbfsFileReader(std::move(file), path));
|
||||
|
||||
if (!reader->IsGood())
|
||||
reader.reset();
|
||||
|
@ -21,7 +21,7 @@ class WbfsFileReader : public IBlobReader
|
||||
public:
|
||||
~WbfsFileReader();
|
||||
|
||||
static std::unique_ptr<WbfsFileReader> Create(const std::string& filename);
|
||||
static std::unique_ptr<WbfsFileReader> 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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user