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/io/file_stream.hpp>
|
||||||
#include <psemek/util/system_error.hpp>
|
#include <psemek/util/system_error.hpp>
|
||||||
|
#include <psemek/util/enum.hpp>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <codecvt>
|
|
||||||
|
|
||||||
namespace psemek::io
|
namespace psemek::io
|
||||||
{
|
{
|
||||||
|
|
||||||
static void throw_fopen [[noreturn]] (std::filesystem::path const & path)
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
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());
|
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)
|
#ifdef __WIN32__
|
||||||
|
wchar_t const * fopen_read_mode()
|
||||||
{
|
{
|
||||||
std::string path_str = path.string();
|
return L"rb";
|
||||||
auto f = std::fopen(path_str.c_str(), mode);
|
}
|
||||||
|
|
||||||
|
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);
|
if (!f) throw_fopen(path);
|
||||||
return f;
|
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_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()
|
void file_istream::reset()
|
||||||
|
|
@ -43,18 +88,8 @@ namespace psemek::io
|
||||||
return std::feof(file_) != 0;
|
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_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()
|
void file_ostream::reset()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue