5#include "../StringViewFormat.h"
7#include "../Logging/Logger.h"
13Cogs::FileHandle::~FileHandle() {
17Cogs::FileHandle::Ptr Cogs::FileHandle::open(std::string_view path, OpenMode openMode, AccessMode accessMode) {
18 Ptr handle = std::make_shared<FileHandle>();
20 constexpr DWORD dwOpenMode[] = {
28 constexpr DWORD dwAccessMode[] = {
33 constexpr DWORD dwShareMode[] = {
38 handle->fileHandle = CreateFileW(Cogs::widen(path).c_str(), dwAccessMode[(
int)accessMode], dwShareMode[(
int)accessMode],
nullptr, dwOpenMode[(
int)openMode], FILE_ATTRIBUTE_NORMAL,
nullptr);
40 if (handle->fileHandle == INVALID_HANDLE_VALUE) {
41 LPSTR messageBuffer =
nullptr;
43 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
46 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
47 reinterpret_cast<LPSTR
>(&messageBuffer),
51 LOG_ERROR(logger,
"Cogs::FileHandle::open(): Failed to open %.*s. Error: %s.", StringViewFormat(path), messageBuffer);
53 LocalFree(messageBuffer);
59void Cogs::FileHandle::close() {
61 ::UnmapViewOfFile(mappedMemory);
62 mappedMemory =
nullptr;
66 ::CloseHandle(mapHandle);
71 ::CloseHandle(fileHandle);
72 fileHandle = INVALID_HANDLE_VALUE;
76bool Cogs::FileHandle::isOpen()
const {
77 return fileHandle != INVALID_HANDLE_VALUE;
80size_t Cogs::FileHandle::getSize()
const {
81 if (fileHandle != INVALID_HANDLE_VALUE) {
83 DWORD lowSize = ::GetFileSize(fileHandle, &highSize);
85 return (
static_cast<size_t>(highSize) << 32) + lowSize;
90bool Cogs::FileHandle::write(
const void* buffer,
size_t size,
size_t& bytesWritten)
92 const uint8_t* src =
static_cast<const uint8_t*
>(buffer);
97 for (
constexpr size_t limit = std::numeric_limits<DWORD>::max(); size > limit; ) {
98 if (WriteFile(fileHandle, src,
static_cast<DWORD
>(limit), &justWritten,
nullptr)) {
101 bytesWritten += justWritten;
104 LOG_ERROR(logger,
"write(): Failed to write FileHandle %p. Error: %d.", fileHandle, GetLastError());
109 if (WriteFile(fileHandle, src,
static_cast<DWORD
>(size), &justWritten,
nullptr)) {
110 bytesWritten += justWritten;
113 LOG_ERROR(logger,
"write(): Failed to write FileHandle %p. Error: %d.", fileHandle, GetLastError());
120bool Cogs::FileHandle::read(
void* buffer,
size_t size,
size_t& bytesRead)
122 uint8_t* dest =
reinterpret_cast<uint8_t*
>(buffer);
127 for (
size_t limit = std::numeric_limits<DWORD>::max(); size > limit; ) {
128 if (ReadFile(fileHandle, dest,
static_cast<DWORD
>(limit), &justRead,
nullptr)) {
131 bytesRead += justRead;
134 LOG_ERROR(logger,
"read(): Failed to read FileHandle %p. Error: %d.", fileHandle, GetLastError());
139 if (ReadFile(fileHandle, dest,
static_cast<DWORD
>(size), &justRead,
nullptr)) {
140 bytesRead += justRead;
143 LOG_ERROR(logger,
"read(): Failed to read FileHandle %p. Error: %d.", fileHandle, GetLastError());
150void* Cogs::FileHandle::map(ProtectionMode ,
size_t offset,
size_t size) {
151 if (fileHandle == INVALID_HANDLE_VALUE) {
152 LOG_ERROR(logger,
"Cannot map invalid file handle.");
157 LOG_ERROR(logger,
"File handle cannot be mapped multiple times.");
161 DWORD maximumSize = (DWORD)(offset + size);
162 DWORD maxHigh = (DWORD)((offset + size) >> 32);
164 mapHandle = ::CreateFileMapping(fileHandle,
nullptr, PAGE_READONLY, maxHigh, maximumSize,
nullptr);
167 LOG_ERROR(logger,
"map(): CreateFileMapping failed. Last error: %d", GetLastError());
171 mappedMemory = ::MapViewOfFile(mapHandle, FILE_MAP_READ, 0,
static_cast<DWORD
>(offset), size);
174 LOG_ERROR(logger,
"map(): MapViewOfFile failed. Last error: %d", GetLastError());
181void Cogs::FileHandle::unmap() {
183 LOG_WARNING(logger,
"Cannot unmap file without mapped memory address (file mapping may have failed).");
187 ::UnmapViewOfFile(mappedMemory);
188 mappedMemory =
nullptr;
190 ::CloseHandle(mapHandle);
Log implementation class.
constexpr Log getLogger(const char(&name)[LEN]) noexcept