From dfb44236e9dcdfe5450e71577e60a6ca3c0434ac Mon Sep 17 00:00:00 2001 From: Mika Fischer Date: Mon, 23 Dec 2019 21:24:57 +0100 Subject: [PATCH] file_stdio supports unicode paths: fix #793, close #1791, close #1793 --- CHANGELOG.md | 1 + include/boost/beast/core/impl/file_stdio.ipp | 43 ++++++++++++++++---- test/beast/core/file_stdio.cpp | 4 ++ test/beast/core/file_test.hpp | 2 +- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea1c4001..0d88b21c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Version 282: * Use superproject docca * Fix release build of docs * file_win32 supports UTF-8 paths +* file_stdio supports unicode paths -------------------------------------------------------------------------------- diff --git a/include/boost/beast/core/impl/file_stdio.ipp b/include/boost/beast/core/impl/file_stdio.ipp index e2d03a72..19efa4e1 100644 --- a/include/boost/beast/core/impl/file_stdio.ipp +++ b/include/boost/beast/core/impl/file_stdio.ipp @@ -11,6 +11,7 @@ #define BOOST_BEAST_CORE_IMPL_FILE_STDIO_IPP #include +#include #include #include #include @@ -79,31 +80,47 @@ open(char const* path, file_mode mode, error_code& ec) fclose(f_); f_ = nullptr; } + ec = {}; +#ifdef BOOST_MSVC + boost::winapi::WCHAR_ const* s; + detail::win32_unicode_path unicode_path(path, ec); + if (ec) + return; +#else char const* s; +#endif switch(mode) { default: case file_mode::read: + #ifdef BOOST_MSVC + s = L"rb"; + #else s = "rb"; + #endif break; case file_mode::scan: #ifdef BOOST_MSVC - s = "rbS"; + s = L"rbS"; #else s = "rb"; #endif break; case file_mode::write: + #ifdef BOOST_MSVC + s = L"wb+"; + #else s = "wb+"; + #endif break; case file_mode::write_new: { #if BOOST_WORKAROUND(BOOST_MSVC, < 1910) FILE* f0; - auto const ev = ::fopen_s(&f0, path, "rb"); + auto const ev = ::_wfopen_s(&f0, unicode_path.c_str(), L"rb"); if(! ev) { std::fclose(f0); @@ -116,20 +133,29 @@ open(char const* path, file_mode mode, error_code& ec) ec.assign(ev, generic_category()); return; } - s = "wb"; + s = L"wb"; +#elif defined(BOOST_MSVC) + s = L"wbx"; #else - s = "wbx"; #endif break; } case file_mode::write_existing: + #ifdef BOOST_MSVC + s = L"rb+"; + #else s = "rb+"; + #endif break; case file_mode::append: + #ifdef BOOST_MSVC + s = L"ab"; + #else s = "ab"; + #endif break; case file_mode::append_existing: @@ -137,7 +163,7 @@ open(char const* path, file_mode mode, error_code& ec) #ifdef BOOST_MSVC FILE* f0; auto const ev = - ::fopen_s(&f0, path, "rb+"); + ::_wfopen_s(&f0, unicode_path.c_str(), L"rb+"); if(ev) { ec.assign(ev, generic_category()); @@ -153,13 +179,17 @@ open(char const* path, file_mode mode, error_code& ec) } #endif std::fclose(f0); + #ifdef BOOST_MSVC + s = L"ab"; + #else s = "ab"; + #endif break; } } #ifdef BOOST_MSVC - auto const ev = ::fopen_s(&f_, path, s); + auto const ev = ::_wfopen_s(&f_, unicode_path.c_str(), s); if(ev) { f_ = nullptr; @@ -174,7 +204,6 @@ open(char const* path, file_mode mode, error_code& ec) return; } #endif - ec = {}; } std::uint64_t diff --git a/test/beast/core/file_stdio.cpp b/test/beast/core/file_stdio.cpp index 3b069509..3af8400c 100644 --- a/test/beast/core/file_stdio.cpp +++ b/test/beast/core/file_stdio.cpp @@ -26,7 +26,11 @@ public: void run() { +#ifdef BOOST_MSVC + test_file(); +#else test_file(); +#endif } }; diff --git a/test/beast/core/file_test.hpp b/test/beast/core/file_test.hpp index 82565e17..280bf727 100644 --- a/test/beast/core/file_test.hpp +++ b/test/beast/core/file_test.hpp @@ -40,7 +40,7 @@ test_file() #ifdef _WIN32 boost::winapi::WCHAR_ unicode_suffix[] = { 0xd83e, 0xdd84, 0x0000 }; // UTF-16-LE unicorn #else - char unicode_suffix[] = { 0xf0, 0x9f, 0xa6, 0x84, 0x00 }; // UTF-8 unicorn + char unicode_suffix[] = { '\xf0', '\x9f', '\xa6', '\x84', '\x00' }; // UTF-8 unicorn #endif class temp_path