Use wide strings for io::file_stream on Windows
This commit is contained in:
parent
dab7b6327e
commit
ef85eec178
1 changed files with 57 additions and 22 deletions
|
|
@ -1,27 +1,72 @@
|
|||
#include <psemek/io/file_stream.hpp>
|
||||
#include <psemek/util/system_error.hpp>
|
||||
#include <psemek/util/enum.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <codecvt>
|
||||
|
||||
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()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue