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