From ef85eec1781d9fc311905de03cc0a63d9363a550 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Tue, 4 Mar 2025 18:12:21 +0300 Subject: [PATCH] Use wide strings for io::file_stream on Windows --- libs/io/source/file_stream.cpp | 79 ++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 22 deletions(-) diff --git a/libs/io/source/file_stream.cpp b/libs/io/source/file_stream.cpp index 7c1cc481..089b9c71 100644 --- a/libs/io/source/file_stream.cpp +++ b/libs/io/source/file_stream.cpp @@ -1,27 +1,72 @@ #include #include +#include #include -#include namespace psemek::io { - static void throw_fopen [[noreturn]] (std::filesystem::path const & path) + namespace { - throw util::system_error(std::error_code{errno, std::system_category()}, "Failed to open " + path.string()); - } - static FILE * safe_fopen(std::filesystem::path const & path, const char * mode) - { - std::string path_str = path.string(); - auto f = std::fopen(path_str.c_str(), mode); - if (!f) throw_fopen(path); - return f; + void throw_fopen [[noreturn]] (std::filesystem::path const & path) + { + throw util::system_error(std::error_code{errno, std::system_category()}, "Failed to open " + path.string()); + } + +#ifdef __WIN32__ + wchar_t const * fopen_read_mode() + { + return L"rb"; + } + + wchar_t const * fopen_write_mode(unsigned flags) + { + switch (flags) + { + case 0: return L"wb"; + case file_ostream::append: return L"ab"; + } + + throw util::exception("Unknown file_ostream open flags"); + } + + FILE * safe_fopen(std::filesystem::path const & path, wchar_t const * mode) + { + auto f = _wfopen(path.c_str(), mode); + if (!f) throw_fopen(path); + return f; + } +#else + char const * fopen_read_mode() + { + return "rb"; + } + + char const * fopen_write_mode(unsigned flags) + { + switch (flags) + { + case 0: return "wb"; + case file_ostream::append: return "ab"; + } + + throw util::exception("Unknown file_ostream open flags"); + } + + FILE * safe_fopen(std::filesystem::path const & path, char const * mode) + { + auto f = std::fopen(path.c_str(), mode); + if (!f) throw_fopen(path); + return f; + } +#endif + } file_istream::file_istream(std::filesystem::path const & path) - : file_{safe_fopen(path.c_str(), "rb")} + : file_{safe_fopen(path, fopen_read_mode())} {} void file_istream::reset() @@ -43,18 +88,8 @@ namespace psemek::io return std::feof(file_) != 0; } - static char const * fopen_write_mode(unsigned flags) - { - switch (flags) - { - case 0: return "wb"; - case file_ostream::append: return "ab"; - default: throw util::exception("Unknown file_ostream open flags"); - } - } - file_ostream::file_ostream(std::filesystem::path const & path, unsigned flags) - : file_{safe_fopen(path.c_str(), fopen_write_mode(flags))} + : file_{safe_fopen(path, fopen_write_mode(flags))} {} void file_ostream::reset()