mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-04 15:40:02 +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:
|
case TGC_MAGIC:
|
||||||
return TGCFileReader::Create(std::move(file));
|
return TGCFileReader::Create(std::move(file));
|
||||||
case WBFS_MAGIC:
|
case WBFS_MAGIC:
|
||||||
return WbfsFileReader::Create(filename);
|
return WbfsFileReader::Create(std::move(file), filename);
|
||||||
default:
|
default:
|
||||||
return PlainFileReader::Create(std::move(file));
|
return PlainFileReader::Create(std::move(file));
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,11 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/Align.h"
|
#include "Common/Align.h"
|
||||||
|
#include "Common/Assert.h"
|
||||||
#include "Common/CommonFuncs.h"
|
#include "Common/CommonFuncs.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/FileUtil.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_SECTOR_COUNT = 143432 * 2;
|
||||||
static const u64 WII_DISC_HEADER_SIZE = 256;
|
static const u64 WII_DISC_HEADER_SIZE = 256;
|
||||||
|
|
||||||
WbfsFileReader::WbfsFileReader(const std::string& filename)
|
WbfsFileReader::WbfsFileReader(File::IOFile file, const std::string& path)
|
||||||
: m_total_files(0), m_size(0), m_good(true)
|
: m_total_files(0), m_size(0), m_good(false)
|
||||||
{
|
{
|
||||||
if (filename.length() < 4 || !OpenFiles(filename) || !ReadHeader())
|
if (!AddFileToList(std::move(file)))
|
||||||
{
|
|
||||||
m_good = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
OpenAdditionalFiles(path);
|
||||||
|
if (!ReadHeader())
|
||||||
|
return;
|
||||||
|
m_good = true;
|
||||||
|
|
||||||
// Grab disc info (assume slot 0, checked in ReadHeader())
|
// Grab disc info (assume slot 0, checked in ReadHeader())
|
||||||
m_wlba_table.resize(m_blocks_per_disc);
|
m_wlba_table.resize(m_blocks_per_disc);
|
||||||
@ -50,38 +53,40 @@ u64 WbfsFileReader::GetDataSize() const
|
|||||||
return WII_SECTOR_COUNT * WII_SECTOR_SIZE;
|
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)
|
while (true)
|
||||||
{
|
{
|
||||||
auto new_entry = std::make_unique<file_entry>();
|
|
||||||
|
|
||||||
// Replace last character with index (e.g. wbfs = wbf1)
|
// Replace last character with index (e.g. wbfs = wbf1)
|
||||||
std::string path = filename;
|
std::string current_path = path;
|
||||||
if (m_total_files != 0)
|
current_path.back() = '0' + m_total_files;
|
||||||
{
|
if (!AddFileToList(File::IOFile(current_path, "rb")))
|
||||||
path[path.length() - 1] = '0' + m_total_files;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
bool WbfsFileReader::ReadHeader()
|
||||||
{
|
{
|
||||||
// Read hd size info
|
// Read hd size info
|
||||||
|
m_files[0]->file.Seek(0, SEEK_SET);
|
||||||
m_files[0]->file.ReadBytes(&m_header, sizeof(WbfsHeader));
|
m_files[0]->file.ReadBytes(&m_header, sizeof(WbfsHeader));
|
||||||
if (m_header.magic != WBFS_MAGIC)
|
if (m_header.magic != WBFS_MAGIC)
|
||||||
return false;
|
return false;
|
||||||
@ -164,9 +169,9 @@ File::IOFile& WbfsFileReader::SeekToCluster(u64 offset, u64* available)
|
|||||||
return m_files[0]->file;
|
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())
|
if (!reader->IsGood())
|
||||||
reader.reset();
|
reader.reset();
|
||||||
|
@ -21,7 +21,7 @@ class WbfsFileReader : public IBlobReader
|
|||||||
public:
|
public:
|
||||||
~WbfsFileReader();
|
~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; }
|
BlobType GetBlobType() const override { return BlobType::WBFS; }
|
||||||
// The WBFS format does not save the original file size.
|
// 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;
|
bool Read(u64 offset, u64 nbytes, u8* out_ptr) override;
|
||||||
|
|
||||||
private:
|
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();
|
bool ReadHeader();
|
||||||
|
|
||||||
File::IOFile& SeekToCluster(u64 offset, u64* available);
|
File::IOFile& SeekToCluster(u64 offset, u64* available);
|
||||||
bool IsGood() { return m_good; }
|
bool IsGood() { return m_good; }
|
||||||
struct file_entry
|
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;
|
File::IOFile file;
|
||||||
u64 base_address;
|
u64 base_address;
|
||||||
u64 size;
|
u64 size;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user