9 const std::array<DWORD, Windows_Handle::mode_count> Windows_Handle::desired_access
12 GENERIC_READ | GENERIC_WRITE,
13 GENERIC_READ | GENERIC_WRITE,
14 GENERIC_READ | GENERIC_WRITE,
15 GENERIC_READ | GENERIC_WRITE,
16 GENERIC_READ | GENERIC_WRITE
19 const std::array<DWORD, Windows_Handle::mode_count> Windows_Handle::share_mode
21 FILE_SHARE_READ | FILE_SHARE_WRITE,
25 FILE_SHARE_READ | FILE_SHARE_WRITE,
26 FILE_SHARE_READ | FILE_SHARE_WRITE
29 const std::array<DWORD, Windows_Handle::mode_count> Windows_Handle::creation_disposition
40 static DWORD size_to_dword(
size_t size)
43 return DWORD(std::min(size,
size_t(1ULL << 31)));
47 void Windows_Handle::throw_last_error
54 const DWORD last_error = GetLastError();
59 FORMAT_MESSAGE_ALLOCATE_BUFFER |
60 FORMAT_MESSAGE_FROM_SYSTEM,
63 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
69 std::string error((
const char *)buffer);
71 while (!error.empty() && std::isspace(error.back()))
76 std::string(action) +
' ' + std::string(file_name) +
": " + error
81 BOOL Windows_Handle::lock(Lock_Operation op, int64_t start, int64_t size)
84 if (start < 0 || size < 0)
99 case Lock_Operation::shared_lock:
111 case Lock_Operation::exclusive_lock:
123 case Lock_Operation::unlock:
139 void Windows_Handle::shared_lock(int64_t start, int64_t size)
142 if (!lock(Lock_Operation::shared_lock, start, size))
143 throw_last_error(
"Read-locking",
"file");
147 void Windows_Handle::exclusive_lock(int64_t start, int64_t size)
150 if (!lock(Lock_Operation::exclusive_lock, start, size))
151 throw_last_error(
"Write-locking",
"file");
155 void Windows_Handle::unlock(int64_t start, int64_t size)
noexcept
158 lock(Lock_Operation::unlock, start, size);
165 OVERLAPPED overlapped{};
166 overlapped.Pointer = PVOID(offset);
170 if (ReadFile(file, buffer, size_to_dword(size), &result, &overlapped))
171 return size_t(result);
174 if (GetLastError() == ERROR_HANDLE_EOF)
177 throw_last_error(
"Reading",
"file");
194 while (written < size)
196 OVERLAPPED overlapped{};
197 overlapped.Pointer = PVOID(offset + written);
199 DWORD actually_written;
207 size_to_dword(size - written),
213 throw_last_error(
"Writing",
"file");
216 written += actually_written;
225 throw_last_error(
"syncing",
"file");
237 desired_access[static_cast<size_t>(mode)],
238 share_mode[static_cast<size_t>(mode)],
240 creation_disposition[static_cast<size_t>(mode)],
241 FILE_ATTRIBUTE_NORMAL,
268 throw_last_error(
"Getting size of",
"file");
void exclusive_lock_tail()
void destructor_flush() noexcept
Windows_File(const char *file_name, Open_Mode mode)
Windows_Handle(const char *file_name, Open_Mode mode)
void pwrite(const char *data, size_t size, int64_t offset) override
int64_t get_size() const override
size_t pread(char *data, size_t size, int64_t offset) const override
~Windows_Handle() override
@ write_lock
like write_existing_or_create_new, but waits instead of failing if already locked