2
0

Unicode.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include "Unicode.h"
  2. #if GP_PLATFORM_WINDOWS
  3. # include <codecvt>
  4. # include <locale>
  5. #else
  6. # include <iconv.h>
  7. #endif
  8. namespace gameplay
  9. {
  10. #if GP_PLATFORM_WINDOWS
  11. class Locale
  12. {
  13. public:
  14. Locale(const char* localeName)
  15. {
  16. locale = _create_locale(LC_ALL, localeName);
  17. }
  18. ~Locale()
  19. {
  20. _free_locale(locale);
  21. }
  22. _locale_t get_locale()
  23. {
  24. return locale;
  25. }
  26. private:
  27. _locale_t locale;
  28. };
  29. static inline auto _get_system_default_locale()
  30. {
  31. static Locale locale("");
  32. return locale.get_locale();
  33. }
  34. static inline auto& _get_wide_converter()
  35. {
  36. GP_IGNOREWARNING_MSC_WITH_PUSH(4996)
  37. static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter(
  38. Unicode::WIDE_TO_UTF8_FAILURE, Unicode::UTF8_TO_WIDE_FAILURE);
  39. GP_IGNOREWARNING_MSC_POP
  40. return converter;
  41. }
  42. std::string Unicode::convert_wide_to_utf8(const wchar_t* wide)
  43. {
  44. GP_IGNOREWARNING_MSC_WITH_PUSH(4996)
  45. return _get_wide_converter().to_bytes(wide);
  46. GP_IGNOREWARNING_MSC_POP
  47. }
  48. std::string Unicode::convert_wide_to_utf8(const std::wstring& wide)
  49. {
  50. GP_IGNOREWARNING_MSC_WITH_PUSH(4996)
  51. return _get_wide_converter().to_bytes(wide);
  52. GP_IGNOREWARNING_MSC_POP
  53. }
  54. std::wstring Unicode::convert_utf8_to_wide(const char* utf8)
  55. {
  56. GP_IGNOREWARNING_MSC_WITH_PUSH(4996)
  57. return _get_wide_converter().from_bytes(utf8);
  58. GP_IGNOREWARNING_MSC_POP
  59. }
  60. std::wstring Unicode::convert_utf8_to_wide(const std::string& utf8)
  61. {
  62. GP_IGNOREWARNING_MSC_WITH_PUSH(4996)
  63. return _get_wide_converter().from_bytes(utf8);
  64. GP_IGNOREWARNING_MSC_POP
  65. }
  66. int Unicode::compare_wide_strings_case_insensitive(const wchar_t* str1, const wchar_t* str2)
  67. {
  68. return _wcsicmp_l(str1, str2, _get_system_default_locale());
  69. }
  70. int Unicode::compare_wide_strings_case_insensitive(const std::wstring& str1, const std::wstring& str2)
  71. {
  72. return compare_wide_strings_case_insensitive(str1.c_str(), str2.c_str());
  73. }
  74. std::wstring Unicode::convert_wide_string_to_uppercase(const std::wstring& str)
  75. {
  76. std::wstring result = str;
  77. _wcsupr_s_l(&result[0], result.size() + 1, _get_system_default_locale());
  78. return result;
  79. }
  80. void Unicode::convert_wide_string_to_uppercase_in_place(std::wstring& str)
  81. {
  82. _wcsupr_s_l(&str[0], str.size() + 1, _get_system_default_locale());
  83. }
  84. std::wstring Unicode::convert_wide_string_to_lowercase(const std::wstring& str)
  85. {
  86. std::wstring result = str;
  87. _wcslwr_s_l(&result[0], result.size() + 1, _get_system_default_locale());
  88. return result;
  89. }
  90. void Unicode::convert_wide_string_to_cowercase_in_place(std::wstring& string)
  91. {
  92. _wcslwr_s_l(&string[0], string.size() + 1, _get_system_default_locale());
  93. }
  94. #endif
  95. std::string Unicode::convert_utf32_to_utf8(uint32_t codepoint)
  96. {
  97. std::string u8str;
  98. #if GP_PLATFORM_WINDOWS
  99. GP_IGNOREWARNING_MSC_WITH_PUSH(4996)
  100. static std::wstring_convert<std::codecvt_utf8<uint32_t>, uint32_t> converter(UTF32_TO_UTF8_FAILURE);
  101. u8str = converter.to_bytes(codepoint);
  102. GP_IGNOREWARNING_MSC_POP
  103. #else
  104. char* input = reinterpret_cast<char*>(&codepoint);
  105. size_t in_size = sizeof(uint32_t);
  106. char output_buffer[5] = { '\0' };
  107. char* output = output_buffer;
  108. size_t out_size = sizeof(output_buffer) - 1;
  109. iconv_t cd = iconv_open("UTF-8", "UTF-32");
  110. size_t ret = iconv(cd, &input, &in_size, &output, &out_size);
  111. iconv_close(cd);
  112. if (ret == (size_t)-1)
  113. {
  114. u8str = UTF32_TO_UTF8_FAILURE;
  115. }
  116. else
  117. {
  118. u8str = std::string(output_buffer);
  119. }
  120. #endif
  121. return u8str;
  122. }
  123. }