11#if defined(_WIN32) && !defined(_WINDOWS_) && !defined(WINAPI)
13 typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, * PSECURITY_ATTRIBUTES, * LPSECURITY_ATTRIBUTES;
16 extern "C" typedef union _LARGE_INTEGER {
28 extern "C" __declspec(dllimport)
int __stdcall FlushViewOfFile(
void const* lpBaseAddress,
size_t dwNumberOfBytesToFlush);
29 extern "C" __declspec(dllimport)
int __stdcall FlushFileBuffers(
void* hFile);
30 extern "C" __declspec(dllimport)
int __stdcall UnmapViewOfFile(
void const* lpBaseAddress);
31 extern "C" __declspec(dllimport)
int __stdcall CloseHandle(
void* hObject);
32 extern "C" __declspec(dllimport)
unsigned long __stdcall GetLastError();
33 extern "C" __declspec(dllimport)
void* __stdcall CreateFileW(
const wchar_t*,
unsigned long,
unsigned long, LPSECURITY_ATTRIBUTES,
unsigned long,
unsigned long,
void*);
34 extern "C" __declspec(dllimport)
long SetFilePointerEx(
void* hFile, LARGE_INTEGER liDistanceToMove, LARGE_INTEGER* lpNewFilePointer,
unsigned long dwMoveMethod);
35 extern "C" __declspec(dllimport)
long SetEndOfFile(
void* hFile);
37 extern "C" struct SYSTEM_INFO {
39 unsigned long dwOemId;
41 unsigned short wProcessorArchitecture;
42 unsigned short wReserved;
45 unsigned long dwPageSize;
46 void* lpMinimumApplicationAddress;
47 void* lpMaximumApplicationAddress;
48 unsigned long* dwActiveProcessorMask;
49 unsigned long dwNumberOfProcessors;
50 unsigned long dwProcessorType;
51 unsigned long dwAllocationGranularity;
52 unsigned short wProcessorLevel;
53 unsigned short wProcessorRevision;
56 extern "C" __declspec(dllimport)
void __stdcall GetSystemInfo(SYSTEM_INFO * lpSystemInfo);
57 extern "C" __declspec(dllimport)
void* __stdcall CreateFileMappingW(
void* hFile,
void* lpFileMappingAttributes,
unsigned long flProtect,
unsigned long dwMaximumSizeHigh,
unsigned long dwMaximumSizeLow,
const wchar_t* lpName);
58 extern "C" __declspec(dllimport)
void* __stdcall MapViewOfFile(
void* hFileMappingObject,
unsigned long dwDesiredAccess,
unsigned long dwFileOffsetHigh,
unsigned long dwFileOffsetLow,
size_t dwNumberOfBytesToMap);
63 inline std::error_code last_error() noexcept
65 std::error_code error;
67 error.assign(GetLastError(), std::system_category());
69 error.assign(errno, std::system_category());
74 inline size_t page_size() noexcept
76 static const size_t page_size = []
79 SYSTEM_INFO SystemInfo{};
80 GetSystemInfo(&SystemInfo);
81 return SystemInfo.dwAllocationGranularity;
83 return sysconf(_SC_PAGE_SIZE);
89 inline size_t make_offset_page_aligned(
size_t offset)
noexcept
91 const size_t page_size_ = page_size();
93 return offset / page_size_ * page_size_;
96 inline unsigned long int64_high(int64_t n)
noexcept
101 inline unsigned long int64_low(int64_t n)
noexcept
103 return n & 0xffffffff;
109 inline bool create_file(std::filesystem::path
const& path,
size_t size, std::error_code& error)
noexcept
112 auto file = CreateFileW(path.c_str(), (0x40000000L), 0x00000001 | 0x00000002, 0, 4, 0x00000080, 0);
115 error = last_error();
118 if (SetFilePointerEx(file, LARGE_INTEGER{.QuadPart = int64_t(size)},
nullptr, 0) == 0)
120 error = last_error();
124 if (SetEndOfFile(file) == 0)
126 error = last_error();
136 template <
typename VALUE_TYPE>
137 void mmap_sink<VALUE_TYPE>::sync(std::error_code& error)
noexcept
140 if (!this->is_open())
142 error = std::make_error_code(std::errc::bad_file_descriptor);
149 if (FlushViewOfFile(get_mapping_start(), this->mapped_length_) == 0 || FlushFileBuffers(this->file_handle_) == 0)
151 if (::msync(get_mapping_start(), mapped_length_, MS_SYNC) != 0)
154 error = last_error();
160 if (FlushFileBuffers(this->file_handle_) == 0)
162 error = last_error();
167 template <
typename VALUE_TYPE>
168 file_handle_type mmap_sink<VALUE_TYPE>::open_file(
const std::filesystem::path& path, std::error_code& error)
noexcept
172 error = std::make_error_code(std::errc::invalid_argument);
173 return invalid_handle;
177 const auto handle = CreateFileW(path.c_str(), (0x80000000L) | (0x40000000L), 0x00000001 | 0x00000002, 0, 3, 0x00000080, 0);
179 const auto handle = ::open(c_str(path), O_RDWR);
181 if (handle == invalid_handle)
182 error = last_error();
187 template <
typename VALUE_TYPE>
188 typename mmap_sink<VALUE_TYPE>::mmap_context mmap_sink<VALUE_TYPE>::memory_map(
const file_handle_type file_handle,
const int64_t offset,
const int64_t length, std::error_code& error)
noexcept
190 const int64_t aligned_offset = make_offset_page_aligned(offset);
191 const int64_t length_to_map = offset - aligned_offset + length;
193 const int64_t max_file_size = offset + length;
194 const auto file_mapping_handle = CreateFileMappingW(file_handle, 0, 0x04, int64_high(max_file_size), int64_low(max_file_size), 0);
195 if (file_mapping_handle == invalid_handle)
197 error = last_error();
200 VALUE_TYPE* mapping_start =
static_cast<VALUE_TYPE*
>(MapViewOfFile(file_mapping_handle, 0x0002, int64_high(aligned_offset), int64_low(aligned_offset), length_to_map));
201 if (mapping_start ==
nullptr)
203 CloseHandle(file_mapping_handle);
204 error = last_error();
208 VALUE_TYPE* mapping_start =
static_cast<VALUE_TYPE*
>(::mmap(0, length_to_map, PROT_WRITE, MAP_SHARED, file_handle, aligned_offset));
209 if (mapping_start == MAP_FAILED)
211 error = last_error();
217 ctx.data = mapping_start + offset - aligned_offset;
219 ctx.mapped_length = length_to_map;
220 ctx.file_mapping_handle = file_mapping_handle;
224 template <
typename VALUE_TYPE>
225 void basic_mmap_base<VALUE_TYPE>::unmap() noexcept
227 if (!this->is_open()) {
return; }
230 if (this->is_mapped())
232 UnmapViewOfFile(this->get_mapping_start());
233 CloseHandle(this->file_mapping_handle_);
236 if (data_) { ::munmap(
const_cast<pointer
>(get_mapping_start()), mapped_length_); }
240 CloseHandle(this->file_handle_);
242 ::close(file_handle_);
246 this->data_ =
nullptr;
247 this->length_ = this->mapped_length_ = 0;
248 this->file_handle_ = invalid_handle;
249 this->file_mapping_handle_ = invalid_handle;
252 template <
typename VALUE_TYPE>
253 file_handle_type mmap_source<VALUE_TYPE>::open_file(
const std::filesystem::path& path, std::error_code& error)
noexcept
258 error = std::make_error_code(std::errc::invalid_argument);
259 return invalid_handle;
262 const auto handle = CreateFileW(path.c_str(), (0x80000000L), 0x00000001 | 0x00000002, 0, 3, 0x00000080, 0);
264 const auto handle = ::open(c_str(path), O_RDONLY);
266 if (handle == invalid_handle)
268 error = last_error();
273 template <
typename VALUE_TYPE>
274 typename mmap_source<VALUE_TYPE>::mmap_context mmap_source<VALUE_TYPE>::memory_map(
const file_handle_type file_handle,
const int64_t offset,
const int64_t length, std::error_code& error)
noexcept
276 const int64_t aligned_offset = make_offset_page_aligned(offset);
277 const int64_t length_to_map = offset - aligned_offset + length;
279 const int64_t max_file_size = offset + length;
280 const auto file_mapping_handle = CreateFileMappingW(file_handle, 0, 0x02, int64_high(max_file_size), int64_low(max_file_size), 0);
281 if (file_mapping_handle == invalid_handle)
283 error = last_error();
286 auto mapping_start =
static_cast<VALUE_TYPE*
>(MapViewOfFile(file_mapping_handle, 0x0004, int64_high(aligned_offset), int64_low(aligned_offset), length_to_map));
287 if (mapping_start ==
nullptr)
290 CloseHandle(file_mapping_handle);
291 error = last_error();
295 auto mapping_start =
static_cast<VALUE_TYPE*
>(::mmap(0, length_to_map, PROT_READ, MAP_SHARED, file_handle, aligned_offset));
296 if (mapping_start == MAP_FAILED)
298 error = last_error();
304 ctx.data = mapping_start + offset - aligned_offset;
306 ctx.mapped_length = length_to_map;
307 ctx.file_mapping_handle = file_mapping_handle;
Primary namespace for everything in this library.