aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/filesystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zencore/filesystem.cpp')
-rw-r--r--src/zencore/filesystem.cpp97
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