aboutsummaryrefslogtreecommitdiff
path: root/source/Utils.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-04-08 22:30:12 -0700
committerrtk0c <[email protected]>2022-04-08 22:30:12 -0700
commite7ef3f208c109357538b1f68af10bcd78db95c95 (patch)
tree066d614ae0f079e53602d7c0fd972998c546c8c1 /source/Utils.cpp
parentf163e8f37123e651ea80b690793845b31ddb8639 (diff)
Changeset: 3 More work
Diffstat (limited to 'source/Utils.cpp')
-rw-r--r--source/Utils.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/source/Utils.cpp b/source/Utils.cpp
new file mode 100644
index 0000000..d47f35b
--- /dev/null
+++ b/source/Utils.cpp
@@ -0,0 +1,58 @@
+#include "Utils.hpp"
+
+#ifdef _WIN32
+# include <Windows.h>
+#endif
+
+#ifdef _WIN32
+# define BRUSSEL_MODE_STRING(string) L##string
+#else
+# define BRUSSEL_MODE_STRING(string) string
+#endif
+
+#if _WIN32
+using FopenModeString = const wchar_t*;
+#else
+using FopenModeString = const char*;
+#endif
+
+static FopenModeString GetModeString(Utils::IoMode mode, bool binary) {
+ using namespace Utils;
+ if (binary) {
+ switch (mode) {
+ case Read: return BRUSSEL_MODE_STRING("r");
+ case WriteTruncate: return BRUSSEL_MODE_STRING("w");
+ case WriteAppend: return BRUSSEL_MODE_STRING("a");
+ }
+ } else {
+ switch (mode) {
+ case Read: return BRUSSEL_MODE_STRING("rb");
+ case WriteTruncate: return BRUSSEL_MODE_STRING("wb");
+ case WriteAppend: return BRUSSEL_MODE_STRING("ab");
+ }
+ }
+ return nullptr;
+}
+
+FILE* Utils::OpenCstdioFile(const std::filesystem::path& path, IoMode mode, bool binary) {
+#ifdef _WIN32
+ // std::filesystem::path::c_str() returns `const wchar_t*` under Windows, because NT uses UTF-16 natively
+ // NOTE: _wfopen() only affects the type of path parameter, otherwise the file stream created is identical to the one by fopen()
+ return _wfopen(path.c_str(), ::GetModeString(mode, binary));
+#else
+ return fopen(path.c_str(), ::GetModeString(mode, binary));
+#endif
+}
+
+FILE* Utils::OpenCstdioFile(const char* path, IoMode mode, bool binary) {
+#ifdef _WIN32
+ // On Windows, fopen() accepts ANSI codepage encoded path, convert our UTF-8 string to UTF-16 to ensure that no matter what the locale is, the path continues to work
+ WCHAR platformPath[MAX_PATH];
+ if (MultiByteToWideChar(CP_UTF8, 0, path, -1, platformPath, MAX_PATH) == 0) {
+ return nullptr;
+ }
+ return _wfopen(platformPath, ::GetModeString(mode, binary));
+#else
+ return fopen(path, ::GetModeString(mode, binary));
+#endif
+}