cp_converter.hpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #pragma once
  2. #include <string>
  3. #include <windows.h>
  4. #include "exceptions/win32_exception.hpp"
  5. #define NKG_CURRENT_SOURCE_FILE() u8".\\common\\cp_converter.hpp"
  6. #define NKG_CURRENT_SOURCE_LINE() __LINE__
  7. namespace nkg {
  8. template<int from_cp, int to_cp>
  9. struct cp_converter {
  10. static std::string convert(std::string_view from_string) {
  11. if constexpr (from_cp == to_cp) {
  12. return from_string;
  13. } else {
  14. if (from_cp == CP_ACP && GetACP() == to_cp) {
  15. return from_string;
  16. } else {
  17. return cp_converter<-1, to_cp>::convert(cp_converter<from_cp, -1>::convert(from_string));
  18. }
  19. }
  20. }
  21. };
  22. template<int from_cp>
  23. struct cp_converter<from_cp, -1> {
  24. static std::wstring convert(std::string_view from_string) {
  25. int len;
  26. len = MultiByteToWideChar(from_cp, 0, from_string.data(), -1, NULL, 0);
  27. if (len <= 0) {
  28. throw ::nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"MultiByteToWideChar failed.");
  29. }
  30. std::wstring to_string(len, 0);
  31. len = MultiByteToWideChar(from_cp, 0, from_string.data(), -1, to_string.data(), len);
  32. if (len <= 0) {
  33. throw ::nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"MultiByteToWideChar failed.");
  34. }
  35. while (to_string.length() > 0 && to_string.back() == 0) {
  36. to_string.pop_back();
  37. }
  38. return to_string;
  39. }
  40. };
  41. template<int to_cp>
  42. struct cp_converter<-1, to_cp> {
  43. static std::string convert(std::wstring_view from_string) {
  44. int len;
  45. len = WideCharToMultiByte(to_cp, 0, from_string.data(), -1, NULL, 0, NULL, NULL);
  46. if (len <= 0) {
  47. throw ::nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"WideCharToMultiByte failed.");
  48. }
  49. std::string to_string(len, 0);
  50. len = WideCharToMultiByte(to_cp, 0, from_string.data(), -1, to_string.data(), len, NULL, NULL);
  51. if (len <= 0) {
  52. throw ::nkg::exceptions::win32_exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), u8"WideCharToMultiByte failed.");
  53. }
  54. while (to_string.length() > 0 && to_string.back() == 0) {
  55. to_string.pop_back();
  56. }
  57. return to_string;
  58. }
  59. };
  60. }
  61. #undef NKG_CURRENT_SOURCE_LINE
  62. #undef NKG_CURRENT_SOURCE_FILE