1 // Copyright (c) 2016 Klemens D. Morgenstern
\r
2 // Copyright (c) 2008 Beman Dawes
\r
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
\r
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
\r
6 #ifndef BOOST_PROCESS_LOCALE_HPP_
\r
7 #define BOOST_PROCESS_LOCALE_HPP_
\r
9 #include <system_error>
\r
10 #include <boost/process/detail/config.hpp>
\r
12 #if defined(BOOST_WINDOWS_API)
\r
13 #include <boost/process/detail/windows/locale.hpp>
\r
14 # elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
\r
15 || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
\r
28 class codecvt_category_t : public std::error_category
\r
31 codecvt_category_t(){}
\r
32 const char* name() const noexcept override {return "codecvt";}
\r
33 std::string message(int ev) const override
\r
38 case std::codecvt_base::ok:
\r
41 case std::codecvt_base::partial:
\r
44 case std::codecvt_base::error:
\r
47 case std::codecvt_base::noconv:
\r
51 str = "unknown error";
\r
59 ///Internally used error cateory for code conversion.
\r
60 inline const std::error_category& codecvt_category()
\r
62 static const ::boost::process::detail::codecvt_category_t cat;
\r
68 //copied from boost.filesystem
\r
69 inline std::locale default_locale()
\r
71 # if defined(BOOST_WINDOWS_API)
\r
72 std::locale global_loc = std::locale();
\r
73 return std::locale(global_loc, new boost::process::detail::windows::windows_file_codecvt);
\r
74 # elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
\r
75 || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
\r
76 std::locale global_loc = std::locale();
\r
77 return std::locale(global_loc, new std::codecvt_utf8<wchar_t>);
\r
78 # else // Other POSIX
\r
79 // ISO C calls std::locale("") "the locale-specific native environment", and this
\r
80 // locale is the default for many POSIX-based operating systems such as Linux.
\r
81 return std::locale("");
\r
85 inline std::locale& process_locale()
\r
87 static std::locale loc(default_locale());
\r
93 ///The internally used type for code conversion.
\r
94 typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
\r
96 ///Get a reference to the currently used code converter.
\r
97 inline const codecvt_type& codecvt()
\r
99 return std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(
\r
100 detail::process_locale());
\r
103 ///Set the locale of the library.
\r
104 inline std::locale imbue(const std::locale& loc)
\r
106 std::locale temp(detail::process_locale());
\r
107 detail::process_locale() = loc;
\r
115 inline std::size_t convert(const char* from,
\r
116 const char* from_end,
\r
117 wchar_t* to, wchar_t* to_end,
\r
118 const ::boost::process::codecvt_type & cvt =
\r
119 ::boost::process::codecvt())
\r
121 std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
\r
122 const char* from_next;
\r
125 auto res = cvt.in(state, from, from_end, from_next,
\r
126 to, to_end, to_next);
\r
128 if (res != std::codecvt_base::ok)
\r
129 throw process_error(res, ::boost::process::codecvt_category(),
\r
130 "boost::process codecvt to wchar_t");
\r
133 return to_next - to;
\r
137 inline std::size_t convert(const wchar_t* from,
\r
138 const wchar_t* from_end,
\r
139 char* to, char* to_end,
\r
140 const ::boost::process::codecvt_type & cvt =
\r
141 ::boost::process::codecvt())
\r
143 std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
\r
144 const wchar_t* from_next;
\r
147 std::codecvt_base::result res;
\r
149 if ((res=cvt.out(state, from, from_end, from_next,
\r
150 to, to_end, to_next)) != std::codecvt_base::ok)
\r
151 throw process_error(res, ::boost::process::codecvt_category(),
\r
152 "boost::process codecvt to char");
\r
154 return to_next - to;
\r
157 inline std::wstring convert(const std::string & st,
\r
158 const ::boost::process::codecvt_type & cvt =
\r
159 ::boost::process::codecvt())
\r
161 std::wstring out(st.size() + 10, ' '); //just to be sure
\r
162 auto sz = convert(st.c_str(), st.c_str() + st.size(),
\r
163 &out.front(), &out.back(), cvt);
\r
169 inline std::string convert(const std::wstring & st,
\r
170 const ::boost::process::codecvt_type & cvt =
\r
171 ::boost::process::codecvt())
\r
173 std::string out(st.size() * 2, ' '); //just to be sure
\r
174 auto sz = convert(st.c_str(), st.c_str() + st.size(),
\r
175 &out.front(), &out.back(), cvt);
\r
181 inline std::vector<wchar_t> convert(const std::vector<char> & st,
\r
182 const ::boost::process::codecvt_type & cvt =
\r
183 ::boost::process::codecvt())
\r
185 std::vector<wchar_t> out(st.size() + 10); //just to be sure
\r
186 auto sz = convert(st.data(), st.data() + st.size(),
\r
187 &out.front(), &out.back(), cvt);
\r
193 inline std::vector<char> convert(const std::vector<wchar_t> & st,
\r
194 const ::boost::process::codecvt_type & cvt =
\r
195 ::boost::process::codecvt())
\r
197 std::vector<char> out(st.size() * 2); //just to be sure
\r
198 auto sz = convert(st.data(), st.data() + st.size(),
\r
199 &out.front(), &out.back(), cvt);
\r
206 inline std::wstring convert(const char *begin, const char* end,
\r
207 const ::boost::process::codecvt_type & cvt =
\r
208 ::boost::process::codecvt())
\r
210 auto size = end-begin;
\r
211 std::wstring out(size + 10, ' '); //just to be sure
\r
212 using namespace std;
\r
213 auto sz = convert(begin, end,
\r
214 &out.front(), &out.back(), cvt);
\r
219 inline std::string convert(const wchar_t * begin, const wchar_t *end,
\r
220 const ::boost::process::codecvt_type & cvt =
\r
221 ::boost::process::codecvt())
\r
223 auto size = end-begin;
\r
225 std::string out(size * 2, ' '); //just to be sure
\r
226 auto sz = convert(begin, end ,
\r
227 &out.front(), &out.back(), cvt);
\r
246 #endif /* BOOST_PROCESS_LOCALE_HPP_ */
\r