StringUtils.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // The MIT License (MIT)
  2. //
  3. // Copyright(c) Unity Technologies, Microsoft Corporation
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files(the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions :
  11. //
  12. // The above copyright notice and this permission notice shall be included in all
  13. // copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. // SOFTWARE.
  22. #pragma once
  23. #include "il2cpp-string-types.h"
  24. #include <string>
  25. #include <vector>
  26. #include <limits>
  27. #include <stdint.h>
  28. #include "il2cpp-config.h"
  29. #include "StringView.h"
  30. #include "StringViewUtils.h"
  31. namespace il2cpp
  32. {
  33. namespace utils
  34. {
  35. class LIBIL2CPP_CODEGEN_API StringUtils
  36. {
  37. public:
  38. static std::string Printf(const char* format, ...);
  39. static std::string NPrintf(const char* format, size_t max_n, ...);
  40. static std::string Utf16ToUtf8(const Il2CppChar* utf16String);
  41. static std::string Utf16ToUtf8(const Il2CppChar* utf16String, int maximumSize);
  42. static std::string Utf16ToUtf8(const UTF16String& utf16String);
  43. static UTF16String Utf8ToUtf16(const char* utf8String);
  44. static UTF16String Utf8ToUtf16(const char* utf8String, size_t length);
  45. static UTF16String Utf8ToUtf16(const std::string& utf8String);
  46. static char* StringDuplicate(const char *strSource);
  47. static Il2CppChar* StringDuplicate(const Il2CppChar* strSource, size_t length);
  48. static bool EndsWith(const std::string& string, const std::string& suffix);
  49. static Il2CppChar* GetChars(Il2CppString* str);
  50. static int32_t GetLength(Il2CppString* str);
  51. #if IL2CPP_TARGET_WINDOWS
  52. static inline std::string NativeStringToUtf8(const Il2CppNativeString& nativeStr)
  53. {
  54. IL2CPP_ASSERT(nativeStr.length() < static_cast<size_t>(std::numeric_limits<int>::max()));
  55. return Utf16ToUtf8(nativeStr.c_str(), static_cast<int>(nativeStr.length()));
  56. }
  57. static inline std::string NativeStringToUtf8(const Il2CppNativeChar* nativeStr)
  58. {
  59. return Utf16ToUtf8(nativeStr);
  60. }
  61. static inline std::string NativeStringToUtf8(const Il2CppNativeChar* nativeStr, uint32_t length)
  62. {
  63. IL2CPP_ASSERT(length < static_cast<uint32_t>(std::numeric_limits<int>::max()));
  64. return Utf16ToUtf8(nativeStr, static_cast<int>(length));
  65. }
  66. static inline Il2CppNativeString Utf8ToNativeString(const std::string& str)
  67. {
  68. IL2CPP_ASSERT(str.length() < static_cast<size_t>(std::numeric_limits<int>::max()));
  69. return Utf8ToUtf16(str.c_str(), str.length());
  70. }
  71. static inline Il2CppNativeString Utf8ToNativeString(const char* str)
  72. {
  73. return Utf8ToUtf16(str);
  74. }
  75. #else
  76. static inline std::string NativeStringToUtf8(Il2CppNativeString& nativeStr)
  77. {
  78. return nativeStr;
  79. }
  80. static inline std::string NativeStringToUtf8(const Il2CppNativeChar* nativeStr)
  81. {
  82. return nativeStr;
  83. }
  84. static inline std::string NativeStringToUtf8(const Il2CppNativeChar* nativeStr, uint32_t length)
  85. {
  86. return std::string(nativeStr, length);
  87. }
  88. static inline Il2CppNativeString Utf8ToNativeString(const std::string& str)
  89. {
  90. return str;
  91. }
  92. static inline Il2CppNativeString Utf8ToNativeString(const char* str)
  93. {
  94. return str;
  95. }
  96. #endif
  97. template<typename CharType, size_t N>
  98. static inline size_t LiteralLength(const CharType(&str)[N])
  99. {
  100. return N - 1;
  101. }
  102. template<typename CharType>
  103. static size_t StrLen(const CharType* str)
  104. {
  105. size_t length = 0;
  106. while (*str)
  107. {
  108. str++;
  109. length++;
  110. }
  111. return length;
  112. }
  113. template <typename CharType>
  114. static inline bool Equals(const StringView<CharType>& left, const StringView<CharType>& right)
  115. {
  116. if (left.Length() != right.Length())
  117. return false;
  118. return memcmp(left.Str(), right.Str(), left.Length() * sizeof(CharType)) == 0;
  119. }
  120. template <typename CharType, size_t rightLength>
  121. static inline bool Equals(const StringView<CharType>& left, const CharType (&right)[rightLength])
  122. {
  123. if (left.Length() != rightLength - 1)
  124. return false;
  125. return memcmp(left.Str(), right, (rightLength - 1) * sizeof(CharType)) == 0;
  126. }
  127. template <typename CharType>
  128. static inline bool StartsWith(const StringView<CharType>& left, const StringView<CharType>& right)
  129. {
  130. if (left.Length() < right.Length())
  131. return false;
  132. return memcmp(left.Str(), right.Str(), right.Length() * sizeof(CharType)) == 0;
  133. }
  134. template <typename CharType, size_t rightLength>
  135. static inline bool StartsWith(const StringView<CharType>& left, const CharType(&right)[rightLength])
  136. {
  137. if (left.Length() < rightLength - 1)
  138. return false;
  139. return memcmp(left.Str(), right, (rightLength - 1) * sizeof(CharType)) == 0;
  140. }
  141. // Taken from github.com/Microsoft/referencesource/blob/master/mscorlib/system/string.cs
  142. template<typename CharType>
  143. static inline size_t Hash(const CharType *str, size_t length)
  144. {
  145. IL2CPP_ASSERT(length <= static_cast<size_t>(std::numeric_limits<int>::max()));
  146. size_t hash1 = 5381;
  147. size_t hash2 = hash1;
  148. size_t i = 0;
  149. CharType c;
  150. const CharType* s = str;
  151. while (true)
  152. {
  153. if (i++ >= length)
  154. break;
  155. c = s[0];
  156. hash1 = ((hash1 << 5) + hash1) ^ c;
  157. if (i++ >= length)
  158. break;
  159. c = s[1];
  160. hash2 = ((hash2 << 5) + hash2) ^ c;
  161. s += 2;
  162. }
  163. return hash1 + (hash2 * 1566083941);
  164. }
  165. template<typename CharType>
  166. static inline size_t Hash(const CharType *str)
  167. {
  168. size_t hash1 = 5381;
  169. size_t hash2 = hash1;
  170. CharType c;
  171. const CharType* s = str;
  172. while ((c = s[0]) != 0)
  173. {
  174. hash1 = ((hash1 << 5) + hash1) ^ c;
  175. c = s[1];
  176. if (c == 0)
  177. break;
  178. hash2 = ((hash2 << 5) + hash2) ^ c;
  179. s += 2;
  180. }
  181. return hash1 + (hash2 * 1566083941);
  182. }
  183. template<typename StringType>
  184. struct StringHasher
  185. {
  186. typedef typename StringType::value_type CharType;
  187. size_t operator()(const StringType& value) const
  188. {
  189. return Hash(value.c_str(), value.length());
  190. }
  191. };
  192. template<typename CharType>
  193. struct StringHasher<const CharType*>
  194. {
  195. size_t operator()(const CharType* value) const
  196. {
  197. return Hash(value);
  198. }
  199. };
  200. };
  201. } /* utils */
  202. } /* il2cpp */
  203. // Assumes str is not NULL
  204. #if defined(_MSC_VER)
  205. #define DECLARE_IL2CPP_STRING_AS_STRING_VIEW_OF_NATIVE_CHARS(variableName, str) \
  206. il2cpp::utils::StringView<Il2CppNativeChar> variableName(reinterpret_cast<Il2CppString*>(str)->chars, reinterpret_cast<Il2CppString*>(str)->length);
  207. #define DECLARE_IL2CPP_CHAR_PTR_AS_STRING_VIEW_OF_NATIVE_CHARS(variableName, str) \
  208. il2cpp::utils::StringView<Il2CppNativeChar> variableName(str, il2cpp::utils::StringUtils::StrLen (str));
  209. #define DECLARE_NATIVE_C_STRING_AS_STRING_VIEW_OF_IL2CPP_CHARS(variableName, str) \
  210. il2cpp::utils::StringView<Il2CppChar> variableName(str, wcslen(str));
  211. #define DECLARE_NATIVE_STRING_AS_STRING_VIEW_OF_IL2CPP_CHARS(variableName, str) \
  212. il2cpp::utils::StringView<Il2CppChar> variableName = STRING_TO_STRINGVIEW(str);
  213. #else
  214. #define DECLARE_IL2CPP_STRING_AS_STRING_VIEW_OF_NATIVE_CHARS(variableName, str) \
  215. Il2CppNativeString variableName##_native_string_storage = il2cpp::utils::StringUtils::Utf16ToUtf8(reinterpret_cast<Il2CppString*>(str)->chars, reinterpret_cast<Il2CppString*>(str)->length); \
  216. il2cpp::utils::StringView<Il2CppNativeChar> variableName(variableName##_native_string_storage.c_str(), variableName##_native_string_storage.length());
  217. #define DECLARE_IL2CPP_CHAR_PTR_AS_STRING_VIEW_OF_NATIVE_CHARS(variableName, str) \
  218. Il2CppNativeString variableName##_native_string_storage = il2cpp::utils::StringUtils::Utf16ToUtf8(str, il2cpp::utils::StringUtils::StrLen (str)); \
  219. il2cpp::utils::StringView<Il2CppNativeChar> variableName(variableName##_native_string_storage.c_str(), variableName##_native_string_storage.length());
  220. #define DECLARE_NATIVE_C_STRING_AS_STRING_VIEW_OF_IL2CPP_CHARS(variableName, str) \
  221. UTF16String variableName##_utf16String = il2cpp::utils::StringUtils::Utf8ToUtf16(str); \
  222. il2cpp::utils::StringView<Il2CppChar> variableName = STRING_TO_STRINGVIEW(variableName##_utf16String);
  223. #define DECLARE_NATIVE_STRING_AS_STRING_VIEW_OF_IL2CPP_CHARS DECLARE_NATIVE_C_STRING_AS_STRING_VIEW_OF_IL2CPP_CHARS
  224. #endif