From 980c37ff640840bf5d8d518c3a9f818fcb9cc250 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 9 Dec 2023 22:40:56 +0000 Subject: [PATCH] Better implementation of directory creation --- .../asys/libuv/filesystem/LibuvDirectory.cpp | 78 ++++++++++++------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/src/hx/libs/asys/libuv/filesystem/LibuvDirectory.cpp b/src/hx/libs/asys/libuv/filesystem/LibuvDirectory.cpp index 478160892..a0ca88d03 100644 --- a/src/hx/libs/asys/libuv/filesystem/LibuvDirectory.cpp +++ b/src/hx/libs/asys/libuv/filesystem/LibuvDirectory.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "../LibuvUtils.h" namespace @@ -166,28 +167,32 @@ void hx::asys::filesystem::Directory_obj::create(Context ctx, String path, int p auto libuvCtx = hx::asys::libuv::context(ctx); auto request = std::make_unique(); - if (recursive) - { - // TODO : This isn't really async, eventually move this loop into haxe. + // Maybe TODO : this is not async and would be a ball ache to do so. - hx::EnterGCFreeZone(); + auto separator = std::array(); + + wcstombs(separator.data(), &std::filesystem::path::preferred_separator, 1); - auto filePath = std::filesystem::u8path(path.utf8_str()); - auto accumulated = std::filesystem::path(); + auto items = path.split(separator.data()); + auto accumulated = std::filesystem::path(); + auto result = 0; - for (auto&& part : filePath) + for (auto i = 0; i < items->length - 1; i++) + { + if (accumulated.empty()) { - if (accumulated.empty()) - { - accumulated = part; - } - else - { - accumulated = accumulated / part; - } + accumulated = items[i].utf8_str(); + } + else + { + accumulated = accumulated / items[i].utf8_str(); + } + + if (!recursive) + { + hx::EnterGCFreeZone(); - auto result = uv_fs_mkdir(libuvCtx->uvLoop, request.get(), accumulated.u8string().c_str(), permissions, nullptr); - if (result < 0 && result != EEXIST) + if ((result = uv_fs_stat(libuvCtx->uvLoop, request.get(), accumulated.u8string().c_str(), nullptr)) < 0 && result != UV_EEXIST) { hx::ExitGCFreeZone(); @@ -195,25 +200,40 @@ void hx::asys::filesystem::Directory_obj::create(Context ctx, String path, int p return; } + + hx::ExitGCFreeZone(); } - hx::ExitGCFreeZone(); + hx::EnterGCFreeZone(); - cbSuccess(); - } - else - { - auto result = uv_fs_mkdir(libuvCtx->uvLoop, request.get(), path.utf8_str(), permissions, hx::asys::libuv::basic_callback); - if (result < 0) + if ((result = uv_fs_mkdir(libuvCtx->uvLoop, request.get(), accumulated.u8string().c_str(), permissions, nullptr)) < 0 && result != UV_EEXIST) { + hx::ExitGCFreeZone(); + cbFailure(hx::asys::libuv::uv_err_to_enum(result)); + + return; } - else - { - request->data = new hx::asys::libuv::BaseRequest(cbSuccess, cbFailure); - request.release(); - } + + hx::ExitGCFreeZone(); } + + accumulated = accumulated / items[items->length - 1].utf8_str(); + + hx::EnterGCFreeZone(); + + if ((result = uv_fs_mkdir(libuvCtx->uvLoop, request.get(), accumulated.u8string().c_str(), permissions, nullptr)) < 0 && result != UV_EEXIST) + { + hx::ExitGCFreeZone(); + + cbFailure(hx::asys::libuv::uv_err_to_enum(result)); + + return; + } + + hx::ExitGCFreeZone(); + + cbSuccess(); } void hx::asys::filesystem::Directory_obj::move(Context ctx, String oldPath, String newPath, Dynamic cbSuccess, Dynamic cbFailure)