• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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