No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VmStringUtils.cpp 4.4KB

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