Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2018-09-14 10:28:00 +0300
committerbubnikv <bubnikv@gmail.com>2018-09-14 10:28:00 +0300
commit9d9e4a0f7b2d9d3440c2a05bc65b2cab707d148a (patch)
treee57a7cb171afe5efa6381a73ad02dcbce3050826 /xs/src/libslic3r/utils.cpp
parentbb70ad609025a259f35f4f21e2fc9587c7a3fc2d (diff)
WIP: Background processing.
Diffstat (limited to 'xs/src/libslic3r/utils.cpp')
-rw-r--r--xs/src/libslic3r/utils.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/xs/src/libslic3r/utils.cpp b/xs/src/libslic3r/utils.cpp
index 95aaf5453..4c2d65605 100644
--- a/xs/src/libslic3r/utils.cpp
+++ b/xs/src/libslic3r/utils.cpp
@@ -23,6 +23,7 @@
#include <boost/nowide/fstream.hpp>
#include <boost/nowide/integration/filesystem.hpp>
#include <boost/nowide/convert.hpp>
+#include <boost/nowide/cstdio.hpp>
namespace Slic3r {
@@ -139,6 +140,87 @@ const std::string& data_dir()
return g_data_dir;
}
+
+// borrowed from LVVM lib/Support/Windows/Path.inc
+int rename_file(const std::string &from, const std::string &to)
+{
+ int ec = 0;
+
+#ifdef _WIN32
+
+ // Convert to utf-16.
+ std::wstring wide_from = boost::nowide::widen(from);
+ std::wstring wide_to = boost::nowide::widen(to);
+
+ // Retry while we see recoverable errors.
+ // System scanners (eg. indexer) might open the source file when it is written
+ // and closed.
+ bool TryReplace = true;
+
+ // This loop may take more than 2000 x 1ms to finish.
+ for (int i = 0; i < 2000; ++ i) {
+ if (i > 0)
+ // Sleep 1ms
+ ::Sleep(1);
+ if (TryReplace) {
+ // Try ReplaceFile first, as it is able to associate a new data stream
+ // with the destination even if the destination file is currently open.
+ if (::ReplaceFileW(wide_to.data(), wide_from.data(), NULL, 0, NULL, NULL))
+ return 0;
+ DWORD ReplaceError = ::GetLastError();
+ ec = -1; // ReplaceError
+ // If ReplaceFileW returned ERROR_UNABLE_TO_MOVE_REPLACEMENT or
+ // ERROR_UNABLE_TO_MOVE_REPLACEMENT_2, retry but only use MoveFileExW().
+ if (ReplaceError == ERROR_UNABLE_TO_MOVE_REPLACEMENT ||
+ ReplaceError == ERROR_UNABLE_TO_MOVE_REPLACEMENT_2) {
+ TryReplace = false;
+ continue;
+ }
+ // If ReplaceFileW returned ERROR_UNABLE_TO_REMOVE_REPLACED, retry
+ // using ReplaceFileW().
+ if (ReplaceError == ERROR_UNABLE_TO_REMOVE_REPLACED)
+ continue;
+ // We get ERROR_FILE_NOT_FOUND if the destination file is missing.
+ // MoveFileEx can handle this case.
+ if (ReplaceError != ERROR_ACCESS_DENIED && ReplaceError != ERROR_FILE_NOT_FOUND && ReplaceError != ERROR_SHARING_VIOLATION)
+ break;
+ }
+ if (::MoveFileExW(wide_from.c_str(), wide_to.c_str(), MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING))
+ return 0;
+ DWORD MoveError = ::GetLastError();
+ ec = -1; // MoveError
+ if (MoveError != ERROR_ACCESS_DENIED && MoveError != ERROR_SHARING_VIOLATION)
+ break;
+ }
+
+#else
+
+ boost::nowide::remove(from.c_str());
+ ec = boost::nowide::rename(from.c_str(), to.c_str());
+
+#endif
+
+ return ec;
+}
+
+int copy_file(const std::string &from, const std::string &to)
+{
+ const boost::filesystem::path source(from);
+ const boost::filesystem::path target(to);
+ static const auto perms = boost::filesystem::owner_read | boost::filesystem::owner_write | boost::filesystem::group_read | boost::filesystem::others_read; // aka 644
+
+ // Make sure the file has correct permission both before and after we copy over it.
+ try {
+ if (boost::filesystem::exists(target))
+ boost::filesystem::permissions(target, perms);
+ boost::filesystem::copy_file(source, target, boost::filesystem::copy_option::overwrite_if_exists);
+ boost::filesystem::permissions(target, perms);
+ } catch (std::exception & /* ex */) {
+ return -1;
+ }
+ return 0;
+}
+
} // namespace Slic3r
#include <xsinit.h>