diff options
Diffstat (limited to 'boost/process/locale.hpp')
-rw-r--r-- | boost/process/locale.hpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/boost/process/locale.hpp b/boost/process/locale.hpp new file mode 100644 index 0000000000..c8bcf4f9ea --- /dev/null +++ b/boost/process/locale.hpp @@ -0,0 +1,246 @@ +// Copyright (c) 2016 Klemens D. Morgenstern
+// Copyright (c) 2008 Beman Dawes
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ +#ifndef BOOST_PROCESS_LOCALE_HPP_
+#define BOOST_PROCESS_LOCALE_HPP_
+ +#include <system_error>
+#include <boost/process/detail/config.hpp>
+ +#if defined(BOOST_WINDOWS_API)
+#include <boost/process/detail/windows/locale.hpp>
+# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
+|| defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
+#include <codecvt>
+#endif
+ +#include <locale>
+ +namespace boost
+{
+namespace process
+{
+namespace detail
+{
+ +class codecvt_category_t : public std::error_category
+{
+public:
+ codecvt_category_t(){}
+ const char* name() const noexcept override {return "codecvt";}
+ std::string message(int ev) const override
+ {
+ std::string str;
+ switch (ev)
+ {
+ case std::codecvt_base::ok:
+ str = "ok";
+ break;
+ case std::codecvt_base::partial:
+ str = "partial";
+ break;
+ case std::codecvt_base::error:
+ str = "error";
+ break;
+ case std::codecvt_base::noconv:
+ str = "noconv";
+ break;
+ default:
+ str = "unknown error";
+ }
+ return str;
+ }
+};
+ +}
+ +///Internally used error cateory for code conversion.
+inline const std::error_category& codecvt_category()
+{
+ static const ::boost::process::detail::codecvt_category_t cat;
+ return cat;
+}
+ +namespace detail
+{
+//copied from boost.filesystem
+inline std::locale default_locale()
+{
+# if defined(BOOST_WINDOWS_API)
+ std::locale global_loc = std::locale();
+ return std::locale(global_loc, new boost::process::detail::windows::windows_file_codecvt);
+# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
+|| defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
+ std::locale global_loc = std::locale();
+ return std::locale(global_loc, new std::codecvt_utf8<wchar_t>);
+# else // Other POSIX
+ // ISO C calls std::locale("") "the locale-specific native environment", and this
+ // locale is the default for many POSIX-based operating systems such as Linux.
+ return std::locale("");
+# endif
+}
+ +inline std::locale& process_locale()
+{
+ static std::locale loc(default_locale());
+ return loc;
+}
+ +}
+ +///The internally used type for code conversion.
+typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
+ +///Get a reference to the currently used code converter.
+inline const codecvt_type& codecvt()
+{
+ return std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(
+ detail::process_locale());
+}
+ +///Set the locale of the library.
+inline std::locale imbue(const std::locale& loc)
+{
+ std::locale temp(detail::process_locale());
+ detail::process_locale() = loc;
+ return temp;
+}
+ + +namespace detail
+{
+ +inline std::size_t convert(const char* from,
+ const char* from_end,
+ wchar_t* to, wchar_t* to_end,
+ const ::boost::process::codecvt_type & cvt =
+ ::boost::process::codecvt())
+{
+ std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
+ const char* from_next;
+ wchar_t* to_next;
+ + auto res = cvt.in(state, from, from_end, from_next,
+ to, to_end, to_next);
+ + if (res != std::codecvt_base::ok)
+ throw process_error(res, ::boost::process::codecvt_category(),
+ "boost::process codecvt to wchar_t");
+ + + return to_next - to;
+ +}
+ +inline std::size_t convert(const wchar_t* from,
+ const wchar_t* from_end,
+ char* to, char* to_end,
+ const ::boost::process::codecvt_type & cvt =
+ ::boost::process::codecvt())
+{
+ std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
+ const wchar_t* from_next;
+ char* to_next;
+ + std::codecvt_base::result res;
+ + if ((res=cvt.out(state, from, from_end, from_next,
+ to, to_end, to_next)) != std::codecvt_base::ok)
+ throw process_error(res, ::boost::process::codecvt_category(),
+ "boost::process codecvt to char");
+ + return to_next - to;
+}
+ +inline std::wstring convert(const std::string & st,
+ const ::boost::process::codecvt_type & cvt =
+ ::boost::process::codecvt())
+{
+ std::wstring out(st.size() + 10, ' '); //just to be sure
+ auto sz = convert(st.c_str(), st.c_str() + st.size(),
+ &out.front(), &out.back(), cvt);
+ + out.resize(sz);
+ return out;
+}
+ +inline std::string convert(const std::wstring & st,
+ const ::boost::process::codecvt_type & cvt =
+ ::boost::process::codecvt())
+{
+ std::string out(st.size() * 2, ' '); //just to be sure
+ auto sz = convert(st.c_str(), st.c_str() + st.size(),
+ &out.front(), &out.back(), cvt);
+ + out.resize(sz);
+ return out;
+}
+ +inline std::vector<wchar_t> convert(const std::vector<char> & st,
+ const ::boost::process::codecvt_type & cvt =
+ ::boost::process::codecvt())
+{
+ std::vector<wchar_t> out(st.size() + 10); //just to be sure
+ auto sz = convert(st.data(), st.data() + st.size(),
+ &out.front(), &out.back(), cvt);
+ + out.resize(sz);
+ return out;
+}
+ +inline std::vector<char> convert(const std::vector<wchar_t> & st,
+ const ::boost::process::codecvt_type & cvt =
+ ::boost::process::codecvt())
+{
+ std::vector<char> out(st.size() * 2); //just to be sure
+ auto sz = convert(st.data(), st.data() + st.size(),
+ &out.front(), &out.back(), cvt);
+ + out.resize(sz);
+ return out;
+}
+ + +inline std::wstring convert(const char *begin, const char* end,
+ const ::boost::process::codecvt_type & cvt =
+ ::boost::process::codecvt())
+{
+ auto size = end-begin;
+ std::wstring out(size + 10, ' '); //just to be sure
+ using namespace std;
+ auto sz = convert(begin, end,
+ &out.front(), &out.back(), cvt);
+ out.resize(sz);
+ return out;
+}
+ +inline std::string convert(const wchar_t * begin, const wchar_t *end,
+ const ::boost::process::codecvt_type & cvt =
+ ::boost::process::codecvt())
+{
+ auto size = end-begin;
+ + std::string out(size * 2, ' '); //just to be sure
+ auto sz = convert(begin, end ,
+ &out.front(), &out.back(), cvt);
+ + out.resize(sz);
+ return out;
+}
+ + + + +}
+ + + +}
+}
+ + + + +#endif /* BOOST_PROCESS_LOCALE_HPP_ */
|