VmStringUtils.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include "il2cpp-config.h"
  2. #if !RUNTIME_TINY
  3. #include "VmStringUtils.h"
  4. #include "il2cpp-object-internals.h"
  5. #include "../char-conversions.h"
  6. #include "utils/Functional.h"
  7. #include "utils/StringUtils.h"
  8. #include "utils/utf8-cpp/source/utf8/unchecked.h"
  9. namespace il2cpp
  10. {
  11. namespace utils
  12. {
  13. Il2CppChar VmStringUtils::Utf16ToLower(Il2CppChar c)
  14. {
  15. const Il2CppChar kDataLowThreshold = 9423;
  16. const Il2CppChar kDataHighThreshold = 65313;
  17. if (c <= kDataLowThreshold)
  18. {
  19. c = ToLowerDataLow[c];
  20. }
  21. else if (c >= kDataHighThreshold)
  22. {
  23. c = ToLowerDataHigh[c - kDataHighThreshold];
  24. }
  25. return c;
  26. }
  27. bool VmStringUtils::CaseSensitiveComparer::operator()(const std::string& left, const std::string& right) const
  28. {
  29. return left == right;
  30. }
  31. bool VmStringUtils::CaseSensitiveComparer::operator()(const std::string& left, const char* right) const
  32. {
  33. return left.compare(right) == 0;
  34. }
  35. bool VmStringUtils::CaseSensitiveComparer::operator()(const char* left, const std::string& right) const
  36. {
  37. return right.compare(left) == 0;
  38. }
  39. bool VmStringUtils::CaseSensitiveComparer::operator()(const char* left, const char* right) const
  40. {
  41. return strcmp(left, right) == 0;
  42. }
  43. static inline void Utf32CharToSurrogatePair(uint32_t c, Il2CppChar(&surrogatePair)[2])
  44. {
  45. const Il2CppChar kLeadOffset = 55232;
  46. const Il2CppChar kTrailSurrogateMin = 56320;
  47. if (c > 0xffff)
  48. {
  49. surrogatePair[0] = static_cast<Il2CppChar>((c >> 10) + kLeadOffset);
  50. surrogatePair[1] = static_cast<Il2CppChar>((c & 0x3ff) + kTrailSurrogateMin);
  51. }
  52. else
  53. {
  54. surrogatePair[0] = static_cast<Il2CppChar>(c);
  55. surrogatePair[1] = 0;
  56. }
  57. }
  58. static inline bool Utf16CharEqualsIgnoreCase(Il2CppChar left, Il2CppChar right)
  59. {
  60. return VmStringUtils::Utf16ToLower(left) == VmStringUtils::Utf16ToLower(right);
  61. }
  62. bool VmStringUtils::CaseInsensitiveComparer::operator()(const std::string& left, const std::string& right) const
  63. {
  64. return operator()(left.c_str(), right.c_str());
  65. }
  66. bool VmStringUtils::CaseInsensitiveComparer::operator()(const std::string& left, const char* right) const
  67. {
  68. return operator()(left.c_str(), right);
  69. }
  70. bool VmStringUtils::CaseInsensitiveComparer::operator()(const char* left, const std::string& right) const
  71. {
  72. return operator()(left, right.c_str());
  73. }
  74. bool VmStringUtils::CaseInsensitiveComparer::operator()(const char* left, const char* right) const
  75. {
  76. #if IL2CPP_DEBUG // Invalid UTF8 strings shouldn't be passed here, so let's assert in debug mode
  77. IL2CPP_ASSERT(utf8::is_valid(left, left + strlen(left)));
  78. IL2CPP_ASSERT(utf8::is_valid(right, right + strlen(right)));
  79. #endif
  80. Il2CppChar utf16Left[2];
  81. Il2CppChar utf16Right[2];
  82. while (*left && *right)
  83. {
  84. Utf32CharToSurrogatePair(utf8::unchecked::next(left), utf16Left);
  85. Utf32CharToSurrogatePair(utf8::unchecked::next(right), utf16Right);
  86. if (!Utf16CharEqualsIgnoreCase(utf16Left[0], utf16Right[0]) ||
  87. !Utf16CharEqualsIgnoreCase(utf16Left[1], utf16Right[1]))
  88. {
  89. return false;
  90. }
  91. }
  92. return *left == '\0' && *right == '\0';
  93. }
  94. bool VmStringUtils::CaseSensitiveEquals(Il2CppString* left, const char* right)
  95. {
  96. std::string leftString = StringUtils::Utf16ToUtf8(left->chars);
  97. functional::Filter<const char*, CaseSensitiveComparer> equalsLeft(leftString.c_str());
  98. return equalsLeft(right);
  99. }
  100. bool VmStringUtils::CaseSensitiveEquals(const char* left, const char* right)
  101. {
  102. functional::Filter<const char*, CaseSensitiveComparer> equalsLeft(left);
  103. return equalsLeft(right);
  104. }
  105. bool VmStringUtils::CaseInsensitiveEquals(Il2CppString* left, const char* right)
  106. {
  107. std::string leftString = StringUtils::Utf16ToUtf8(left->chars);
  108. functional::Filter<const char*, CaseInsensitiveComparer> equalsLeft(leftString.c_str());
  109. return equalsLeft(right);
  110. }
  111. bool VmStringUtils::CaseInsensitiveEquals(const char* left, const char* right)
  112. {
  113. functional::Filter<const char *, CaseInsensitiveComparer> equalsLeft(left);
  114. return equalsLeft(right);
  115. }
  116. }
  117. }
  118. #endif