24 return !
p.empty() &&
p.native().find(std::filesystem::path::value_type{}) ==
25 std::filesystem::path::string_type::npos;
27constexpr std::uint64_t
hashSeed = 14695981039346656037ull;
28inline void hashBytes(std::uint64_t &hash,
const unsigned char *
p, std::size_t
n)
30 for (std::size_t
i = 0;
i <
n; ++
i) {
32 hash *= 1099511628211ull;
37 std::filesystem::path target_, temp_;
38 bool overwrite_, durable_;
39 std::FILE *file_ =
nullptr;
51 static std::atomic<std::uint64_t> sequence{0};
52 std::random_device random;
53 for (
int attempt = 0; attempt < 32; ++attempt) {
54 const auto nonce = (std::uint64_t(random()) << 32) ^ random() ^ ++sequence;
55 temp_ =
parent / (
".meshkit-" + std::to_string(nonce) +
".tmp");
57 file_ = _wfopen(temp_.c_str(), L
"wbx");
59 file_ = std::fopen(temp_.c_str(),
"wbx");
67 "Cannot create an exclusive output temporary: " + std::string(std::strerror(errno)),
75 std::error_code
error;
76 std::filesystem::remove(temp_,
error);
80 std::FILE *
file()
const {
return file_; }
83 if (std::fflush(file_) != 0)
87 if (_commit(_fileno(file_)) != 0)
90 if (::fsync(fileno(file_)) != 0)
94 const int closed = std::fclose(file_);
100 (overwrite_ ? MOVEFILE_REPLACE_EXISTING : 0) | (durable_ ? MOVEFILE_WRITE_THROUGH : 0);
101 if (!MoveFileExW(temp_.c_str(), target_.c_str(), flags))
102 fail(
"publish",
"Cannot atomically publish output (destination may already exist).",
106 if (::rename(temp_.c_str(), target_.c_str()) != 0)
108 "Cannot atomically replace output: " + std::string(std::strerror(errno)),
111 if (
::link(temp_.c_str(), target_.c_str()) != 0)
113 "Cannot publish output without replacing an existing file: " +
114 std::string(std::strerror(errno)),
116 ::unlink(temp_.c_str());
126 std::array<unsigned char, 65536> buffer_{};
127 std::size_t used_ = 0;
131 Output(std::FILE *file,
Work &work) : file_(file), work_(work) {}
135 if (used_ && std::fwrite(buffer_.data(), 1, used_, file_) != used_)
139 void raw(
const void *data, std::size_t
n,
bool hashed =
true)
141 auto p =
static_cast<const unsigned char *
>(data);
146 const auto count = std::min(
n, buffer_.size() - used_);
147 std::memcpy(buffer_.data() + used_,
p,
count);
151 if (used_ == buffer_.size())
157 unsigned char data[8];
158 for (
int i = 0;
i < width; ++
i) {
162 raw(data, width, hashed);
167 static_assert(
sizeof(
value) ==
sizeof(bits));
168 std::memcpy(&bits, &
value, 8);
174 raw(
s.data(),
s.size());
179 std::istream &stream_;
181 std::array<unsigned char, 65536> buffer_{};
182 std::size_t at_ = 0, end_ = 0;
186 Input(std::istream &stream,
Work &work) : stream_(stream), work_(work) {}
191 stream_.read(
reinterpret_cast<char *
>(buffer_.data()), buffer_.size());
192 end_ = std::size_t(stream_.gcount());
200 value = buffer_[at_++];
208 auto p =
static_cast<unsigned char *
>(
target);
209 for (std::size_t
i = 0;
i <
n; ++
i)
210 if (!
byte(
p[
i], hashed))
213 std::uint64_t
number(
int width,
bool hashed =
true)
215 unsigned char data[8];
216 raw(data, width, hashed);
217 std::uint64_t
value = 0;
218 for (
int i = 0;
i < width; ++
i)
219 value |= std::uint64_t(data[
i]) << (8 *
i);
224 const auto bits =
number(8);
226 std::memcpy(&
value, &bits, 8);
235 std::string result(std::size_t(
n),
'\0');
236 raw(result.data(), result.size());
240inline void appendId(std::vector<std::int64_t> &values, std::int64_t
id, std::size_t index)
242 if (values.empty() &&
id == std::int64_t(index + 1))
244 if (values.empty()) {
245 values.reserve(index + 1);
246 for (std::size_t
i = 0;
i < index; ++
i)
247 values.push_back(
i + 1);
249 values.push_back(
id);
251inline void appendMarker(std::vector<std::int32_t> &values, std::int32_t marker, std::size_t index)
253 if (!marker && values.empty())
256 values.resize(index, 0);
257 values.push_back(marker);
259inline std::int64_t
externalId(
const std::vector<std::int64_t> &ids, std::size_t index)
261 return ids.empty() ? std::int64_t(index + 1) : ids[index];
266 std::memcpy(&
value, &bits, 8);
271 std::uint32_t raw = std::uint32_t(bits);
273 std::memcpy(&
value, &raw, 4);
285 r.
code =
"allocation";
286 r.
message =
"Insufficient memory.";
291 r.
code =
"exception";
298 fail(r.code, r.message, r.status);
void raw(const void *data, std::size_t n, bool hashed=true)
Definition file.hpp:139
void flush()
Definition file.hpp:132
void text(const std::string &s)
Definition file.hpp:171
void number(std::uint64_t value, int width, bool hashed=true)
Definition file.hpp:155
std::uint64_t bytes
Definition file.hpp:130
std::uint64_t hash
Definition file.hpp:130
Output(std::FILE *file, Work &work)
Definition file.hpp:131
void real(double value)
Definition file.hpp:164
Transaction(const Transaction &)=delete
std::FILE * file() const
Definition file.hpp:80
void commit()
Definition file.hpp:81
Transaction(const std::filesystem::path &target, const IOOptions &options)
Definition file.hpp:42
~Transaction()
Definition file.hpp:70
size_t i
Definition contourjob.cpp:30
int link
Definition heatconfigdialog.cpp:65
QString target
Definition initialbedqualitydialog.cpp:51
double s
Scene px per model length unit.
Definition inletdrawingview.cpp:95
ArrowPlacement p
Definition linesymbollayer.cpp:29
std::size_t n
Definition mesh2dresultsexport.cpp:538
Definition meshcommands.h:38
constexpr std::uint64_t hashSeed
Definition file.hpp:27
void appendMarker(std::vector< std::int32_t > &values, std::int32_t marker, std::size_t index)
Definition file.hpp:251
std::int64_t externalId(const std::vector< std::int64_t > &ids, std::size_t index)
Definition file.hpp:259
void fail(std::string code, std::string message, RunStatus status=RunStatus::Infeasible)
Definition operation.hpp:17
bool validPath(const std::filesystem::path &p)
Definition file.hpp:22
std::int32_t signed32(std::uint64_t bits)
Definition file.hpp:269
void setException(IOReport &r, const std::bad_alloc &)
Definition file.hpp:282
void hashBytes(std::uint64_t &hash, const unsigned char *p, std::size_t n)
Definition file.hpp:28
void setError(IOReport &r, const Stop &e)
Definition file.hpp:276
void appendId(std::vector< std::int64_t > &values, std::int64_t id, std::size_t index)
Definition file.hpp:240
void validated(const Mesh &mesh, const IOOptions &o)
Definition file.hpp:294
std::int64_t signed64(std::uint64_t bits)
Definition file.hpp:263
OperationReport validateMesh(const Mesh &, const Limits &={}, const std::function< bool()> &cancelled={})
Definition mesh.cpp:9
const ConstraintAuditOptions & options
Definition constraintaudit.cpp:34
std::uint64_t remaining
Definition constraintaudit.cpp:35
int parent
Definition planning.cpp:199
double value
Definition rasterfluxintegration.cpp:27
std::uint64_t number
Definition smsio.cpp:24
Limits limits
Definition io.hpp:12
std::function< bool()> cancelled
Definition io.hpp:13
RunStatus status
Definition mesh.hpp:67
std::string message
Definition mesh.hpp:68
std::string code
Definition mesh.hpp:68
Definition operation.hpp:13
RunStatus status
Definition operation.hpp:14
std::string message
Definition operation.hpp:15
std::string code
Definition operation.hpp:15
Definition operation.hpp:22
double error
Definition terrainerrorfield.cpp:42
quint64 count
Definition terrainerrorfield.cpp:43