22constexpr const char charset[] =
"0123456789"
23 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
24 "abcdefghijklmnopqrstuvwxyz";
26constexpr size_t max_index = (
sizeof(charset) - 1);
28using random_generator_t = ::std::mt19937;
30static const auto make_seeded_engine = []()
33 std::hash<std::thread::id> hasher;
34 std::seed_seq seed(std::initializer_list<typename random_generator_t::result_type>{
35 static_cast<typename random_generator_t::result_type
>(
36 std::chrono::system_clock::now().time_since_epoch().count()),
37 static_cast<typename random_generator_t::result_type
>(hasher(std::this_thread::get_id())),
46 return random_generator_t(seed);
49std::string generate_random_string(
size_t len)
51 static thread_local random_generator_t
engine(make_seeded_engine());
53 std::uniform_int_distribution<> dist(0, max_index);
58 for (
size_t i = 0; i < len; i++)
60 str.push_back(charset[dist(
engine)]);
67auto sync_file(
const fs::path& temp, fs::error_code& ec)
noexcept ->
bool
72 HANDLE h = CreateFileW(temp.wstring().c_str(),
74 FILE_SHARE_READ | FILE_SHARE_WRITE,
77 FILE_ATTRIBUTE_NORMAL,
79 if(h == INVALID_HANDLE_VALUE)
81 ec = fs::error_code(GetLastError(), std::system_category());
85 if(!FlushFileBuffers(h))
87 ec = fs::error_code(GetLastError(), std::system_category());
96 int fd = ::open(temp.c_str(), O_RDWR);
99 ec = fs::error_code(errno, std::generic_category());
100 fs::remove(temp, ec);
105 ec = fs::error_code(errno, std::generic_category());
107 fs::remove(temp, ec);
119auto atomic_rename_file(
const fs::path& src,
const fs::path& dst, fs::error_code& ec)
noexcept ->
bool
122 fs::rename(src, dst, ec);
130auto make_temp_path(
const fs::path& dir, fs::path& out, fs::error_code& ec)
noexcept ->
bool
133 if(!fs::exists(dir, ec) || ec)
135 if(!fs::is_directory(dir, ec) || ec)
138 out = dir / (
"." + hpp::to_string(
generate_uuid()) +
".temp");
145 out.make_preferred();
156auto atomic_copy_file(
const fs::path& src,
const fs::path& dst, fs::error_code& ec)
noexcept ->
bool
161 if(!fs::exists(src, ec) || ec)
164 ec = std::make_error_code(std::errc::no_such_file_or_directory);
167 if(!fs::is_regular_file(src, ec) || ec)
170 ec = std::make_error_code(std::errc::invalid_argument);
179 fs::copy_file(src, temp, fs::copy_options::overwrite_existing, ec);
182 fs::remove(temp, ec);
188 fs::remove(temp, ec);
195 fs::remove(temp, ec);
203 const std::function<
void(
const fs::path&)>& callback,
204 fs::error_code& ec)
noexcept
211 fs::path temp = fs::temp_directory_path(err);
221 fs::copy_file(temp, dst, err);
223 fs::remove(temp, err);