service/fsp_srv: Implement CleanDirectoryRecursively
This is the same behavior-wise as DeleteDirectoryRecursively, with the only difference being that it doesn't delete the top level directory in the hierarchy, so given: root_dir/ - some_dir/ - File.txt - OtherFile.txt The end result is just: root_dir/
This commit is contained in:
parent
b7104263ba
commit
a7d9fe993a
|
@ -384,6 +384,28 @@ bool VfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VfsDirectory::CleanSubdirectoryRecursive(std::string_view name) {
|
||||||
|
auto dir = GetSubdirectory(name);
|
||||||
|
if (dir == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = true;
|
||||||
|
for (const auto& file : dir->GetFiles()) {
|
||||||
|
if (!dir->DeleteFile(file->GetName())) {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& sdir : dir->GetSubdirectories()) {
|
||||||
|
if (!dir->DeleteSubdirectoryRecursive(sdir->GetName())) {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
bool VfsDirectory::Copy(std::string_view src, std::string_view dest) {
|
bool VfsDirectory::Copy(std::string_view src, std::string_view dest) {
|
||||||
const auto f1 = GetFile(src);
|
const auto f1 = GetFile(src);
|
||||||
auto f2 = CreateFile(dest);
|
auto f2 = CreateFile(dest);
|
||||||
|
@ -435,6 +457,10 @@ bool ReadOnlyVfsDirectory::DeleteSubdirectory(std::string_view name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsDirectory::CleanSubdirectoryRecursive(std::string_view name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) {
|
bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,12 +245,18 @@ public:
|
||||||
// any failure.
|
// any failure.
|
||||||
virtual std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path);
|
virtual std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path);
|
||||||
|
|
||||||
// Deletes the subdirectory with name and returns true on success.
|
// Deletes the subdirectory with the given name and returns true on success.
|
||||||
virtual bool DeleteSubdirectory(std::string_view name) = 0;
|
virtual bool DeleteSubdirectory(std::string_view name) = 0;
|
||||||
// Deletes all subdirectories and files of subdirectory with name recirsively and then deletes
|
|
||||||
// the subdirectory. Returns true on success.
|
// Deletes all subdirectories and files within the provided directory and then deletes
|
||||||
|
// the directory itself. Returns true on success.
|
||||||
virtual bool DeleteSubdirectoryRecursive(std::string_view name);
|
virtual bool DeleteSubdirectoryRecursive(std::string_view name);
|
||||||
// Returnes whether or not the file with name name was deleted successfully.
|
|
||||||
|
// Deletes all subdirectories and files within the provided directory.
|
||||||
|
// Unlike DeleteSubdirectoryRecursive, this does not delete the provided directory.
|
||||||
|
virtual bool CleanSubdirectoryRecursive(std::string_view name);
|
||||||
|
|
||||||
|
// Returns whether or not the file with name name was deleted successfully.
|
||||||
virtual bool DeleteFile(std::string_view name) = 0;
|
virtual bool DeleteFile(std::string_view name) = 0;
|
||||||
|
|
||||||
// Returns whether or not this directory was renamed to name.
|
// Returns whether or not this directory was renamed to name.
|
||||||
|
@ -277,6 +283,7 @@ public:
|
||||||
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
|
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
|
||||||
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
|
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
|
||||||
bool DeleteSubdirectory(std::string_view name) override;
|
bool DeleteSubdirectory(std::string_view name) override;
|
||||||
|
bool CleanSubdirectoryRecursive(std::string_view name) override;
|
||||||
bool DeleteFile(std::string_view name) override;
|
bool DeleteFile(std::string_view name) override;
|
||||||
bool Rename(std::string_view name) override;
|
bool Rename(std::string_view name) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -113,6 +113,18 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::str
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResultCode VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::string& path) const {
|
||||||
|
const std::string sanitized_path(FileUtil::SanitizePath(path));
|
||||||
|
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(sanitized_path));
|
||||||
|
|
||||||
|
if (!dir->CleanSubdirectoryRecursive(FileUtil::GetFilename(sanitized_path))) {
|
||||||
|
// TODO(DarkLordZach): Find a better error code for this
|
||||||
|
return ResultCode(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
|
ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
|
||||||
const std::string& dest_path_) const {
|
const std::string& dest_path_) const {
|
||||||
std::string src_path(FileUtil::SanitizePath(src_path_));
|
std::string src_path(FileUtil::SanitizePath(src_path_));
|
||||||
|
|
|
@ -113,6 +113,18 @@ public:
|
||||||
*/
|
*/
|
||||||
ResultCode DeleteDirectoryRecursively(const std::string& path) const;
|
ResultCode DeleteDirectoryRecursively(const std::string& path) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans the specified directory. This is similar to DeleteDirectoryRecursively,
|
||||||
|
* in that it deletes all the contents of the specified directory, however, this
|
||||||
|
* function does *not* delete the directory itself. It only deletes everything
|
||||||
|
* within it.
|
||||||
|
*
|
||||||
|
* @param path Path relative to the archive.
|
||||||
|
*
|
||||||
|
* @return Result of the operation.
|
||||||
|
*/
|
||||||
|
ResultCode CleanDirectoryRecursively(const std::string& path) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename a File specified by its path
|
* Rename a File specified by its path
|
||||||
* @param src_path Source path relative to the archive
|
* @param src_path Source path relative to the archive
|
||||||
|
|
|
@ -291,7 +291,7 @@ public:
|
||||||
{10, &IFileSystem::Commit, "Commit"},
|
{10, &IFileSystem::Commit, "Commit"},
|
||||||
{11, nullptr, "GetFreeSpaceSize"},
|
{11, nullptr, "GetFreeSpaceSize"},
|
||||||
{12, nullptr, "GetTotalSpaceSize"},
|
{12, nullptr, "GetTotalSpaceSize"},
|
||||||
{13, nullptr, "CleanDirectoryRecursively"},
|
{13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"},
|
||||||
{14, nullptr, "GetFileTimeStampRaw"},
|
{14, nullptr, "GetFileTimeStampRaw"},
|
||||||
{15, nullptr, "QueryEntry"},
|
{15, nullptr, "QueryEntry"},
|
||||||
};
|
};
|
||||||
|
@ -361,6 +361,16 @@ public:
|
||||||
rb.Push(backend.DeleteDirectoryRecursively(name));
|
rb.Push(backend.DeleteDirectoryRecursively(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CleanDirectoryRecursively(Kernel::HLERequestContext& ctx) {
|
||||||
|
const auto file_buffer = ctx.ReadBuffer();
|
||||||
|
const std::string name = Common::StringFromBuffer(file_buffer);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_FS, "called. Directory: {}", name);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(backend.CleanDirectoryRecursively(name));
|
||||||
|
}
|
||||||
|
|
||||||
void RenameFile(Kernel::HLERequestContext& ctx) {
|
void RenameFile(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
|
Reference in New Issue