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.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp
index 3311ba1b9..8abe5af00 100644
--- a/src/zencore/filesystem.cpp
+++ b/src/zencore/filesystem.cpp
@@ -676,6 +676,69 @@ WriteFile(std::filesystem::path Path, CompositeBuffer InData)
WriteFile(Path, DataPtrs.data(), DataPtrs.size());
}
+bool
+MoveToFile(std::filesystem::path Path, IoBuffer Data)
+{
+ if (!Data.IsWholeFile())
+ {
+ return false;
+ }
+ IoBufferFileReference FileRef;
+ if (!Data.GetFileReference(/* out */ FileRef))
+ {
+ return false;
+ }
+
+#if ZEN_PLATFORM_WINDOWS
+ const HANDLE ChunkFileHandle = FileRef.FileHandle;
+ std::wstring FileName = Path.native();
+ const DWORD BufferSize = sizeof(FILE_RENAME_INFO) + gsl::narrow<DWORD>(FileName.size() * sizeof(WCHAR));
+ FILE_RENAME_INFO* RenameInfo = reinterpret_cast<FILE_RENAME_INFO*>(Memory::Alloc(BufferSize));
+ memset(RenameInfo, 0, BufferSize);
+
+ RenameInfo->ReplaceIfExists = TRUE;
+ RenameInfo->FileNameLength = gsl::narrow<DWORD>(FileName.size());
+ memcpy(RenameInfo->FileName, FileName.c_str(), FileName.size() * sizeof(WCHAR));
+ RenameInfo->FileName[FileName.size()] = 0;
+
+ // Try to move file into place
+ BOOL Success = SetFileInformationByHandle(ChunkFileHandle, FileRenameInfo, RenameInfo, BufferSize);
+
+ if (!Success)
+ {
+ DWORD LastError = GetLastError();
+ if (LastError == ERROR_PATH_NOT_FOUND)
+ {
+ zen::CreateDirectories(Path.parent_path());
+ Success = SetFileInformationByHandle(ChunkFileHandle, FileRenameInfo, RenameInfo, BufferSize);
+ }
+ }
+ Memory::Free(RenameInfo);
+ if (!Success)
+ {
+ return false;
+ }
+#elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+ std::filesystem::path SourcePath = PathFromHandle(FileRef.FileHandle);
+ int Ret = link(SourcePath.c_str(), Path.c_str());
+ if (Ret < 0)
+ {
+ int32_t err = errno;
+ if (err == ENOENT)
+ {
+ zen::CreateDirectories(Path.parent_path());
+ Ret = link(SourcePath.c_str(), Path.c_str());
+ }
+ }
+ if (Ret < 0)
+ {
+ return false;
+ }
+#endif // ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+ Data.SetDeleteOnClose(false);
+ return true;
+}
+
IoBuffer
FileContents::Flatten()
{