MemStick: Delete the originals by top-level folder on content URIs

DeleteDir takes a folder's contents along there, so a copying move's cleanup
is one storage call per top-level item instead of one per file and folder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-11-06 16:16:29 +01:00
1 parent ec532bd420
commit edff9f4a95
2 files changed
+31 -2

No files matched your search

+28 -2
View File
@@ -516,9 +516,35 @@ MoveResult *MoveDirectoryContentsSafe(Path moveSrc, Path moveDest, MoveProgressR
return fail("Couldn't switch to the new folder", 0);
}
// Delete the originals: the files, then the folders. On content URIs DeleteDir would take the files
// along anyway, but on native paths it only removes empty folders.
progressReporter.SetPhase(ms->T("Deleting from old folder..."));
if (moveSrc.Type() == PathType::CONTENT_URI) {
// DeleteDir takes a folder's contents along here, so only the top level needs deleting, one call
// each instead of one per file. All of it is safely copied: the listing fails if any part of the
// tree can't be read.
std::vector<std::string> topLevel;
for (const std::string &dirSuffix : directorySuffixesToCreate) {
if (dirSuffix.find('/') == std::string::npos) {
topLevel.push_back(dirSuffix);
}
}
const size_t dirCount = topLevel.size();
for (const FileSuffix &fileSuffix : fileSuffixesToMove) {
if (fileSuffix.suffix.find('/') == std::string::npos) {
topLevel.push_back(fileSuffix.suffix);
}
}
for (size_t i = 0; i < topLevel.size(); i++) {
const Path item = moveSrc / topLevel[i];
progressReporter.SetProgress(topLevel[i], i, topLevel.size());
if (!(i < dirCount ? File::DeleteDir(item) : File::Delete(item))) {
// It's safely copied, so this only leaves a duplicate behind.
WARN_LOG(Log::System, "Failed to delete '%s' after copying it", item.c_str());
}
}
return new MoveResult{ true, "", 0 };
}
// Native paths: the files, then the folders, since DeleteDir only removes empty ones.
for (size_t i = 0; i < fileSuffixesToMove.size(); i++) {
const Path from = moveSrc / fileSuffixesToMove[i].suffix;
progressReporter.SetProgress(fileSuffixesToMove[i].suffix, i, fileSuffixesToMove.size());
+3
View File
@@ -292,6 +292,9 @@ int RunStorageTests(const Path &root, const std::function<void(const StorageTest
CHECK(ReadAll(dest / "PSP/SAVEDATA/GAME2/DATA.BIN") == "other");
CHECK(ReadAll(dest / "PSP/SYSTEM/ppsspp.ini") == "ini");
CHECK(!File::Exists(src / "PSP/SAVEDATA/GAME1/DATA.BIN"));
// The old folders go too.
CHECK(!File::Exists(src / "PSP/SAVEDATA"));
CHECK(!File::Exists(src / "PSP/SYSTEM"));
return "";
});