158 lines
3.4 KiB
C++
158 lines
3.4 KiB
C++
module;
|
|
|
|
#include <ee_utils/platform.hpp>
|
|
|
|
module FileSystem;
|
|
import utils;
|
|
|
|
//TOO: REWORK WITH IOCP
|
|
|
|
IFileSystem::~IFileSystem()
|
|
{
|
|
for (FileHandle* handle : activeFiles)
|
|
Deallocate(handle);
|
|
for (FileHandle* handle : failedFiles)
|
|
Deallocate(handle);
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
|
|
FileHandle& NativeFileSystem::Open(const std::filesystem::path &path, const std::uint32_t flags)
|
|
{
|
|
FileHandle* result = Allocate<FileHandle>();
|
|
|
|
#ifndef NDEBUG
|
|
result->debugPath = path;
|
|
#endif
|
|
|
|
DWORD createFileMode = 0;
|
|
|
|
if (flags & FILE_OPEN_READ)
|
|
createFileMode |= GENERIC_READ;
|
|
if (flags & FILE_OPEN_WRITE)
|
|
createFileMode |= GENERIC_WRITE;
|
|
|
|
HANDLE file = CreateFileW(
|
|
path.c_str(),
|
|
createFileMode,
|
|
NULL,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_OVERLAPPED,
|
|
NULL
|
|
);
|
|
|
|
if (file == INVALID_HANDLE_VALUE)
|
|
{
|
|
LOG(ERROR, "Failed to open file %s. Error: %d", path.c_str(), GetLastError());
|
|
failedFiles.push_back(result);
|
|
return *result;
|
|
}
|
|
|
|
result->win32Handle = file;
|
|
result->size = GetFileSize(file, NULL);
|
|
if (result->size == INVALID_FILE_SIZE)
|
|
LOG(ERROR, "Failed to get size of file %s. Error: %d", path.c_str(), GetLastError());
|
|
|
|
if (freeFileSlots.size() > 0)
|
|
{
|
|
std::size_t pos = freeFileSlots.back();
|
|
result->id = pos;
|
|
activeFiles[pos] = result;
|
|
freeFileSlots.pop_back();
|
|
}
|
|
else
|
|
{
|
|
result->id = activeFiles.size();
|
|
activeFiles.push_back(result);
|
|
}
|
|
|
|
return *result;
|
|
}
|
|
|
|
void NativeFileSystem::ReadAsync(FileHandle &file, const std::uint32_t bufferSize, const std::uint32_t flags)
|
|
{
|
|
file.overlapped = {
|
|
.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr)
|
|
};
|
|
file.buffer = AllocateArray<std::uint8_t>(bufferSize);
|
|
file.bufferSize = bufferSize;
|
|
|
|
BOOL isSync = ReadFile(
|
|
file.win32Handle,
|
|
file.buffer,
|
|
bufferSize,
|
|
NULL,
|
|
&file.overlapped
|
|
);
|
|
|
|
if (isSync || GetLastError() != ERROR_IO_PENDING)
|
|
LOG(ERROR, "File reading is synchronious while asynchronious is awaited");
|
|
}
|
|
|
|
bool NativeFileSystem::PollReady(FileHandle &file)
|
|
{
|
|
DWORD status = WaitForSingleObject(file.overlapped.hEvent, 0);
|
|
|
|
switch (status)
|
|
{
|
|
case WAIT_OBJECT_0:
|
|
{
|
|
if (file.size == file.bufferSize)
|
|
{
|
|
file.data = file.buffer;
|
|
file.buffer = nullptr;
|
|
}
|
|
else
|
|
{
|
|
/* TODO: reserve size for data, shift and move */
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case WAIT_ABANDONED:
|
|
case WAIT_TIMEOUT:
|
|
return false;
|
|
|
|
default:
|
|
{
|
|
LOG(CRITICAL, "Failed to get file status. Error: %d", GetLastError());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void NativeFileSystem::Close(FileHandle &file)
|
|
{
|
|
if (file.overlapped.hEvent)
|
|
CloseHandle(file.overlapped.hEvent);
|
|
|
|
if (file.buffer != nullptr)
|
|
{
|
|
DeallocateArray(file.buffer);
|
|
file.buffer = nullptr;
|
|
}
|
|
if (file.data != nullptr)
|
|
{
|
|
DeallocateArray(file.data);
|
|
file.data = nullptr;
|
|
}
|
|
|
|
if (file.win32Handle != INVALID_HANDLE_VALUE)
|
|
{
|
|
CloseHandle(file.win32Handle);
|
|
file.win32Handle = INVALID_HANDLE_VALUE;
|
|
}
|
|
freeFileSlots.push_back(file.id);
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef __linux__
|
|
|
|
|
|
|
|
#endif |