DirectoryBlob: Create a DiscContent class for use in m_virtual_disc
This commit is contained in:
parent
b56214789e
commit
e1321b131d
|
@ -10,8 +10,8 @@
|
|||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <locale>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
@ -49,6 +49,50 @@ const std::array<u32, 10> PARTITION_TABLE = {
|
|||
{Common::swap32(1), Common::swap32((PARTITION_TABLE_ADDRESS + 0x20) >> 2), 0, 0, 0, 0, 0, 0,
|
||||
Common::swap32(GAME_PARTITION_ADDRESS >> 2), 0}};
|
||||
|
||||
DiscContent::DiscContent(u64 offset, u64 size, const std::string& path)
|
||||
: m_offset(offset), m_size(size), m_path(path)
|
||||
{
|
||||
}
|
||||
|
||||
DiscContent::DiscContent(u64 offset) : m_offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
u64 DiscContent::GetOffset() const
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
u64 DiscContent::GetSize() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
bool DiscContent::Read(u64* offset, u64* length, u8** buffer) const
|
||||
{
|
||||
if (m_size == 0)
|
||||
return true;
|
||||
|
||||
_dbg_assert_(DISCIO, *offset >= m_offset);
|
||||
const u64 offset_in_content = *offset - m_offset;
|
||||
|
||||
if (offset_in_content < m_size)
|
||||
{
|
||||
const u64 bytes_to_read = std::min(m_size - offset_in_content, *length);
|
||||
|
||||
File::IOFile file(m_path, "rb");
|
||||
file.Seek(offset_in_content, SEEK_SET);
|
||||
if (!file.ReadBytes(*buffer, bytes_to_read))
|
||||
return false;
|
||||
|
||||
*length -= bytes_to_read;
|
||||
*buffer += bytes_to_read;
|
||||
*offset += bytes_to_read;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool PathCharactersEqual(char a, char b)
|
||||
{
|
||||
return a == b
|
||||
|
@ -140,49 +184,29 @@ bool DirectoryBlobReader::ReadPartition(u64 offset, u64 length, u8* buffer)
|
|||
WriteToBuffer(m_fst_address, m_fst_data.size(), m_fst_data.data(), &offset, &length, &buffer);
|
||||
}
|
||||
|
||||
if (m_virtual_disk.empty())
|
||||
if (m_virtual_disc.empty())
|
||||
return true;
|
||||
|
||||
// Determine which file the offset refers to
|
||||
std::map<u64, std::string>::const_iterator fileIter = m_virtual_disk.lower_bound(offset);
|
||||
if (fileIter->first > offset && fileIter != m_virtual_disk.begin())
|
||||
--fileIter;
|
||||
// Determine which DiscContent the offset refers to
|
||||
std::set<DiscContent>::const_iterator it = m_virtual_disc.lower_bound(DiscContent(offset));
|
||||
if (it->GetOffset() > offset && it != m_virtual_disc.begin())
|
||||
--it;
|
||||
|
||||
// zero fill to start of file data
|
||||
PadToAddress(fileIter->first, &offset, &length, &buffer);
|
||||
PadToAddress(it->GetOffset(), &offset, &length, &buffer);
|
||||
|
||||
while (fileIter != m_virtual_disk.end() && length > 0)
|
||||
while (it != m_virtual_disc.end() && length > 0)
|
||||
{
|
||||
_dbg_assert_(DVDINTERFACE, fileIter->first <= offset);
|
||||
u64 fileOffset = offset - fileIter->first;
|
||||
const std::string fileName = fileIter->second;
|
||||
|
||||
File::IOFile file(fileName, "rb");
|
||||
if (!file)
|
||||
_dbg_assert_(DVDINTERFACE, it->GetOffset() <= offset);
|
||||
if (!it->Read(&offset, &length, &buffer))
|
||||
return false;
|
||||
|
||||
u64 fileSize = file.GetSize();
|
||||
++it;
|
||||
|
||||
if (fileOffset < fileSize)
|
||||
if (it != m_virtual_disc.end())
|
||||
{
|
||||
u64 fileBytes = std::min(fileSize - fileOffset, length);
|
||||
|
||||
if (!file.Seek(fileOffset, SEEK_SET))
|
||||
return false;
|
||||
if (!file.ReadBytes(buffer, fileBytes))
|
||||
return false;
|
||||
|
||||
length -= fileBytes;
|
||||
buffer += fileBytes;
|
||||
offset += fileBytes;
|
||||
}
|
||||
|
||||
++fileIter;
|
||||
|
||||
if (fileIter != m_virtual_disk.end())
|
||||
{
|
||||
_dbg_assert_(DVDINTERFACE, fileIter->first >= offset);
|
||||
PadToAddress(fileIter->first, &offset, &length, &buffer);
|
||||
_dbg_assert_(DVDINTERFACE, it->GetOffset() >= offset);
|
||||
PadToAddress(it->GetOffset(), &offset, &length, &buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,9 +492,9 @@ void DirectoryBlobReader::WriteDirectory(const File::FSTEntry& parent_entry, u32
|
|||
m_address_shift);
|
||||
WriteEntryName(name_offset, entry.virtualName);
|
||||
|
||||
// write entry to virtual disk
|
||||
_dbg_assert_(DVDINTERFACE, m_virtual_disk.find(*data_offset) == m_virtual_disk.end());
|
||||
m_virtual_disk.emplace(*data_offset, entry.physicalName);
|
||||
// write entry to virtual disc
|
||||
auto result = m_virtual_disc.emplace(*data_offset, entry.size, entry.physicalName);
|
||||
_dbg_assert_(DISCIO, result.second); // Check that this offset wasn't already occupied
|
||||
|
||||
// 32 KiB aligned - many games are fine with less alignment, but not all
|
||||
*data_offset = Common::AlignUp(*data_offset + std::max<u64>(entry.size, 1ull), 0x8000ull);
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -22,6 +23,30 @@ class IOFile;
|
|||
|
||||
namespace DiscIO
|
||||
{
|
||||
class DiscContent
|
||||
{
|
||||
public:
|
||||
DiscContent(u64 offset, u64 size, const std::string& path);
|
||||
|
||||
// Provided because it's convenient when searching for DiscContent in an std::set
|
||||
explicit DiscContent(u64 offset);
|
||||
|
||||
u64 GetOffset() const;
|
||||
u64 GetSize() const;
|
||||
bool Read(u64* offset, u64* length, u8** buffer) const;
|
||||
|
||||
bool operator==(const DiscContent& other) const { return m_offset == other.m_offset; }
|
||||
bool operator!=(const DiscContent& other) const { return !(*this == other); }
|
||||
bool operator<(const DiscContent& other) const { return m_offset < other.m_offset; }
|
||||
bool operator>(const DiscContent& other) const { return other < *this; }
|
||||
bool operator<=(const DiscContent& other) const { return !(*this < other); }
|
||||
bool operator>=(const DiscContent& other) const { return !(*this > other); }
|
||||
private:
|
||||
u64 m_offset;
|
||||
u64 m_size = 0;
|
||||
std::string m_path;
|
||||
};
|
||||
|
||||
class DirectoryBlobReader : public BlobReader
|
||||
{
|
||||
public:
|
||||
|
@ -70,7 +95,7 @@ private:
|
|||
|
||||
std::string m_root_directory;
|
||||
|
||||
std::map<u64, std::string> m_virtual_disk;
|
||||
std::set<DiscContent> m_virtual_disc;
|
||||
|
||||
bool m_is_wii = false;
|
||||
|
||||
|
|
Loading…
Reference in New Issue