Merge pull request #1875 from sahchandler/master

Reduce number of allocations in CFileSystemGCWii::BuildFilenames
This commit is contained in:
Ryan Houdek 2015-01-11 18:06:36 -06:00
commit 5c1caded4d
2 changed files with 45 additions and 42 deletions

View File

@ -206,8 +206,7 @@ u32 CFileSystemGCWii::Read32(u64 _Offset) const
std::string CFileSystemGCWii::GetStringFromOffset(u64 _Offset) const std::string CFileSystemGCWii::GetStringFromOffset(u64 _Offset) const
{ {
std::string data; std::string data(255, 0x00);
data.resize(255);
m_rVolume->Read(_Offset, data.size(), (u8*)&data[0], m_Wii); m_rVolume->Read(_Offset, data.size(), (u8*)&data[0], m_Wii);
data.erase(std::find(data.begin(), data.end(), 0x00), data.end()); data.erase(std::find(data.begin(), data.end(), 0x00), data.end());
@ -263,40 +262,41 @@ bool CFileSystemGCWii::DetectFileSystem()
void CFileSystemGCWii::InitFileSystem() void CFileSystemGCWii::InitFileSystem()
{ {
m_Initialized = true; m_Initialized = true;
u32 const shift = GetOffsetShift();
// read the whole FST // read the whole FST
u64 FSTOffset = (u64)Read32(0x424) << GetOffsetShift(); u64 FSTOffset = static_cast<u64>(Read32(0x424)) << shift;
// u32 FSTSize = Read32(0x428); // u32 FSTSize = Read32(0x428);
// u32 FSTMaxSize = Read32(0x42C); // u32 FSTMaxSize = Read32(0x42C);
// read all fileinfos // read all fileinfos
SFileInfo Root; SFileInfo Root
Root.m_NameOffset = Read32(FSTOffset + 0x0);
Root.m_Offset = (u64)Read32(FSTOffset + 0x4) << GetOffsetShift();
Root.m_FileSize = Read32(FSTOffset + 0x8);
if (Root.IsDirectory())
{ {
if (m_FileInfoVector.size()) Read32(FSTOffset + 0x0),
PanicAlert("Wtf?"); static_cast<u64>(FSTOffset + 0x4) << shift,
u64 NameTableOffset = FSTOffset; Read32(FSTOffset + 0x8)
};
m_FileInfoVector.reserve((unsigned int)Root.m_FileSize); if (!Root.IsDirectory())
for (u32 i = 0; i < Root.m_FileSize; i++) return;
{
SFileInfo sfi;
u64 Offset = FSTOffset + (i * 0xC);
sfi.m_NameOffset = Read32(Offset + 0x0);
sfi.m_Offset = (u64)Read32(Offset + 0x4) << GetOffsetShift();
sfi.m_FileSize = Read32(Offset + 0x8);
m_FileInfoVector.push_back(sfi); if (m_FileInfoVector.size())
NameTableOffset += 0xC; PanicAlert("Wtf?");
} u64 NameTableOffset = FSTOffset;
BuildFilenames(1, m_FileInfoVector.size(), "", NameTableOffset); m_FileInfoVector.reserve((size_t)Root.m_FileSize);
for (u32 i = 0; i < Root.m_FileSize; i++)
{
u64 const read_offset = FSTOffset + (i * 0xC);
u64 const name_offset = Read32(read_offset + 0x0);
u64 const offset = static_cast<u64>(Read32(read_offset + 0x4)) << shift;
u64 const size = Read32(read_offset + 0x8);
m_FileInfoVector.emplace_back(name_offset, offset, size);
NameTableOffset += 0xC;
} }
BuildFilenames(1, m_FileInfoVector.size(), "", NameTableOffset);
} }
size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const std::string& _szDirectory, u64 _NameTableOffset) size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const std::string& _szDirectory, u64 _NameTableOffset)
@ -307,19 +307,22 @@ size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _
{ {
SFileInfo& rFileInfo = m_FileInfoVector[CurrentIndex]; SFileInfo& rFileInfo = m_FileInfoVector[CurrentIndex];
u64 const uOffset = _NameTableOffset + (rFileInfo.m_NameOffset & 0xFFFFFF); u64 const uOffset = _NameTableOffset + (rFileInfo.m_NameOffset & 0xFFFFFF);
std::string const offset_str { GetStringFromOffset(uOffset) };
bool const is_dir = rFileInfo.IsDirectory();
rFileInfo.m_FullPath.reserve(_szDirectory.size() + offset_str.size());
rFileInfo.m_FullPath = _szDirectory + GetStringFromOffset(uOffset); rFileInfo.m_FullPath.append(_szDirectory.data(), _szDirectory.size())
.append(offset_str.data(), offset_str.size())
.append("/", size_t(is_dir));
// check next index if (!is_dir)
if (rFileInfo.IsDirectory())
{
rFileInfo.m_FullPath += '/';
CurrentIndex = BuildFilenames(CurrentIndex + 1, (size_t) rFileInfo.m_FileSize, rFileInfo.m_FullPath, _NameTableOffset);
}
else
{ {
++CurrentIndex; ++CurrentIndex;
continue;
} }
// check next index
CurrentIndex = BuildFilenames(CurrentIndex + 1, (size_t) rFileInfo.m_FileSize, rFileInfo.m_FullPath, _NameTableOffset);
} }
return CurrentIndex; return CurrentIndex;

View File

@ -19,21 +19,21 @@ class IVolume;
// file info of an FST entry // file info of an FST entry
struct SFileInfo struct SFileInfo
{ {
u64 m_NameOffset; u64 m_NameOffset = 0u;
u64 m_Offset; u64 m_Offset = 0u;
u64 m_FileSize; u64 m_FileSize = 0u;
std::string m_FullPath; std::string m_FullPath;
bool IsDirectory() const { return (m_NameOffset & 0xFF000000) != 0; } bool IsDirectory() const { return (m_NameOffset & 0xFF000000) != 0; }
SFileInfo() : m_NameOffset(0), m_Offset(0), m_FileSize(0) SFileInfo(u64 name_offset, u64 offset, u64 filesize) :
{ m_NameOffset(name_offset),
} m_Offset(offset),
m_FileSize(filesize)
{ }
SFileInfo(const SFileInfo& rhs) : m_NameOffset(rhs.m_NameOffset), SFileInfo (SFileInfo const&) = default;
m_Offset(rhs.m_Offset), m_FileSize(rhs.m_FileSize), m_FullPath(rhs.m_FullPath) SFileInfo () = default;
{
}
}; };
class IFileSystem class IFileSystem