mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-31 01:59:52 -06:00
Rewrite FileSearch and improve ScanDirectoryTree.
- FileSearch is now just one function, and it converts the original glob into a regex on all platforms rather than relying on native Windows pattern matching on there and a complete hack elsewhere. It now supports recursion out of the box rather than manually expanding into a full list of directories in multiple call sites. - This adds a GCC >= 4.9 dependency due to older versions having outright broken <regex>. MSVC is fine with it. - ScanDirectoryTree returns the parent entry rather than filling parts of it in via reference. The count is now stored in the entry like it was for subdirectories. - .glsl file search is now done with DoFileSearch. - IOCTLV_READ_DIR now uses ScanDirectoryTree directly and sorts the results after replacements for better determinism.
This commit is contained in:
@ -151,16 +151,7 @@ GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, u
|
||||
hdrfile.ReadBytes(&m_hdr, BLOCK_SIZE);
|
||||
}
|
||||
|
||||
File::FSTEntry FST_Temp;
|
||||
File::ScanDirectoryTree(m_SaveDirectory, FST_Temp);
|
||||
|
||||
CFileSearch::XStringVector Directory;
|
||||
Directory.push_back(m_SaveDirectory);
|
||||
CFileSearch::XStringVector Extensions;
|
||||
Extensions.push_back("*.gci");
|
||||
|
||||
CFileSearch FileSearch(Extensions, Directory);
|
||||
const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames();
|
||||
std::vector<std::string> rFilenames = DoFileSearch({"*.gci"}, {m_SaveDirectory});
|
||||
|
||||
if (rFilenames.size() > 112)
|
||||
{
|
||||
@ -170,7 +161,7 @@ GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, u
|
||||
4000);
|
||||
}
|
||||
|
||||
for (auto gciFile : rFilenames)
|
||||
for (const std::string& gciFile : rFilenames)
|
||||
{
|
||||
if (m_saves.size() == DIRLEN)
|
||||
{
|
||||
|
@ -67,9 +67,8 @@ void CWiiSaveCrypted::ExportAllSaves()
|
||||
const u32 path_mask = 0x00010000;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
File::FSTEntry fst_tmp;
|
||||
std::string folder = StringFromFormat("%s/%08x/", title_folder.c_str(), path_mask | i);
|
||||
File::ScanDirectoryTree(folder, fst_tmp);
|
||||
File::FSTEntry fst_tmp = File::ScanDirectoryTree(folder, false);
|
||||
|
||||
for (const File::FSTEntry& entry : fst_tmp.children)
|
||||
{
|
||||
@ -627,8 +626,7 @@ void CWiiSaveCrypted::ScanForFiles(const std::string& save_directory, std::vecto
|
||||
file_list.push_back(directories[i]);
|
||||
}
|
||||
|
||||
File::FSTEntry fst_tmp;
|
||||
File::ScanDirectoryTree(directories[i], fst_tmp);
|
||||
File::FSTEntry fst_tmp = File::ScanDirectoryTree(directories[i], false);
|
||||
for (const File::FSTEntry& elem : fst_tmp.children)
|
||||
{
|
||||
if (elem.virtualName != "banner.bin")
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FileSearch.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/NandPaths.h"
|
||||
#include "Common/StringUtil.h"
|
||||
@ -106,25 +105,28 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
||||
break;
|
||||
}
|
||||
|
||||
// make a file search
|
||||
CFileSearch::XStringVector Directories;
|
||||
Directories.push_back(DirName);
|
||||
|
||||
CFileSearch::XStringVector Extensions;
|
||||
Extensions.push_back("*.*");
|
||||
|
||||
CFileSearch FileSearch(Extensions, Directories);
|
||||
File::FSTEntry entry = File::ScanDirectoryTree(DirName, false);
|
||||
|
||||
// it is one
|
||||
if ((CommandBuffer.InBuffer.size() == 1) && (CommandBuffer.PayloadBuffer.size() == 1))
|
||||
{
|
||||
size_t numFile = FileSearch.GetFileNames().size();
|
||||
size_t numFile = entry.children.size();
|
||||
INFO_LOG(WII_IPC_FILEIO, "\t%lu files found", (unsigned long)numFile);
|
||||
|
||||
Memory::Write_U32((u32)numFile, CommandBuffer.PayloadBuffer[0].m_Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (File::FSTEntry& child : entry.children)
|
||||
{
|
||||
// Decode entities of invalid file system characters so that
|
||||
// games (such as HP:HBP) will be able to find what they expect.
|
||||
for (const Common::replace_t& r : replacements)
|
||||
child.virtualName = ReplaceAll(child.virtualName, r.second, {r.first});
|
||||
}
|
||||
|
||||
std::sort(entry.children.begin(), entry.children.end(), [](const File::FSTEntry& one, const File::FSTEntry& two) { return one.virtualName < two.virtualName; });
|
||||
|
||||
u32 MaxEntries = Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address);
|
||||
|
||||
memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0, CommandBuffer.PayloadBuffer[0].m_Size);
|
||||
@ -132,22 +134,10 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
||||
size_t numFiles = 0;
|
||||
char* pFilename = (char*)Memory::GetPointer((u32)(CommandBuffer.PayloadBuffer[0].m_Address));
|
||||
|
||||
for (size_t i=0; i<FileSearch.GetFileNames().size(); i++)
|
||||
for (size_t i=0; i < entry.children.size() && i < MaxEntries; i++)
|
||||
{
|
||||
if (i >= MaxEntries)
|
||||
break;
|
||||
const std::string& FileName = entry.children[i].virtualName;
|
||||
|
||||
std::string name, ext;
|
||||
SplitPath(FileSearch.GetFileNames()[i], nullptr, &name, &ext);
|
||||
std::string FileName = name + ext;
|
||||
|
||||
// Decode entities of invalid file system characters so that
|
||||
// games (such as HP:HBP) will be able to find what they expect.
|
||||
for (const Common::replace_t& r : replacements)
|
||||
{
|
||||
for (size_t j = 0; (j = FileName.find(r.second, j)) != FileName.npos; ++j)
|
||||
FileName.replace(j, r.second.length(), 1, r.first);
|
||||
}
|
||||
|
||||
strcpy(pFilename, FileName.c_str());
|
||||
pFilename += FileName.length();
|
||||
@ -192,10 +182,9 @@ IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
||||
}
|
||||
else
|
||||
{
|
||||
File::FSTEntry parentDir;
|
||||
// add one for the folder itself, allows some games to create their save files
|
||||
// R8XE52 (Jurassic: The Hunted), STEETR (Tetris Party Deluxe) now create their saves with this change
|
||||
iNodes = 1 + File::ScanDirectoryTree(path, parentDir);
|
||||
File::FSTEntry parentDir = File::ScanDirectoryTree(path, true);
|
||||
// add one for the folder itself
|
||||
iNodes = 1 + (u32)parentDir.size;
|
||||
|
||||
u64 totalSize = ComputeTotalFileSize(parentDir); // "Real" size, to be converted to nand blocks
|
||||
|
||||
@ -542,8 +531,7 @@ void CWII_IPC_HLE_Device_fs::DoState(PointerWrap& p)
|
||||
{
|
||||
//recurse through tmp and save dirs and files
|
||||
|
||||
File::FSTEntry parentEntry;
|
||||
File::ScanDirectoryTree(Path, parentEntry);
|
||||
File::FSTEntry parentEntry = File::ScanDirectoryTree(Path, true);
|
||||
std::deque<File::FSTEntry> todo;
|
||||
todo.insert(todo.end(), parentEntry.children.begin(),
|
||||
parentEntry.children.end());
|
||||
|
Reference in New Issue
Block a user