diff options
Diffstat (limited to 'core/src/Utils/IO')
-rw-r--r-- | core/src/Utils/IO/DataStream.cpp | 28 | ||||
-rw-r--r-- | core/src/Utils/IO/FileStream.cpp | 122 | ||||
-rw-r--r-- | core/src/Utils/IO/FileStream.hpp | 2 |
3 files changed, 130 insertions, 22 deletions
diff --git a/core/src/Utils/IO/DataStream.cpp b/core/src/Utils/IO/DataStream.cpp index bfc6252..c0797e3 100644 --- a/core/src/Utils/IO/DataStream.cpp +++ b/core/src/Utils/IO/DataStream.cpp @@ -21,7 +21,7 @@ static uint16_t ByteSwap(uint16_t n) static uint32_t ByteSwap(uint32_t n) { #ifdef _MSC_VER - // TODO + return _byteswap_ulong(n); #else return __builtin_bswap32(n); #endif @@ -30,7 +30,7 @@ static uint32_t ByteSwap(uint32_t n) static uint64_t ByteSwap(uint64_t n) { #ifdef _MSC_VER - // TODO + return _byteswap_uint64(n); #else return __builtin_bswap64(n); #endif @@ -62,34 +62,34 @@ InputDataStream::InputDataStream(InputFileStream stream) void InputDataStream::ReadBytes(size_t byteCount, std::byte* buffer) { - mBackend.ReadBytes(static_cast<std::streamsize>(byteCount),reinterpret_cast<std::byte*>(buffer)); + mBackend.ReadBytes(static_cast<std::streamsize>(byteCount), reinterpret_cast<std::byte*>(buffer)); } void InputDataStream::ReadBytes(size_t byteCount, char* buffer) { - mBackend.ReadBytes(static_cast<std::streamsize>(byteCount),reinterpret_cast<std::byte*>(buffer)); + mBackend.ReadBytes(static_cast<std::streamsize>(byteCount), reinterpret_cast<std::byte*>(buffer)); } void InputDataStream::ReadBytes(size_t byteCount, signed char* buffer) { - mBackend.ReadBytes(static_cast<std::streamsize>(byteCount),reinterpret_cast<std::byte*>(buffer)); + mBackend.ReadBytes(static_cast<std::streamsize>(byteCount), reinterpret_cast<std::byte*>(buffer)); } void InputDataStream::ReadBytes(size_t byteCount, unsigned char* buffer) { - mBackend.ReadBytes(static_cast<std::streamsize>(byteCount),reinterpret_cast<std::byte*>(buffer)); + mBackend.ReadBytes(static_cast<std::streamsize>(byteCount), reinterpret_cast<std::byte*>(buffer)); } void InputDataStream::Read(int8_t& n) { // sizeof() of a reference type yields the size of the reference - mBackend.ReadBytes(sizeof(n),reinterpret_cast<std::byte*>(&n)); + mBackend.ReadBytes(sizeof(n), reinterpret_cast<std::byte*>(&n)); } void InputDataStream::Read(int16_t& n) { int16_t tmp; - mBackend.ReadBytes(sizeof(tmp),reinterpret_cast<std::byte*>(&tmp)); + mBackend.ReadBytes(sizeof(tmp), reinterpret_cast<std::byte*>(&tmp)); if (GetEndianness() != std::endian::native) { n = ::ByteSwap(tmp); } else { @@ -100,7 +100,7 @@ void InputDataStream::Read(int16_t& n) void InputDataStream::Read(int32_t& n) { int32_t tmp; - mBackend.ReadBytes(sizeof(tmp),reinterpret_cast<std::byte*>(&tmp)); + mBackend.ReadBytes(sizeof(tmp), reinterpret_cast<std::byte*>(&tmp)); if (GetEndianness() != std::endian::native) { n = ::ByteSwap(tmp); } else { @@ -111,7 +111,7 @@ void InputDataStream::Read(int32_t& n) void InputDataStream::Read(int64_t& n) { int64_t tmp; - mBackend.ReadBytes(sizeof(tmp),reinterpret_cast<std::byte*>(&tmp)); + mBackend.ReadBytes(sizeof(tmp), reinterpret_cast<std::byte*>(&tmp)); if (GetEndianness() != std::endian::native) { n = ::ByteSwap(tmp); } else { @@ -121,13 +121,13 @@ void InputDataStream::Read(int64_t& n) void InputDataStream::Read(uint8_t& n) { - mBackend.ReadBytes(sizeof(n),reinterpret_cast<std::byte*>(&n)); + mBackend.ReadBytes(sizeof(n), reinterpret_cast<std::byte*>(&n)); } void InputDataStream::Read(uint16_t& n) { uint16_t tmp; - mBackend.ReadBytes(sizeof(tmp),reinterpret_cast<std::byte*>(&tmp)); + mBackend.ReadBytes(sizeof(tmp), reinterpret_cast<std::byte*>(&tmp)); if (GetEndianness() != std::endian::native) { n = ::ByteSwap(tmp); } else { @@ -138,7 +138,7 @@ void InputDataStream::Read(uint16_t& n) void InputDataStream::Read(uint32_t& n) { uint32_t tmp; - mBackend.ReadBytes(sizeof(tmp),reinterpret_cast<std::byte*>(&tmp)); + mBackend.ReadBytes(sizeof(tmp), reinterpret_cast<std::byte*>(&tmp)); if (GetEndianness() != std::endian::native) { n = ::ByteSwap(tmp); } else { @@ -149,7 +149,7 @@ void InputDataStream::Read(uint32_t& n) void InputDataStream::Read(uint64_t& n) { uint64_t tmp; - mBackend.ReadBytes(sizeof(tmp),reinterpret_cast<std::byte*>(&tmp)); + mBackend.ReadBytes(sizeof(tmp), reinterpret_cast<std::byte*>(&tmp)); if (GetEndianness() != std::endian::native) { n = ::ByteSwap(tmp); } else { diff --git a/core/src/Utils/IO/FileStream.cpp b/core/src/Utils/IO/FileStream.cpp index bc95b7e..b9ef2a7 100644 --- a/core/src/Utils/IO/FileStream.cpp +++ b/core/src/Utils/IO/FileStream.cpp @@ -3,17 +3,125 @@ #include <cstring> #include <iostream> -#if PLATFORM_WIN32 +namespace fs = std::filesystem; -// TODO +#if defined(_WIN32) +# define WIN32_LEAN_AND_MEAN +# define NOMINMAX +# include <Windows.h> -#elif PLATFORM_MACOS || PLATFORM_LINUX +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 std::filesystem::path& path) +InputFileStream::InputFileStream(const fs::path& path) : mOsFileHandle{ 0 } { auto fd = reinterpret_cast<int*>(mOsFileHandle); @@ -26,7 +134,7 @@ InputFileStream::~InputFileStream() close(*fd); } -OutputFileStream::OutputFileStream(const std::filesystem::path& path, WriteMode mode) +OutputFileStream::OutputFileStream(const fs::path& path, WriteMode mode) : mOsFileHandle{ 0 } { auto fd = reinterpret_cast<int*>(mOsFileHandle); @@ -70,7 +178,7 @@ static IoResult ReadBytesDirect(const char* osFileHandle, size_t byteCount, std: int err = errno; return IoResult{ .Error = ::MapErrnoToIoResult(err), - .SystemError = err, + .SystemError = (uint32_t)err, .BytesMoved = 0, }; } else { @@ -91,7 +199,7 @@ static IoResult WriteBytesDirect(const char* osFileHandle, size_t byteCount, con int err = errno; return IoResult{ .Error = ::MapErrnoToIoResult(err), - .SystemError = err, + .SystemError = (uint32_t)err, .BytesMoved = 0, }; } else { diff --git a/core/src/Utils/IO/FileStream.hpp b/core/src/Utils/IO/FileStream.hpp index 9f5f24a..5b91632 100644 --- a/core/src/Utils/IO/FileStream.hpp +++ b/core/src/Utils/IO/FileStream.hpp @@ -18,7 +18,7 @@ struct IoResult }; ErrorKind Error; - int32_t SystemError; + uint32_t SystemError; size_t BytesMoved; }; |