aboutsummaryrefslogtreecommitdiff
path: root/core/src/Utils/IO/FileStream_Custom.inl
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/Utils/IO/FileStream_Custom.inl')
-rw-r--r--core/src/Utils/IO/FileStream_Custom.inl358
1 files changed, 0 insertions, 358 deletions
diff --git a/core/src/Utils/IO/FileStream_Custom.inl b/core/src/Utils/IO/FileStream_Custom.inl
deleted file mode 100644
index 004dd01..0000000
--- a/core/src/Utils/IO/FileStream_Custom.inl
+++ /dev/null
@@ -1,358 +0,0 @@
-// Note: included by FileStream.cpp conditionally, not compiled separately
-#include "FileStream.hpp"
-
-#include <cstring>
-#include <filesystem>
-#include <iostream>
-
-namespace fs = std::filesystem;
-
-#if defined(_WIN32)
-# define WIN32_LEAN_AND_MEAN
-# define NOMINMAX
-# include <Windows.h>
-
-InputFileStream::InputFileStream(const fs::path& path)
- : mOsFileHandle{ 0 }
-{
- auto handle = reinterpret_cast<HANDLE*>(mOsFileHandle);
-
- *handle = CreateFileW(
- path.c_str(), // fs::path::c_str() returns a wide string on Windows
- GENERIC_READ,
- /* No sharing */ 0,
- /* Use default security*/ nullptr,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- /* No attribute template */ nullptr);
-
- // TODO handle error
-}
-
-InputFileStream::~InputFileStream()
-{
- auto handle = reinterpret_cast<HANDLE*>(mOsFileHandle);
- CloseHandle(*handle);
-}
-
-OutputFileStream::OutputFileStream(const fs::path& path, WriteMode mode)
- : mOsFileHandle{ 0 }
-{
- auto handle = reinterpret_cast<HANDLE*>(mOsFileHandle);
-
- DWORD creationDisposition;
- switch (mode) {
- case AppendFile: creationDisposition = OPEN_ALWAYS; break;
- case TruncateFile: creationDisposition = CREATE_ALWAYS; break;
- }
-
- *handle = CreateFileW(
- path.c_str(),
- GENERIC_WRITE,
- /* No sharing */ 0,
- /* Use default security*/ nullptr,
- creationDisposition,
- FILE_ATTRIBUTE_NORMAL,
- /* No attribute template */ nullptr);
-
- // TODO handle error
-}
-
-OutputFileStream::~OutputFileStream()
-{
- auto handle = reinterpret_cast<HANDLE*>(mOsFileHandle);
- CloseHandle(*handle);
-}
-
-static IoResult::ErrorKind MapErrorCodeToIoResult(DWORD error)
-{
- switch (error) {
- // TODO
-
- default:
- std::cerr << "Unimplemented win32 error code " << error << ", report bug immediately.\n";
- std::abort();
- }
-}
-
-static IoResult ReadBytesDirect(HANDLE hFile, size_t byteCount, std::byte* bytes)
-{
- DWORD bytesRead;
- BOOL result = ReadFile(hFile, bytes, byteCount, &bytesRead, nullptr);
-
- if (result) {
- return IoResult{
- .Error = IoResult::ERR_None,
- .SystemError = 0,
- .BytesMoved = bytesRead,
- };
- } else {
- DWORD errorCode = GetLastError();
- return IoResult{
- .Error = ::MapErrorCodeToIoResult(errorCode),
- .SystemError = errorCode,
- .BytesMoved = bytesRead,
- };
- }
-}
-
-static IoResult WriteBytesDirect(HANDLE hFile, size_t byteCount, const std::byte* bytes)
-{
- DWORD bytesWritten;
- BOOL result = WriteFile(hFile, bytes, byteCount, &bytesWritten, nullptr);
-
- if (result) {
- return IoResult{
- .Error = IoResult::ERR_None,
- .SystemError = 0,
- .BytesMoved = bytesWritten,
- };
- } else {
- DWORD errorCode = GetLastError();
- return IoResult{
- .Error = ::MapErrorCodeToIoResult(errorCode),
- .SystemError = errorCode,
- .BytesMoved = bytesWritten,
- };
- }
-}
-
-#elif defined(__APPLE__) || defined(__linux__)
-# include <fcntl.h>
-# include <sys/stat.h>
-# include <sys/types.h>
-# include <unistd.h>
-
-InputFileStream::InputFileStream(const fs::path& path)
- : mOsFileHandle{ 0 }
-{
- auto fd = reinterpret_cast<int*>(mOsFileHandle);
- *fd = open(path.c_str(), O_RDONLY);
-}
-
-InputFileStream::~InputFileStream()
-{
- auto fd = reinterpret_cast<int*>(mOsFileHandle);
- close(*fd);
-}
-
-OutputFileStream::OutputFileStream(const fs::path& path, WriteMode mode)
- : mOsFileHandle{ 0 }
-{
- auto fd = reinterpret_cast<int*>(mOsFileHandle);
-
- int flags = O_WRONLY | O_CREAT;
- switch (mode) {
- case AppendFile: flags |= O_APPEND; break;
- case TruncateFile: flags |= O_TRUNC; break;
- }
-
- *fd = open(path.c_str(), flags, 0644);
-}
-
-OutputFileStream::~OutputFileStream()
-{
- auto fd = reinterpret_cast<int*>(mOsFileHandle);
- close(*fd);
-}
-
-static IoResult::ErrorKind MapErrnoToIoResult(int err)
-{
- switch (err) {
- // TODO
- case EFAULT: return IoResult::ERR_UnexpectedEof;
- case EPERM: return IoResult::ERR_PermissionDenied;
- case ENOSPC: return IoResult::ERR_OutOfSpace;
- case EIO: return IoResult::ERR_Other;
-
- default:
- std::cerr << "Unimplemented POSIX errno " << err << ", report bug immediately.\n";
- std::abort();
- }
-}
-
-static IoResult ReadBytesDirect(const char* osFileHandle, size_t byteCount, std::byte* bytes)
-{
- int fd = *reinterpret_cast<const int*>(osFileHandle);
- int status = read(fd, bytes, byteCount);
-
- if (status == -1) {
- int err = errno;
- return IoResult{
- .Error = ::MapErrnoToIoResult(err),
- .SystemError = (uint32_t)err,
- .BytesMoved = 0,
- };
- } else {
- return IoResult{
- .Error = IoResult::ERR_None,
- .SystemError = 0,
- .BytesMoved = (size_t)status, // Equal to number of bytes read
- };
- }
-}
-
-static IoResult WriteBytesDirect(const char* osFileHandle, size_t byteCount, const std::byte* bytes)
-{
- int fd = *reinterpret_cast<const int*>(osFileHandle);
- int status = write(fd, bytes, byteCount);
-
- if (status == -1) {
- int err = errno;
- return IoResult{
- .Error = ::MapErrnoToIoResult(err),
- .SystemError = (uint32_t)err,
- .BytesMoved = 0,
- };
- } else {
- return IoResult{
- .Error = IoResult::ERR_None,
- .SystemError = 0,
- .BytesMoved = (size_t)status, // Equal to number of bytes read
- };
- }
-}
-
-#else
-# error "Unsupported target platform."
-#endif
-
-int InputFileStream::GetReadInSize() const
-{
- return mReadInSize;
-}
-
-void InputFileStream::SetReadInSize(int size)
-{
- if (size > mReadInSize) {
- mReadInSize = size;
- mBuffer = std::make_unique<std::byte[]>(size);
- }
-}
-
-bool InputFileStream::IsEof() const
-{
- return mEof;
-}
-
-IoResult InputFileStream::ReadBytes(size_t bufferLength, std::byte* buffer)
-{
- // TODO reduce duplicated code
-
- auto bytesMoved = std::min<size_t>(mAvailableBytes, bufferLength);
-
- // On first call after construction, mFirstByteIdx will equal to mReadInSize, i.e. bytesAvailable == 0
- // and this call to std::memcpy will be no-op
- std::memcpy(buffer, &mBuffer[mFirstByteIdx], bytesMoved);
- mFirstByteIdx += (int)bytesMoved;
- mAvailableBytes -= (int)bytesMoved;
- buffer += bytesMoved;
-
- size_t bytesLeft = bufferLength - bytesMoved;
- if (bytesLeft > mReadInSize) {
- // Our buffer can't handle rest of the request, just skip the buffering step
-
- // Read rest of the data into buffer
- {
- auto result = ::ReadBytesDirect(mOsFileHandle, bytesLeft, buffer);
- bytesMoved += result.BytesMoved;
-
- if (result.Error == IoResult::ERR_None) {
- if (result.BytesMoved < mReadInSize) {
- mEof = true;
- }
- } else {
- goto end;
- }
- }
-
- // Refill our buffer
- {
- auto result = ::ReadBytesDirect(mOsFileHandle, mReadInSize, mBuffer.get());
- mFirstByteIdx = 0;
- mAvailableBytes = (int)result.BytesMoved;
-
- if (result.Error == IoResult::ERR_None) {
- if (result.BytesMoved < mReadInSize) {
- mEof = true;
- }
- } else {
- goto end;
- }
- }
- } else if (bytesLeft > 0) {
- // Our buffer can handle rest of the request, first buffer than supply the requested data
-
- // Refill our buffer
- {
- auto result = ::ReadBytesDirect(mOsFileHandle, mReadInSize, mBuffer.get());
- mFirstByteIdx = 0;
- mAvailableBytes = (int)result.BytesMoved;
-
- if (result.Error == IoResult::ERR_None) {
- if (result.BytesMoved < mReadInSize) {
- mEof = true;
- }
- } else {
- goto end;
- }
- }
-
- // Copy data into buffer
- {
- std::memcpy(buffer, &mBuffer[mFirstByteIdx], bytesLeft);
- mFirstByteIdx += (int)bytesLeft;
- bytesMoved += bytesLeft;
- buffer += bytesLeft;
- }
- } else {
- // Request completed already
- }
-
-end:
- return IoResult{
- .Error = IoResult::ERR_None,
- .SystemError = 0,
- .BytesMoved = bytesMoved,
- };
-}
-
-int OutputFileStream::GetMaxBufferSize() const
-{
- return mMaxBufferSize;
-}
-
-void OutputFileStream::SetMaxBufferSize(int maxSize)
-{
- FlushBuffer();
- if (maxSize > mMaxBufferSize) {
- mMaxBufferSize = maxSize;
- mBuffer = std::make_unique<std::byte[]>(maxSize);
- }
-}
-
-IoResult OutputFileStream::WriteBytes(size_t bufferLength, const std::byte* buffer)
-{
- if (bufferLength + mCurrentBufferSize > mMaxBufferSize) {
- FlushBuffer();
-
- if (bufferLength > mMaxBufferSize) {
- return ::WriteBytesDirect(mOsFileHandle, bufferLength, buffer);
- }
- }
-
- std::memcpy(mBuffer.get() + mCurrentBufferSize, buffer, bufferLength);
- mCurrentBufferSize += (int)bufferLength;
-
- return IoResult{
- .Error = IoResult::ERR_None,
- .SystemError = 0,
- .BytesMoved = bufferLength,
- };
-}
-
-void OutputFileStream::FlushBuffer()
-{
- ::WriteBytesDirect(mOsFileHandle, mCurrentBufferSize, mBuffer.get());
- mCurrentBufferSize = 0;
-}