Merge pull request #1833 from lioncash/clean
service/fsp_srv: Implement CleanDirectoryRecursively
This commit is contained in:
		| @@ -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); | ||||||
| @@ -431,10 +453,34 @@ std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFile(std::string_view name) | |||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileAbsolute(std::string_view path) { | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileRelative(std::string_view path) { | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryAbsolute(std::string_view path) { | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryRelative(std::string_view path) { | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  |  | ||||||
| bool ReadOnlyVfsDirectory::DeleteSubdirectory(std::string_view name) { | bool ReadOnlyVfsDirectory::DeleteSubdirectory(std::string_view name) { | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool ReadOnlyVfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) { | ||||||
|  |     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. | ||||||
| @@ -276,7 +282,13 @@ public: | |||||||
|     bool IsReadable() const override; |     bool IsReadable() const override; | ||||||
|     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; | ||||||
|  |     std::shared_ptr<VfsFile> CreateFileAbsolute(std::string_view path) override; | ||||||
|  |     std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override; | ||||||
|  |     std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path) override; | ||||||
|  |     std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override; | ||||||
|     bool DeleteSubdirectory(std::string_view name) override; |     bool DeleteSubdirectory(std::string_view name) override; | ||||||
|  |     bool DeleteSubdirectoryRecursive(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
	
	Block a user
	 bunnei
					bunnei