diff options
| author | JosJuice <josjuice@gmail.com> | 2016-12-25 22:35:38 +0100 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2016-12-25 22:35:38 +0100 |
| commit | a502f069e8228fb0b63db44ffccc4b2e13201418 (patch) | |
| tree | c6df49ead6942166ad5fabc7805da7498b8cb52b /Source/Core/DiscIO/VolumeDirectory.cpp | |
| parent | 09c6148abaaad47bec90ffa8c43b9fff28db2bfd (diff) | |
VolumeDirectory: Sort the FST
We can't rely on the OS returning files and directories
in a deterministic order, so we should sort them on our own
if we want VolumeDirectory to work for movies and netplay.
Diffstat (limited to 'Source/Core/DiscIO/VolumeDirectory.cpp')
| -rw-r--r-- | Source/Core/DiscIO/VolumeDirectory.cpp | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/Source/Core/DiscIO/VolumeDirectory.cpp b/Source/Core/DiscIO/VolumeDirectory.cpp index 1d58f76052..60bb9f40f0 100644 --- a/Source/Core/DiscIO/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/VolumeDirectory.cpp @@ -363,10 +363,7 @@ void CVolumeDirectory::BuildFST() // write root entry WriteEntryData(fstOffset, DIRECTORY_ENTRY, 0, 0, totalEntries); - for (auto& entry : rootEntry.children) - { - WriteEntry(entry, fstOffset, nameOffset, curDataAddress, rootOffset); - } + WriteDirectory(rootEntry, fstOffset, nameOffset, curDataAddress, rootOffset); // overflow check _dbg_assert_(DVDINTERFACE, nameOffset == m_totalNameSize); @@ -443,34 +440,41 @@ void CVolumeDirectory::WriteEntryName(u32& nameOffset, const std::string& name) nameOffset += (u32)(name.length() + 1); } -void CVolumeDirectory::WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset, - u64& dataOffset, u32 parentEntryNum) +void CVolumeDirectory::WriteDirectory(const File::FSTEntry& parent_entry, u32& fstOffset, + u32& nameOffset, u64& dataOffset, u32 parentEntryNum) { - if (entry.isDirectory) - { - u32 myOffset = fstOffset; - u32 myEntryNum = myOffset / ENTRY_SIZE; - WriteEntryData(fstOffset, DIRECTORY_ENTRY, nameOffset, parentEntryNum, - myEntryNum + entry.size + 1); - WriteEntryName(nameOffset, entry.virtualName); + std::vector<File::FSTEntry> sorted_entries = parent_entry.children; - for (const auto& child : entry.children) + std::sort(sorted_entries.begin(), sorted_entries.end(), + [](const File::FSTEntry& one, const File::FSTEntry& two) { + return one.virtualName < two.virtualName; + }); + + for (const File::FSTEntry& entry : sorted_entries) + { + if (entry.isDirectory) { - WriteEntry(child, fstOffset, nameOffset, dataOffset, myEntryNum); + u32 myOffset = fstOffset; + u32 myEntryNum = myOffset / ENTRY_SIZE; + WriteEntryData(fstOffset, DIRECTORY_ENTRY, nameOffset, parentEntryNum, + myEntryNum + entry.size + 1); + WriteEntryName(nameOffset, entry.virtualName); + + WriteDirectory(entry, fstOffset, nameOffset, dataOffset, myEntryNum); } - } - else - { - // put entry in FST - WriteEntryData(fstOffset, FILE_ENTRY, nameOffset, dataOffset, entry.size); - WriteEntryName(nameOffset, entry.virtualName); + else + { + // put entry in FST + WriteEntryData(fstOffset, FILE_ENTRY, nameOffset, dataOffset, entry.size); + WriteEntryName(nameOffset, entry.virtualName); - // write entry to virtual disk - _dbg_assert_(DVDINTERFACE, m_virtualDisk.find(dataOffset) == m_virtualDisk.end()); - m_virtualDisk.emplace(dataOffset, entry.physicalName); + // write entry to virtual disk + _dbg_assert_(DVDINTERFACE, m_virtualDisk.find(dataOffset) == m_virtualDisk.end()); + m_virtualDisk.emplace(dataOffset, entry.physicalName); - // 4 byte aligned - dataOffset = Common::AlignUp(dataOffset + std::max<u64>(entry.size, 1ull), 0x8000ull); + // 4 byte aligned + dataOffset = Common::AlignUp(dataOffset + std::max<u64>(entry.size, 1ull), 0x8000ull); + } } } |
