4#include "Stroika/Foundation/StroikaPreComp.h"
8#if qStroika_Foundation_Common_Platform_Windows
10#elif qStroika_Foundation_Common_Platform_POSIX
16#include "Stroika/Foundation/Containers/Common.h"
17#include "Stroika/Foundation/Execution/Activity.h"
18#include "Stroika/Foundation/Execution/Exceptions.h"
19#include "Stroika/Foundation/Execution/Throw.h"
20#if qStroika_Foundation_Common_Platform_Windows
21#include "Stroika/Foundation/Execution/Platform/Windows/Exception.h"
33using namespace Stroika::Foundation::IO;
36#if qStroika_Foundation_Common_Platform_Windows
45ThroughTmpFileWriter::ThroughTmpFileWriter (
const filesystem::path& realFileName,
const String& tmpSuffix)
46 : fRealFilePath_{realFileName}
47 , fTmpFilePath_{filesystem::path{realFileName}.operator+= (tmpSuffix.As<wstring> ())}
49 Require (not realFileName.empty ());
50 Require (not tmpSuffix.empty ());
53ThroughTmpFileWriter::~ThroughTmpFileWriter ()
55 if (not fTmpFilePath_.empty ()) {
56 DbgTrace (
"ThroughTmpFileWriter::DTOR - tmpfile not successfully commited to {}"_f, fRealFilePath_);
58#if qStroika_Foundation_Common_Platform_POSIX
59 (void)::unlink (fTmpFilePath_.c_str ());
60#elif qStroika_Foundation_Common_Platform_Windows
61 (void)::DeleteFileW (fTmpFilePath_.c_str ());
70 Require (not fTmpFilePath_.empty ());
73 auto activity =
LazyEvalActivity ([&] () ->
String {
return "committing temporary file {} to {}"_f(fTmpFilePath_, fRealFilePath_); });
75#if qStroika_Foundation_Common_Platform_POSIX
77#elif qStroika_Foundation_Common_Platform_Windows
79 ThrowIfZeroGetLastError (::MoveFileExW (fTmpFilePath_.c_str (), fRealFilePath_.c_str (), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH));
81 catch (
const system_error& we) {
83 if (we.code () == error_code{ERROR_CALL_NOT_IMPLEMENTED, system_category ()}) {
84 ::DeleteFileW (fRealFilePath_.c_str ());
85 ThrowIfZeroGetLastError (::MoveFileW (fTmpFilePath_.c_str (), fRealFilePath_.c_str ()));
94 fTmpFilePath_.clear ();
#define AssertNotImplemented()
String is like std::u32string, except it is much easier to use, often much more space efficient,...
static INT_TYPE ThrowPOSIXErrNoIfNegative(INT_TYPE returnCode, const path &p1={}, const path &p2={})