diff options
Diffstat (limited to 'core/src/Utils')
-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 | ||||
-rw-r--r-- | core/src/Utils/StandardDirectories.cpp | 18 |
4 files changed, 139 insertions, 31 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; }; diff --git a/core/src/Utils/StandardDirectories.cpp b/core/src/Utils/StandardDirectories.cpp index e7d3657..2202f51 100644 --- a/core/src/Utils/StandardDirectories.cpp +++ b/core/src/Utils/StandardDirectories.cpp @@ -5,7 +5,7 @@ namespace fs = std::filesystem; -#if PLATFORM_WIN32 +#if defined(_WIN32) // https://stackoverflow.com/questions/54499256/how-to-find-the-saved-games-folder-programmatically-in-c-c # include <ShlObj_core.h> # include <objbase.h> @@ -29,9 +29,9 @@ static fs::path GetAppDataRoaming() } } -#elif PLATFORM_MACOS +#elif defined(__APPLE__) // TODO -#elif PLATFORM_LINUX +#elif defined(__linux__) # include <cstdlib> static fs::path GetEnvVar(const char* name, const char* backup) @@ -52,11 +52,11 @@ static fs::path GetEnvVar(const char* name, const char* backup) const std::filesystem::path& StandardDirectories::UserData() { static auto userDataDir = []() -> fs::path { -#if PLATFORM_WIN32 +#if defined(_WIN32) return GetAppDataRoaming(); -#elif PLATFORM_MACOS +#elif defined(__APPLE__) // TODO where? -#elif PLATFORM_LINUX +#elif defined(__linux__) return GetEnvVar("XDG_DATA_HOME", "~/.local/share"); #endif }(); @@ -66,11 +66,11 @@ const std::filesystem::path& StandardDirectories::UserData() const std::filesystem::path& StandardDirectories::UserConfig() { static auto userConfigDir = []() -> fs::path { -#if PLATFORM_WIN32 +#if defined(_WIN32) return GetAppDataRoaming(); -#elif PLATFORM_MACOS +#elif defined(__APPLE__) // TODO where? -#elif PLATFORM_LINUX +#elif defined(__linux__) return GetEnvVar("XDG_CONFIG_HOME", "~/.config"); #endif }(); |