locale.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. #ifndef BOOST_PROCESS_DETAIL_WINDOWS_LOCALE_HPP_
  7. #define BOOST_PROCESS_DETAIL_WINDOWS_LOCALE_HPP_
  8. #include <boost/process/v1/detail/config.hpp>
  9. #include <locale>
  10. #include <boost/core/ignore_unused.hpp>
  11. #include <boost/winapi/file_management.hpp>
  12. #include <boost/winapi/character_code_conversion.hpp>
  13. namespace boost
  14. {
  15. namespace process
  16. {
  17. BOOST_PROCESS_V1_INLINE namespace v1
  18. {
  19. namespace detail
  20. {
  21. namespace windows
  22. {
  23. //copied from boost.filesystem
  24. class windows_file_codecvt
  25. : public std::codecvt< wchar_t, char, std::mbstate_t >
  26. {
  27. public:
  28. explicit windows_file_codecvt(std::size_t refs = 0)
  29. : std::codecvt<wchar_t, char, std::mbstate_t>(refs) {}
  30. protected:
  31. bool do_always_noconv() const noexcept override { return false; }
  32. // seems safest to assume variable number of characters since we don't
  33. // actually know what codepage is active
  34. int do_encoding() const noexcept override { return 0; }
  35. std::codecvt_base::result do_in(std::mbstate_t& state,
  36. const char* from, const char* from_end, const char*& from_next,
  37. wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const override
  38. {
  39. boost::ignore_unused(state);
  40. auto codepage =
  41. #if !defined(BOOST_NO_ANSI_APIS)
  42. ::boost::winapi::AreFileApisANSI() ?
  43. ::boost::winapi::CP_ACP_ :
  44. #endif
  45. ::boost::winapi::CP_OEMCP_;
  46. int count = 0;
  47. if ((count = ::boost::winapi::MultiByteToWideChar(codepage,
  48. ::boost::winapi::MB_PRECOMPOSED_, from,
  49. static_cast<int>(from_end - from), to, static_cast<int>(to_end - to))) == 0)
  50. {
  51. return error; // conversion failed
  52. }
  53. from_next = from_end;
  54. to_next = to + count;
  55. *to_next = L'\0';
  56. return ok;
  57. }
  58. std::codecvt_base::result do_out(std::mbstate_t & state,
  59. const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next,
  60. char* to, char* to_end, char*& to_next) const override
  61. {
  62. boost::ignore_unused(state);
  63. auto codepage =
  64. #if !defined(BOOST_NO_ANSI_APIS)
  65. ::boost::winapi::AreFileApisANSI() ?
  66. ::boost::winapi::CP_ACP_ :
  67. #endif
  68. ::boost::winapi::CP_OEMCP_;
  69. int count = 0;
  70. if ((count = ::boost::winapi::WideCharToMultiByte(codepage,
  71. ::boost::winapi::WC_NO_BEST_FIT_CHARS_, from,
  72. static_cast<int>(from_end - from), to, static_cast<int>(to_end - to), 0, 0)) == 0)
  73. {
  74. return error; // conversion failed
  75. }
  76. from_next = from_end;
  77. to_next = to + count;
  78. *to_next = '\0';
  79. return ok;
  80. }
  81. std::codecvt_base::result do_unshift(std::mbstate_t&,
  82. char* /*from*/, char* /*to*/, char* & /*next*/) const override { return ok; }
  83. int do_length(std::mbstate_t&,
  84. const char* /*from*/, const char* /*from_end*/, std::size_t /*max*/) const override { return 0; }
  85. int do_max_length() const noexcept override { return 0; }
  86. };
  87. }
  88. }
  89. }
  90. }
  91. }
  92. #endif /* BOOST_PROCESS_LOCALE_HPP_ */