diff options
Diffstat (limited to 'src/zencore/filesystem.cpp')
| -rw-r--r-- | src/zencore/filesystem.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp index 06cda7382..4a26c64e7 100644 --- a/src/zencore/filesystem.cpp +++ b/src/zencore/filesystem.cpp @@ -613,6 +613,103 @@ CopyFile(std::filesystem::path FromPath, std::filesystem::path ToPath, const Cop } void +CopyTree(std::filesystem::path FromPath, std::filesystem::path ToPath, const CopyFileOptions& Options) +{ + // Validate arguments + + if (FromPath.empty() || !std::filesystem::is_directory(FromPath)) + throw std::runtime_error("invalid CopyTree source directory specified"); + + if (ToPath.empty()) + throw std::runtime_error("no CopyTree target specified"); + + if (std::filesystem::exists(ToPath)) + { + if (!std::filesystem::is_directory(ToPath)) + { + throw std::runtime_error(fmt::format("specified CopyTree target '{}' is not a directory", ToPath)); + } + } + else + { + std::filesystem::create_directories(ToPath); + } + + struct CopyVisitor : public FileSystemTraversal::TreeVisitor + { + CopyVisitor(std::filesystem::path InBasePath, zen::CopyFileOptions InCopyOptions) : BasePath(InBasePath), CopyOptions(InCopyOptions) + { + } + + virtual void VisitFile(const std::filesystem::path& Parent, const path_view& File, uint64_t FileSize) override + { + std::error_code Ec; + const std::filesystem::path Relative = std::filesystem::relative(Parent, BasePath, Ec); + + if (Ec) + { + FailedFileCount++; + } + else + { + const std::filesystem::path FromPath = Parent / File; + std::filesystem::path ToPath; + + if (Relative.compare(".")) + { + zen::CreateDirectories(TargetPath / Relative); + + ToPath = TargetPath / Relative / File; + } + else + { + ToPath = TargetPath / File; + } + + try + { + if (zen::CopyFile(FromPath, ToPath, CopyOptions)) + { + ++FileCount; + ByteCount += FileSize; + } + else + { + throw std::runtime_error("CopyFile failed in an unexpected way"); + } + } + catch (std::exception& Ex) + { + ++FailedFileCount; + + throw std::runtime_error(fmt::format("failed to copy '{}' to '{}': '{}'", FromPath, ToPath, Ex.what())); + } + } + } + + virtual bool VisitDirectory(const std::filesystem::path&, const path_view&) override { return true; } + + std::filesystem::path BasePath; + std::filesystem::path TargetPath; + zen::CopyFileOptions CopyOptions; + int FileCount = 0; + uint64_t ByteCount = 0; + int FailedFileCount = 0; + }; + + CopyVisitor Visitor{FromPath, Options}; + Visitor.TargetPath = ToPath; + + FileSystemTraversal Traversal; + Traversal.TraverseFileSystem(FromPath, Visitor); + + if (Visitor.FailedFileCount) + { + throw std::runtime_error(fmt::format("{} file copy operations FAILED", Visitor.FailedFileCount)); + } +} + +void WriteFile(std::filesystem::path Path, const IoBuffer* const* Data, size_t BufferCount) { #if ZEN_PLATFORM_WINDOWS |