mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-09 23:59:27 +01:00
Filesystem: Replace FileInfo struct with interface
GC/Wii filesystem internals shouldn't be exposed to other classes. This change isn't especially useful by itself, but it opens up the way for some neat stuff in the following commits.
This commit is contained in:
parent
95bc57cff3
commit
5021b4a567
@ -16,6 +16,8 @@
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "DiscIO/DiscScrubber.h"
|
||||
#include "DiscIO/Filesystem.h"
|
||||
// TODO: eww
|
||||
#include "DiscIO/FileSystemGCWii.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
|
||||
namespace DiscIO
|
||||
@ -219,11 +221,11 @@ bool DiscScrubber::ParsePartitionData(const Partition& partition, PartitionHeade
|
||||
MarkAsUsedE(partition_data_offset, header->fst_offset, header->fst_size);
|
||||
|
||||
// Go through the filesystem and mark entries as used
|
||||
for (const FileInfo& file : filesystem->GetFileList())
|
||||
for (const FileInfoGCWii& file : filesystem->GetFileList())
|
||||
{
|
||||
DEBUG_LOG(DISCIO, "%s", file.m_FullPath.empty() ? "/" : file.m_FullPath.c_str());
|
||||
if (!file.IsDirectory())
|
||||
MarkAsUsedE(partition_data_offset, file.m_Offset, file.m_FileSize);
|
||||
MarkAsUsedE(partition_data_offset, file.GetOffset(), file.GetSize());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -22,8 +22,17 @@
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
FileInfoGCWii::FileInfoGCWii(u64 name_offset, u64 offset, u64 file_size)
|
||||
: m_NameOffset(name_offset), m_Offset(offset), m_FileSize(file_size)
|
||||
{
|
||||
}
|
||||
|
||||
FileInfoGCWii::~FileInfoGCWii()
|
||||
{
|
||||
}
|
||||
|
||||
FileSystemGCWii::FileSystemGCWii(const Volume* _rVolume, const Partition& partition)
|
||||
: FileSystem(_rVolume, partition), m_Initialized(false), m_Valid(false), m_offset_shift(0)
|
||||
: FileSystem(_rVolume, partition), m_Initialized(false), m_Valid(false), m_offset_shift(0)
|
||||
{
|
||||
m_Valid = DetectFileSystem();
|
||||
}
|
||||
@ -38,10 +47,10 @@ u64 FileSystemGCWii::GetFileSize(const std::string& _rFullPath)
|
||||
if (!m_Initialized)
|
||||
InitFileSystem();
|
||||
|
||||
const FileInfo* pFileInfo = FindFileInfo(_rFullPath);
|
||||
const FileInfoGCWii* pFileInfo = FindFileInfo(_rFullPath);
|
||||
|
||||
if (pFileInfo != nullptr && !pFileInfo->IsDirectory())
|
||||
return pFileInfo->m_FileSize;
|
||||
return pFileInfo->GetSize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -53,7 +62,8 @@ std::string FileSystemGCWii::GetFileName(u64 _Address)
|
||||
|
||||
for (auto& fileInfo : m_FileInfoVector)
|
||||
{
|
||||
if ((fileInfo.m_Offset <= _Address) && ((fileInfo.m_Offset + fileInfo.m_FileSize) > _Address))
|
||||
if ((fileInfo.GetOffset() <= _Address) &&
|
||||
((fileInfo.GetOffset() + fileInfo.GetSize()) > _Address))
|
||||
{
|
||||
return fileInfo.m_FullPath;
|
||||
}
|
||||
@ -68,21 +78,21 @@ u64 FileSystemGCWii::ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _
|
||||
if (!m_Initialized)
|
||||
InitFileSystem();
|
||||
|
||||
const FileInfo* pFileInfo = FindFileInfo(_rFullPath);
|
||||
const FileInfoGCWii* pFileInfo = FindFileInfo(_rFullPath);
|
||||
if (pFileInfo == nullptr)
|
||||
return 0;
|
||||
|
||||
if (_OffsetInFile >= pFileInfo->m_FileSize)
|
||||
if (_OffsetInFile >= pFileInfo->GetSize())
|
||||
return 0;
|
||||
|
||||
u64 read_length = std::min(_MaxBufferSize, pFileInfo->m_FileSize - _OffsetInFile);
|
||||
u64 read_length = std::min(_MaxBufferSize, pFileInfo->GetSize() - _OffsetInFile);
|
||||
|
||||
DEBUG_LOG(DISCIO, "Reading %" PRIx64 " bytes at %" PRIx64 " from file %s. Offset: %" PRIx64
|
||||
" Size: %" PRIx64,
|
||||
read_length, _OffsetInFile, _rFullPath.c_str(), pFileInfo->m_Offset,
|
||||
pFileInfo->m_FileSize);
|
||||
read_length, _OffsetInFile, _rFullPath.c_str(), pFileInfo->GetOffset(),
|
||||
pFileInfo->GetSize());
|
||||
|
||||
m_rVolume->Read(pFileInfo->m_Offset + _OffsetInFile, read_length, _pBuffer, m_partition);
|
||||
m_rVolume->Read(pFileInfo->GetOffset() + _OffsetInFile, read_length, _pBuffer, m_partition);
|
||||
return read_length;
|
||||
}
|
||||
|
||||
@ -91,13 +101,13 @@ bool FileSystemGCWii::ExportFile(const std::string& _rFullPath, const std::strin
|
||||
if (!m_Initialized)
|
||||
InitFileSystem();
|
||||
|
||||
const FileInfo* pFileInfo = FindFileInfo(_rFullPath);
|
||||
const FileInfoGCWii* pFileInfo = FindFileInfo(_rFullPath);
|
||||
|
||||
if (!pFileInfo)
|
||||
return false;
|
||||
|
||||
u64 remainingSize = pFileInfo->m_FileSize;
|
||||
u64 fileOffset = pFileInfo->m_Offset;
|
||||
u64 remainingSize = pFileInfo->GetSize();
|
||||
u64 fileOffset = pFileInfo->GetOffset();
|
||||
|
||||
File::IOFile f(_rExportFilename, "wb");
|
||||
if (!f)
|
||||
@ -225,7 +235,7 @@ std::string FileSystemGCWii::GetStringFromOffset(u64 _Offset) const
|
||||
return SHIFTJISToUTF8(data);
|
||||
}
|
||||
|
||||
const std::vector<FileInfo>& FileSystemGCWii::GetFileList()
|
||||
const std::vector<FileInfoGCWii>& FileSystemGCWii::GetFileList()
|
||||
{
|
||||
if (!m_Initialized)
|
||||
InitFileSystem();
|
||||
@ -233,7 +243,7 @@ const std::vector<FileInfo>& FileSystemGCWii::GetFileList()
|
||||
return m_FileInfoVector;
|
||||
}
|
||||
|
||||
const FileInfo* FileSystemGCWii::FindFileInfo(const std::string& _rFullPath)
|
||||
const FileInfoGCWii* FileSystemGCWii::FindFileInfo(const std::string& _rFullPath)
|
||||
{
|
||||
if (!m_Initialized)
|
||||
InitFileSystem();
|
||||
@ -279,7 +289,8 @@ void FileSystemGCWii::InitFileSystem()
|
||||
const std::optional<u32> root_size = m_rVolume->ReadSwapped<u32>(FSTOffset + 0x8, m_partition);
|
||||
if (!root_name_offset || !root_offset || !root_size)
|
||||
return;
|
||||
FileInfo root = {*root_name_offset, static_cast<u64>(*root_offset) << m_offset_shift, *root_size};
|
||||
FileInfoGCWii root(*root_name_offset, static_cast<u64>(*root_offset) << m_offset_shift,
|
||||
*root_size);
|
||||
|
||||
if (!root.IsDirectory())
|
||||
return;
|
||||
@ -287,7 +298,7 @@ void FileSystemGCWii::InitFileSystem()
|
||||
// 12 bytes (the size of a file entry) times 10 * 1024 * 1024 is 120 MiB,
|
||||
// more than total RAM in a Wii. No file system should use anywhere near that much.
|
||||
static const u32 ARBITRARY_FILE_SYSTEM_SIZE_LIMIT = 10 * 1024 * 1024;
|
||||
if (root.m_FileSize > ARBITRARY_FILE_SYSTEM_SIZE_LIMIT)
|
||||
if (root.GetSize() > ARBITRARY_FILE_SYSTEM_SIZE_LIMIT)
|
||||
{
|
||||
// Without this check, Dolphin can crash by trying to allocate too much
|
||||
// memory when loading the file systems of certain malformed disc images.
|
||||
@ -300,8 +311,8 @@ void FileSystemGCWii::InitFileSystem()
|
||||
PanicAlert("Wtf?");
|
||||
u64 NameTableOffset = FSTOffset;
|
||||
|
||||
m_FileInfoVector.reserve((size_t)root.m_FileSize);
|
||||
for (u32 i = 0; i < root.m_FileSize; i++)
|
||||
m_FileInfoVector.reserve((size_t)root.GetSize());
|
||||
for (u32 i = 0; i < root.GetSize(); i++)
|
||||
{
|
||||
const u64 read_offset = FSTOffset + (i * 0xC);
|
||||
const std::optional<u32> name_offset = m_rVolume->ReadSwapped<u32>(read_offset, m_partition);
|
||||
@ -323,7 +334,7 @@ size_t FileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _L
|
||||
|
||||
while (CurrentIndex < _LastIndex)
|
||||
{
|
||||
FileInfo& rFileInfo = m_FileInfoVector[CurrentIndex];
|
||||
FileInfoGCWii& rFileInfo = m_FileInfoVector[CurrentIndex];
|
||||
u64 const uOffset = _NameTableOffset + (rFileInfo.m_NameOffset & 0xFFFFFF);
|
||||
std::string const offset_str{GetStringFromOffset(uOffset)};
|
||||
bool const is_dir = rFileInfo.IsDirectory();
|
||||
@ -340,7 +351,7 @@ size_t FileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _L
|
||||
}
|
||||
|
||||
// check next index
|
||||
CurrentIndex = BuildFilenames(CurrentIndex + 1, (size_t)rFileInfo.m_FileSize,
|
||||
CurrentIndex = BuildFilenames(CurrentIndex + 1, (size_t)rFileInfo.GetSize(),
|
||||
rFileInfo.m_FullPath, _NameTableOffset);
|
||||
}
|
||||
|
||||
|
@ -17,15 +17,32 @@ namespace DiscIO
|
||||
class Volume;
|
||||
struct Partition;
|
||||
|
||||
class FileInfoGCWii : public FileInfo
|
||||
{
|
||||
public:
|
||||
FileInfoGCWii(u64 name_offset, u64 offset, u64 file_size);
|
||||
~FileInfoGCWii() override;
|
||||
|
||||
u64 GetOffset() const override { return m_Offset; }
|
||||
u64 GetSize() const override { return m_FileSize; }
|
||||
bool IsDirectory() const override { return (m_NameOffset & 0xFF000000) != 0; }
|
||||
// TODO: These shouldn't be public
|
||||
std::string m_FullPath;
|
||||
const u64 m_NameOffset = 0u;
|
||||
|
||||
private:
|
||||
const u64 m_Offset = 0u;
|
||||
const u64 m_FileSize = 0u;
|
||||
};
|
||||
|
||||
class FileSystemGCWii : public FileSystem
|
||||
{
|
||||
public:
|
||||
FileSystemGCWii(const Volume* _rVolume, const Partition& partition);
|
||||
virtual ~FileSystemGCWii();
|
||||
|
||||
~FileSystemGCWii() override;
|
||||
bool IsValid() const override { return m_Valid; }
|
||||
u64 GetFileSize(const std::string& _rFullPath) override;
|
||||
const std::vector<FileInfo>& GetFileList() override;
|
||||
const std::vector<FileInfoGCWii>& GetFileList() override;
|
||||
std::string GetFileName(u64 _Address) override;
|
||||
u64 ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize,
|
||||
u64 _OffsetInFile) override;
|
||||
@ -39,10 +56,10 @@ private:
|
||||
bool m_Initialized;
|
||||
bool m_Valid;
|
||||
u32 m_offset_shift;
|
||||
std::vector<FileInfo> m_FileInfoVector;
|
||||
std::vector<FileInfoGCWii> m_FileInfoVector;
|
||||
|
||||
std::string GetStringFromOffset(u64 _Offset) const;
|
||||
const FileInfo* FindFileInfo(const std::string& _rFullPath);
|
||||
const FileInfoGCWii* FindFileInfo(const std::string& _rFullPath);
|
||||
bool DetectFileSystem();
|
||||
void InitFileSystem();
|
||||
size_t BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex,
|
||||
|
@ -9,6 +9,10 @@
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
FileInfo::~FileInfo()
|
||||
{
|
||||
}
|
||||
|
||||
FileSystem::FileSystem(const Volume* _rVolume, const Partition& partition)
|
||||
: m_rVolume(_rVolume), m_partition(partition)
|
||||
{
|
||||
|
@ -14,22 +14,20 @@
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
// TODO: eww
|
||||
class FileInfoGCWii;
|
||||
|
||||
// file info of an FST entry
|
||||
struct FileInfo
|
||||
class FileInfo
|
||||
{
|
||||
u64 m_NameOffset = 0u;
|
||||
u64 m_Offset = 0u;
|
||||
u64 m_FileSize = 0u;
|
||||
std::string m_FullPath;
|
||||
public:
|
||||
virtual ~FileInfo();
|
||||
|
||||
bool IsDirectory() const { return (m_NameOffset & 0xFF000000) != 0; }
|
||||
FileInfo(u64 name_offset, u64 offset, u64 filesize)
|
||||
: m_NameOffset(name_offset), m_Offset(offset), m_FileSize(filesize)
|
||||
{
|
||||
}
|
||||
|
||||
FileInfo(FileInfo const&) = default;
|
||||
FileInfo() = default;
|
||||
// Not guaranteed to return a meaningful value for directories
|
||||
virtual u64 GetOffset() const = 0;
|
||||
// Not guaranteed to return a meaningful value for directories
|
||||
virtual u64 GetSize() const = 0;
|
||||
virtual bool IsDirectory() const = 0;
|
||||
};
|
||||
|
||||
class FileSystem
|
||||
@ -39,7 +37,8 @@ public:
|
||||
|
||||
virtual ~FileSystem();
|
||||
virtual bool IsValid() const = 0;
|
||||
virtual const std::vector<FileInfo>& GetFileList() = 0;
|
||||
// TODO: Should only return FileInfo, not FileInfoGCWii
|
||||
virtual const std::vector<FileInfoGCWii>& GetFileList() = 0;
|
||||
virtual u64 GetFileSize(const std::string& _rFullPath) = 0;
|
||||
virtual u64 ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _MaxBufferSize,
|
||||
u64 _OffsetInFile = 0) = 0;
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "DiscIO/Filesystem.h"
|
||||
// TODO: eww
|
||||
#include "DiscIO/FileSystemGCWii.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
#include "DolphinWX/ISOFile.h"
|
||||
#include "DolphinWX/WxUtils.h"
|
||||
@ -84,14 +86,14 @@ wxImageList* LoadIconBitmaps(const wxWindow* context)
|
||||
}
|
||||
|
||||
size_t CreateDirectoryTree(wxTreeCtrl* tree_ctrl, wxTreeItemId parent,
|
||||
const std::vector<DiscIO::FileInfo>& file_infos,
|
||||
const std::vector<DiscIO::FileInfoGCWii>& file_infos,
|
||||
const size_t first_index, const size_t last_index)
|
||||
{
|
||||
size_t current_index = first_index;
|
||||
|
||||
while (current_index < last_index)
|
||||
{
|
||||
const DiscIO::FileInfo& file_info = file_infos[current_index];
|
||||
const DiscIO::FileInfoGCWii& file_info = file_infos[current_index];
|
||||
std::string file_path = file_info.m_FullPath;
|
||||
|
||||
// Trim the trailing '/' if it exists.
|
||||
@ -113,7 +115,7 @@ size_t CreateDirectoryTree(wxTreeCtrl* tree_ctrl, wxTreeItemId parent,
|
||||
{
|
||||
const wxTreeItemId item = tree_ctrl->AppendItem(parent, StrToWxStr(file_path), ICON_FOLDER);
|
||||
current_index = CreateDirectoryTree(tree_ctrl, item, file_infos, current_index + 1,
|
||||
static_cast<size_t>(file_info.m_FileSize));
|
||||
static_cast<size_t>(file_info.GetSize()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -126,12 +128,12 @@ size_t CreateDirectoryTree(wxTreeCtrl* tree_ctrl, wxTreeItemId parent,
|
||||
}
|
||||
|
||||
size_t CreateDirectoryTree(wxTreeCtrl* tree_ctrl, wxTreeItemId parent,
|
||||
const std::vector<DiscIO::FileInfo>& file_infos)
|
||||
const std::vector<DiscIO::FileInfoGCWii>& file_infos)
|
||||
{
|
||||
if (file_infos.empty())
|
||||
return 0;
|
||||
|
||||
return CreateDirectoryTree(tree_ctrl, parent, file_infos, 1, file_infos.at(0).m_FileSize);
|
||||
return CreateDirectoryTree(tree_ctrl, parent, file_infos, 1, file_infos.at(0).GetSize());
|
||||
}
|
||||
|
||||
WiiPartition* FindWiiPartition(wxTreeCtrl* tree_ctrl, const wxString& label)
|
||||
@ -452,7 +454,7 @@ void FilesystemPanel::ExtractDirectories(const std::string& full_path,
|
||||
const std::string& output_folder,
|
||||
DiscIO::FileSystem* filesystem)
|
||||
{
|
||||
const std::vector<DiscIO::FileInfo>& fst = filesystem->GetFileList();
|
||||
const std::vector<DiscIO::FileInfoGCWii>& fst = filesystem->GetFileList();
|
||||
|
||||
u32 index = 0;
|
||||
u32 size = 0;
|
||||
@ -473,7 +475,7 @@ void FilesystemPanel::ExtractDirectories(const std::string& full_path,
|
||||
if (fst[index].m_FullPath == full_path)
|
||||
{
|
||||
INFO_LOG(DISCIO, "Found the directory at %u", index);
|
||||
size = static_cast<u32>(fst[index].m_FileSize);
|
||||
size = static_cast<u32>(fst[index].GetSize());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user