1 // Copyright (c) 2016 Klemens D. Morgenstern 2 // Copyright (c) 2008 Beman Dawes 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 7 #ifndef BOOST_PROCESS_DETAIL_WINDOWS_LOCALE_HPP_ 8 #define BOOST_PROCESS_DETAIL_WINDOWS_LOCALE_HPP_ 9 10 #include <locale> 11 #include <boost/core/ignore_unused.hpp> 12 #include <boost/winapi/file_management.hpp> 13 #include <boost/winapi/character_code_conversion.hpp> 14 15 namespace boost 16 { 17 namespace process 18 { 19 namespace detail 20 { 21 namespace windows 22 { 23 24 //copied from boost.filesystem 25 class windows_file_codecvt 26 : public std::codecvt< wchar_t, char, std::mbstate_t > 27 { 28 public: windows_file_codecvt(std::size_t refs=0)29 explicit windows_file_codecvt(std::size_t refs = 0) 30 : std::codecvt<wchar_t, char, std::mbstate_t>(refs) {} 31 protected: 32 do_always_noconv() const33 bool do_always_noconv() const noexcept override { return false; } 34 35 // seems safest to assume variable number of characters since we don't 36 // actually know what codepage is active do_encoding() const37 int do_encoding() const noexcept override { return 0; } 38 do_in(std::mbstate_t & state,const char * from,const char * from_end,const char * & from_next,wchar_t * to,wchar_t * to_end,wchar_t * & to_next) const39 std::codecvt_base::result do_in(std::mbstate_t& state, 40 const char* from, const char* from_end, const char*& from_next, 41 wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const override 42 { 43 boost::ignore_unused(state); 44 45 auto codepage = 46 #if !defined(BOOST_NO_ANSI_APIS) 47 ::boost::winapi::AreFileApisANSI() ? 48 ::boost::winapi::CP_ACP_ : 49 #endif 50 ::boost::winapi::CP_OEMCP_; 51 52 int count = 0; 53 if ((count = ::boost::winapi::MultiByteToWideChar(codepage, 54 ::boost::winapi::MB_PRECOMPOSED_, from, 55 static_cast<int>(from_end - from), to, static_cast<int>(to_end - to))) == 0) 56 { 57 return error; // conversion failed 58 } 59 60 from_next = from_end; 61 to_next = to + count; 62 *to_next = L'\0'; 63 return ok; 64 } 65 do_out(std::mbstate_t & state,const wchar_t * from,const wchar_t * from_end,const wchar_t * & from_next,char * to,char * to_end,char * & to_next) const66 std::codecvt_base::result do_out(std::mbstate_t & state, 67 const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, 68 char* to, char* to_end, char*& to_next) const override 69 { 70 boost::ignore_unused(state); 71 auto codepage = 72 #if !defined(BOOST_NO_ANSI_APIS) 73 ::boost::winapi::AreFileApisANSI() ? 74 ::boost::winapi::CP_ACP_ : 75 #endif 76 ::boost::winapi::CP_OEMCP_; 77 int count = 0; 78 79 80 if ((count = ::boost::winapi::WideCharToMultiByte(codepage, 81 ::boost::winapi::WC_NO_BEST_FIT_CHARS_, from, 82 static_cast<int>(from_end - from), to, static_cast<int>(to_end - to), 0, 0)) == 0) 83 { 84 return error; // conversion failed 85 } 86 87 from_next = from_end; 88 to_next = to + count; 89 *to_next = '\0'; 90 return ok; 91 } 92 do_unshift(std::mbstate_t &,char *,char *,char * &) const93 std::codecvt_base::result do_unshift(std::mbstate_t&, 94 char* /*from*/, char* /*to*/, char* & /*next*/) const override { return ok; } 95 do_length(std::mbstate_t &,const char *,const char *,std::size_t) const96 int do_length(std::mbstate_t&, 97 const char* /*from*/, const char* /*from_end*/, std::size_t /*max*/) const override { return 0; } 98 do_max_length() const99 int do_max_length() const noexcept override { return 0; } 100 }; 101 102 103 104 } 105 } 106 } 107 } 108 109 110 111 #endif /* BOOST_PROCESS_LOCALE_HPP_ */ 112