ustring.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. /**************************************************************************/
  2. /* ustring.h */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #pragma once
  31. // Note: _GODOT suffix added to header guard to avoid conflict with ICU header.
  32. #include "core/string/char_utils.h" // IWYU pragma: export
  33. #include "core/templates/cowdata.h"
  34. #include "core/templates/vector.h"
  35. #include "core/typedefs.h"
  36. #include "core/variant/array.h"
  37. class String;
  38. template <typename T>
  39. class CharStringT;
  40. /*************************************************************************/
  41. /* Utility Functions */
  42. /*************************************************************************/
  43. // Not defined by std.
  44. // strlen equivalent function for char16_t * arguments.
  45. constexpr size_t strlen(const char16_t *p_str) {
  46. const char16_t *ptr = p_str;
  47. while (*ptr != 0) {
  48. ++ptr;
  49. }
  50. return ptr - p_str;
  51. }
  52. // strlen equivalent function for char32_t * arguments.
  53. constexpr size_t strlen(const char32_t *p_str) {
  54. const char32_t *ptr = p_str;
  55. while (*ptr != 0) {
  56. ++ptr;
  57. }
  58. return ptr - p_str;
  59. }
  60. // strlen equivalent function for wchar_t * arguments; depends on the platform.
  61. constexpr size_t strlen(const wchar_t *p_str) {
  62. // Use static_cast twice because reinterpret_cast is not allowed in constexpr
  63. #ifdef WINDOWS_ENABLED
  64. // wchar_t is 16-bit
  65. return strlen(static_cast<const char16_t *>(static_cast<const void *>(p_str)));
  66. #else
  67. // wchar_t is 32-bit
  68. return strlen(static_cast<const char32_t *>(static_cast<const void *>(p_str)));
  69. #endif
  70. }
  71. // strnlen equivalent function for char16_t * arguments.
  72. constexpr size_t strnlen(const char16_t *p_str, size_t p_clip_to_len) {
  73. size_t len = 0;
  74. while (len < p_clip_to_len && *(p_str++) != 0) {
  75. len++;
  76. }
  77. return len;
  78. }
  79. // strnlen equivalent function for char32_t * arguments.
  80. constexpr size_t strnlen(const char32_t *p_str, size_t p_clip_to_len) {
  81. size_t len = 0;
  82. while (len < p_clip_to_len && *(p_str++) != 0) {
  83. len++;
  84. }
  85. return len;
  86. }
  87. // strnlen equivalent function for wchar_t * arguments; depends on the platform.
  88. constexpr size_t strnlen(const wchar_t *p_str, size_t p_clip_to_len) {
  89. // Use static_cast twice because reinterpret_cast is not allowed in constexpr
  90. #ifdef WINDOWS_ENABLED
  91. // wchar_t is 16-bit
  92. return strnlen(static_cast<const char16_t *>(static_cast<const void *>(p_str)), p_clip_to_len);
  93. #else
  94. // wchar_t is 32-bit
  95. return strnlen(static_cast<const char32_t *>(static_cast<const void *>(p_str)), p_clip_to_len);
  96. #endif
  97. }
  98. template <typename L, typename R>
  99. constexpr int64_t str_compare(const L *l_ptr, const R *r_ptr) {
  100. while (true) {
  101. const char32_t l = *l_ptr;
  102. const char32_t r = *r_ptr;
  103. if (l == 0 || l != r) {
  104. return static_cast<int64_t>(l) - static_cast<int64_t>(r);
  105. }
  106. l_ptr++;
  107. r_ptr++;
  108. }
  109. }
  110. /*************************************************************************/
  111. /* CharProxy */
  112. /*************************************************************************/
  113. template <typename T>
  114. class [[nodiscard]] CharProxy {
  115. friend String;
  116. friend CharStringT<T>;
  117. const int _index;
  118. CowData<T> &_cowdata;
  119. static constexpr T _null = 0;
  120. _FORCE_INLINE_ CharProxy(const int &p_index, CowData<T> &p_cowdata) :
  121. _index(p_index),
  122. _cowdata(p_cowdata) {}
  123. public:
  124. _FORCE_INLINE_ CharProxy(const CharProxy<T> &p_other) :
  125. _index(p_other._index),
  126. _cowdata(p_other._cowdata) {}
  127. _FORCE_INLINE_ operator T() const {
  128. if (unlikely(_index == _cowdata.size())) {
  129. return _null;
  130. }
  131. return _cowdata.get(_index);
  132. }
  133. _FORCE_INLINE_ const T *operator&() const {
  134. return _cowdata.ptr() + _index;
  135. }
  136. _FORCE_INLINE_ void operator=(const T &p_other) const {
  137. _cowdata.set(_index, p_other);
  138. }
  139. _FORCE_INLINE_ void operator=(const CharProxy<T> &p_other) const {
  140. _cowdata.set(_index, p_other.operator T());
  141. }
  142. };
  143. /*************************************************************************/
  144. /* CharStringT */
  145. /*************************************************************************/
  146. template <typename T>
  147. class [[nodiscard]] CharStringT {
  148. CowData<T> _cowdata;
  149. static constexpr T _null = 0;
  150. public:
  151. _FORCE_INLINE_ T *ptrw() { return _cowdata.ptrw(); }
  152. _FORCE_INLINE_ const T *ptr() const { return _cowdata.ptr(); }
  153. _FORCE_INLINE_ const T *get_data() const { return ptr() ? ptr() : &_null; }
  154. _FORCE_INLINE_ int size() const { return _cowdata.size(); }
  155. _FORCE_INLINE_ int length() const { return ptr() ? size() - 1 : 0; }
  156. _FORCE_INLINE_ bool is_empty() const { return length() == 0; }
  157. _FORCE_INLINE_ operator Span<T>() const { return Span(ptr(), length()); }
  158. _FORCE_INLINE_ Span<T> span() const { return Span(ptr(), length()); }
  159. _FORCE_INLINE_ Error resize(int p_size) { return _cowdata.template resize<false>(p_size); }
  160. _FORCE_INLINE_ T get(int p_index) const { return _cowdata.get(p_index); }
  161. _FORCE_INLINE_ void set(int p_index, const T &p_elem) { _cowdata.set(p_index, p_elem); }
  162. _FORCE_INLINE_ const T &operator[](int p_index) const {
  163. if (unlikely(p_index == _cowdata.size())) {
  164. return _null;
  165. }
  166. return _cowdata.get(p_index);
  167. }
  168. _FORCE_INLINE_ CharProxy<T> operator[](int p_index) { return CharProxy<T>(p_index, _cowdata); }
  169. _FORCE_INLINE_ CharStringT() = default;
  170. _FORCE_INLINE_ CharStringT(const CharStringT &p_str) = default;
  171. _FORCE_INLINE_ CharStringT(CharStringT &&p_str) = default;
  172. _FORCE_INLINE_ void operator=(const CharStringT &p_str) { _cowdata = p_str._cowdata; }
  173. _FORCE_INLINE_ void operator=(CharStringT &&p_str) { _cowdata = std::move(p_str._cowdata); }
  174. _FORCE_INLINE_ CharStringT(const T *p_cstr) { copy_from(p_cstr); }
  175. _FORCE_INLINE_ void operator=(const T *p_cstr) { copy_from(p_cstr); }
  176. _FORCE_INLINE_ bool operator==(const CharStringT<T> &p_other) const {
  177. if (length() != p_other.length()) {
  178. return false;
  179. }
  180. return memcmp(ptr(), p_other.ptr(), length() * sizeof(T)) == 0;
  181. }
  182. _FORCE_INLINE_ bool operator!=(const CharStringT<T> &p_other) const { return !(*this == p_other); }
  183. _FORCE_INLINE_ bool operator<(const CharStringT<T> &p_other) const {
  184. if (length() == 0) {
  185. return p_other.length() != 0;
  186. }
  187. return str_compare(get_data(), p_other.get_data()) < 0;
  188. }
  189. _FORCE_INLINE_ CharStringT<T> &operator+=(T p_char) {
  190. const int lhs_len = length();
  191. resize(lhs_len + 2);
  192. T *dst = ptrw();
  193. dst[lhs_len] = p_char;
  194. dst[lhs_len + 1] = _null;
  195. return *this;
  196. }
  197. protected:
  198. void copy_from(const T *p_cstr) {
  199. if (!p_cstr) {
  200. resize(0);
  201. return;
  202. }
  203. size_t len = strlen(p_cstr);
  204. if (len == 0) {
  205. resize(0);
  206. return;
  207. }
  208. Error err = resize(++len); // include terminating null char.
  209. ERR_FAIL_COND_MSG(err != OK, "Failed to copy C-string.");
  210. memcpy(ptrw(), p_cstr, len * sizeof(T));
  211. }
  212. };
  213. template <typename T>
  214. struct is_zero_constructible<CharStringT<T>> : std::true_type {};
  215. using CharString = CharStringT<char>;
  216. using Char16String = CharStringT<char16_t>;
  217. /*************************************************************************/
  218. /* String */
  219. /*************************************************************************/
  220. class [[nodiscard]] String {
  221. CowData<char32_t> _cowdata;
  222. static constexpr char32_t _null = 0;
  223. static constexpr char32_t _replacement_char = 0xfffd;
  224. // Known-length copy.
  225. void copy_from_unchecked(const char32_t *p_char, int p_length);
  226. // NULL-terminated c string copy - automatically parse the string to find the length.
  227. void append_latin1(const char *p_cstr) {
  228. append_latin1(Span(p_cstr, p_cstr ? strlen(p_cstr) : 0));
  229. }
  230. void append_utf32(const char32_t *p_cstr) {
  231. append_utf32(Span(p_cstr, p_cstr ? strlen(p_cstr) : 0));
  232. }
  233. // wchar_t copy_from depends on the platform.
  234. void append_wstring(const Span<wchar_t> &p_cstr) {
  235. #ifdef WINDOWS_ENABLED
  236. // wchar_t is 16-bit, parse as UTF-16
  237. append_utf16((const char16_t *)p_cstr.ptr(), p_cstr.size());
  238. #else
  239. // wchar_t is 32-bit, copy directly
  240. append_utf32((Span<char32_t> &)p_cstr);
  241. #endif
  242. }
  243. void append_wstring(const wchar_t *p_cstr) {
  244. #ifdef WINDOWS_ENABLED
  245. // wchar_t is 16-bit, parse as UTF-16
  246. append_utf16((const char16_t *)p_cstr);
  247. #else
  248. // wchar_t is 32-bit, copy directly
  249. append_utf32((const char32_t *)p_cstr);
  250. #endif
  251. }
  252. bool _base_is_subsequence_of(const String &p_string, bool case_insensitive) const;
  253. int _count(const String &p_string, int p_from, int p_to, bool p_case_insensitive) const;
  254. int _count(const char *p_string, int p_from, int p_to, bool p_case_insensitive) const;
  255. String _separate_compound_words() const;
  256. public:
  257. enum {
  258. npos = -1 ///<for "some" compatibility with std::string (npos is a huge value in std::string)
  259. };
  260. _FORCE_INLINE_ char32_t *ptrw() { return _cowdata.ptrw(); }
  261. _FORCE_INLINE_ const char32_t *ptr() const { return _cowdata.ptr(); }
  262. _FORCE_INLINE_ const char32_t *get_data() const { return ptr() ? ptr() : &_null; }
  263. _FORCE_INLINE_ int size() const { return _cowdata.size(); }
  264. _FORCE_INLINE_ int length() const { return ptr() ? size() - 1 : 0; }
  265. _FORCE_INLINE_ bool is_empty() const { return length() == 0; }
  266. _FORCE_INLINE_ operator Span<char32_t>() const { return Span(ptr(), length()); }
  267. _FORCE_INLINE_ Span<char32_t> span() const { return Span(ptr(), length()); }
  268. void remove_at(int p_index) { _cowdata.remove_at(p_index); }
  269. _FORCE_INLINE_ void clear() { resize(0); }
  270. _FORCE_INLINE_ char32_t get(int p_index) const { return _cowdata.get(p_index); }
  271. _FORCE_INLINE_ void set(int p_index, const char32_t &p_elem) { _cowdata.set(p_index, p_elem); }
  272. Error resize(int p_size) { return _cowdata.resize<false>(p_size); }
  273. _FORCE_INLINE_ const char32_t &operator[](int p_index) const {
  274. if (unlikely(p_index == _cowdata.size())) {
  275. return _null;
  276. }
  277. return _cowdata.get(p_index);
  278. }
  279. _FORCE_INLINE_ CharProxy<char32_t> operator[](int p_index) { return CharProxy<char32_t>(p_index, _cowdata); }
  280. /* Compatibility Operators */
  281. bool operator==(const String &p_str) const;
  282. bool operator!=(const String &p_str) const;
  283. String operator+(const String &p_str) const;
  284. String operator+(const char *p_char) const;
  285. String operator+(const wchar_t *p_char) const;
  286. String operator+(const char32_t *p_char) const;
  287. String operator+(char32_t p_char) const;
  288. String &operator+=(const String &);
  289. String &operator+=(char32_t p_char);
  290. String &operator+=(const char *p_str);
  291. String &operator+=(const wchar_t *p_str);
  292. String &operator+=(const char32_t *p_str);
  293. bool operator==(const char *p_str) const;
  294. bool operator==(const wchar_t *p_str) const;
  295. bool operator==(const char32_t *p_str) const;
  296. bool operator==(const Span<char32_t> &p_str_range) const;
  297. bool operator!=(const char *p_str) const;
  298. bool operator!=(const wchar_t *p_str) const;
  299. bool operator!=(const char32_t *p_str) const;
  300. bool operator<(const char32_t *p_str) const;
  301. bool operator<(const char *p_str) const;
  302. bool operator<(const wchar_t *p_str) const;
  303. bool operator<(const String &p_str) const;
  304. bool operator<=(const String &p_str) const;
  305. bool operator>(const String &p_str) const;
  306. bool operator>=(const String &p_str) const;
  307. signed char casecmp_to(const String &p_str) const;
  308. signed char nocasecmp_to(const String &p_str) const;
  309. signed char naturalcasecmp_to(const String &p_str) const;
  310. signed char naturalnocasecmp_to(const String &p_str) const;
  311. // Special sorting for file names. Names starting with `_` are put before all others except those starting with `.`, otherwise natural comparison is used.
  312. signed char filecasecmp_to(const String &p_str) const;
  313. signed char filenocasecmp_to(const String &p_str) const;
  314. bool is_valid_string() const;
  315. /* debug, error messages */
  316. void print_unicode_error(const String &p_message, bool p_critical = false) const;
  317. /* complex helpers */
  318. String substr(int p_from, int p_chars = -1) const;
  319. int find(const String &p_str, int p_from = 0) const; ///< return <0 if failed
  320. int find(const char *p_str, int p_from = 0) const; ///< return <0 if failed
  321. int find_char(char32_t p_char, int p_from = 0) const; ///< return <0 if failed
  322. int findn(const String &p_str, int p_from = 0) const; ///< return <0 if failed, case insensitive
  323. int findn(const char *p_str, int p_from = 0) const; ///< return <0 if failed
  324. int rfind(const String &p_str, int p_from = -1) const; ///< return <0 if failed
  325. int rfind(const char *p_str, int p_from = -1) const; ///< return <0 if failed
  326. int rfind_char(char32_t p_char, int p_from = -1) const; ///< return <0 if failed
  327. int rfindn(const String &p_str, int p_from = -1) const; ///< return <0 if failed, case insensitive
  328. int rfindn(const char *p_str, int p_from = -1) const; ///< return <0 if failed
  329. int findmk(const Vector<String> &p_keys, int p_from = 0, int *r_key = nullptr) const; ///< return <0 if failed
  330. bool match(const String &p_wildcard) const;
  331. bool matchn(const String &p_wildcard) const;
  332. bool begins_with(const String &p_string) const;
  333. bool begins_with(const char *p_string) const;
  334. bool ends_with(const String &p_string) const;
  335. bool ends_with(const char *p_string) const;
  336. bool is_enclosed_in(const String &p_string) const;
  337. bool is_subsequence_of(const String &p_string) const;
  338. bool is_subsequence_ofn(const String &p_string) const;
  339. bool is_quoted() const;
  340. bool is_lowercase() const;
  341. Vector<String> bigrams() const;
  342. float similarity(const String &p_string) const;
  343. String format(const Variant &values, const String &placeholder = "{_}") const;
  344. String replace_first(const String &p_key, const String &p_with) const;
  345. String replace_first(const char *p_key, const char *p_with) const;
  346. String replace(const String &p_key, const String &p_with) const;
  347. String replace(const char *p_key, const char *p_with) const;
  348. String replace_char(char32_t p_key, char32_t p_with) const;
  349. String replace_chars(const String &p_keys, char32_t p_with) const;
  350. String replace_chars(const char *p_keys, char32_t p_with) const;
  351. String replacen(const String &p_key, const String &p_with) const;
  352. String replacen(const char *p_key, const char *p_with) const;
  353. String repeat(int p_count) const;
  354. String reverse() const;
  355. String insert(int p_at_pos, const String &p_string) const;
  356. String erase(int p_pos, int p_chars = 1) const;
  357. String remove_char(char32_t p_what) const;
  358. String remove_chars(const String &p_chars) const;
  359. String remove_chars(const char *p_chars) const;
  360. String pad_decimals(int p_digits) const;
  361. String pad_zeros(int p_digits) const;
  362. String trim_prefix(const String &p_prefix) const;
  363. String trim_prefix(const char *p_prefix) const;
  364. String trim_suffix(const String &p_suffix) const;
  365. String trim_suffix(const char *p_suffix) const;
  366. String lpad(int min_length, const String &character = " ") const;
  367. String rpad(int min_length, const String &character = " ") const;
  368. String sprintf(const Array &values, bool *error) const;
  369. String quote(const String &quotechar = "\"") const;
  370. String unquote() const;
  371. static String num(double p_num, int p_decimals = -1);
  372. static String num_scientific(double p_num);
  373. static String num_scientific(float p_num);
  374. static String num_real(double p_num, bool p_trailing = true);
  375. static String num_real(float p_num, bool p_trailing = true);
  376. static String num_int64(int64_t p_num, int base = 10, bool capitalize_hex = false);
  377. static String num_uint64(uint64_t p_num, int base = 10, bool capitalize_hex = false);
  378. static String chr(char32_t p_char) {
  379. String string;
  380. string.append_utf32(Span(&p_char, 1));
  381. return string;
  382. }
  383. static String md5(const uint8_t *p_md5);
  384. static String hex_encode_buffer(const uint8_t *p_buffer, int p_len);
  385. Vector<uint8_t> hex_decode() const;
  386. bool is_numeric() const;
  387. double to_float() const;
  388. int64_t hex_to_int() const;
  389. int64_t bin_to_int() const;
  390. int64_t to_int() const;
  391. static int64_t to_int(const char *p_str, int p_len = -1);
  392. static int64_t to_int(const wchar_t *p_str, int p_len = -1);
  393. static int64_t to_int(const char32_t *p_str, int p_len = -1, bool p_clamp = false);
  394. static double to_float(const char *p_str);
  395. static double to_float(const wchar_t *p_str, const wchar_t **r_end = nullptr);
  396. static double to_float(const char32_t *p_str, const char32_t **r_end = nullptr);
  397. static uint32_t num_characters(int64_t p_int);
  398. String capitalize() const;
  399. String to_camel_case() const;
  400. String to_pascal_case() const;
  401. String to_snake_case() const;
  402. String to_kebab_case() const;
  403. String get_with_code_lines() const;
  404. int get_slice_count(const String &p_splitter) const;
  405. int get_slice_count(const char *p_splitter) const;
  406. String get_slice(const String &p_splitter, int p_slice) const;
  407. String get_slice(const char *p_splitter, int p_slice) const;
  408. String get_slicec(char32_t p_splitter, int p_slice) const;
  409. Vector<String> split(const String &p_splitter = "", bool p_allow_empty = true, int p_maxsplit = 0) const;
  410. Vector<String> split(const char *p_splitter = "", bool p_allow_empty = true, int p_maxsplit = 0) const;
  411. Vector<String> rsplit(const String &p_splitter = "", bool p_allow_empty = true, int p_maxsplit = 0) const;
  412. Vector<String> rsplit(const char *p_splitter = "", bool p_allow_empty = true, int p_maxsplit = 0) const;
  413. Vector<String> split_spaces(int p_maxsplit = 0) const;
  414. Vector<double> split_floats(const String &p_splitter, bool p_allow_empty = true) const;
  415. Vector<float> split_floats_mk(const Vector<String> &p_splitters, bool p_allow_empty = true) const;
  416. Vector<int> split_ints(const String &p_splitter, bool p_allow_empty = true) const;
  417. Vector<int> split_ints_mk(const Vector<String> &p_splitters, bool p_allow_empty = true) const;
  418. String join(const Vector<String> &parts) const;
  419. static char32_t char_uppercase(char32_t p_char);
  420. static char32_t char_lowercase(char32_t p_char);
  421. String to_upper() const;
  422. String to_lower() const;
  423. int count(const String &p_string, int p_from = 0, int p_to = 0) const;
  424. int count(const char *p_string, int p_from = 0, int p_to = 0) const;
  425. int countn(const String &p_string, int p_from = 0, int p_to = 0) const;
  426. int countn(const char *p_string, int p_from = 0, int p_to = 0) const;
  427. String left(int p_len) const;
  428. String right(int p_len) const;
  429. String indent(const String &p_prefix) const;
  430. String dedent() const;
  431. String strip_edges(bool left = true, bool right = true) const;
  432. String strip_escapes() const;
  433. String lstrip(const String &p_chars) const;
  434. String rstrip(const String &p_chars) const;
  435. String get_extension() const;
  436. String get_basename() const;
  437. String path_join(const String &p_path) const;
  438. char32_t unicode_at(int p_idx) const;
  439. CharString ascii(bool p_allow_extended = false) const;
  440. // Parse an ascii string.
  441. // If any character is > 127, an error will be logged, and 0xfffd will be inserted.
  442. Error append_ascii(const Span<char> &p_range);
  443. static String ascii(const Span<char> &p_range) {
  444. String s;
  445. s.append_ascii(p_range);
  446. return s;
  447. }
  448. CharString latin1() const { return ascii(true); }
  449. void append_latin1(const Span<char> &p_cstr);
  450. static String latin1(const Span<char> &p_string) {
  451. String string;
  452. string.append_latin1(p_string);
  453. return string;
  454. }
  455. CharString utf8(Vector<uint8_t> *r_ch_length_map = nullptr) const;
  456. Error append_utf8(const char *p_utf8, int p_len = -1, bool p_skip_cr = false);
  457. Error append_utf8(const Span<char> &p_range, bool p_skip_cr = false) {
  458. return append_utf8(p_range.ptr(), p_range.size(), p_skip_cr);
  459. }
  460. static String utf8(const char *p_utf8, int p_len = -1) {
  461. String ret;
  462. ret.append_utf8(p_utf8, p_len);
  463. return ret;
  464. }
  465. static String utf8(const Span<char> &p_range) { return utf8(p_range.ptr(), p_range.size()); }
  466. Char16String utf16() const;
  467. Error append_utf16(const char16_t *p_utf16, int p_len = -1, bool p_default_little_endian = true);
  468. Error append_utf16(const Span<char16_t> p_range, bool p_skip_cr = false) {
  469. return append_utf16(p_range.ptr(), p_range.size(), p_skip_cr);
  470. }
  471. static String utf16(const char16_t *p_utf16, int p_len = -1) {
  472. String ret;
  473. ret.append_utf16(p_utf16, p_len);
  474. return ret;
  475. }
  476. static String utf16(const Span<char16_t> &p_range) { return utf16(p_range.ptr(), p_range.size()); }
  477. void append_utf32(const Span<char32_t> &p_cstr);
  478. static String utf32(const Span<char32_t> &p_span) {
  479. String string;
  480. string.append_utf32(p_span);
  481. return string;
  482. }
  483. static uint32_t hash(const char32_t *p_cstr, int p_len); /* hash the string */
  484. static uint32_t hash(const char32_t *p_cstr); /* hash the string */
  485. static uint32_t hash(const wchar_t *p_cstr, int p_len); /* hash the string */
  486. static uint32_t hash(const wchar_t *p_cstr); /* hash the string */
  487. static uint32_t hash(const char *p_cstr, int p_len); /* hash the string */
  488. static uint32_t hash(const char *p_cstr); /* hash the string */
  489. uint32_t hash() const; /* hash the string */
  490. uint64_t hash64() const; /* hash the string */
  491. String md5_text() const;
  492. String sha1_text() const;
  493. String sha256_text() const;
  494. Vector<uint8_t> md5_buffer() const;
  495. Vector<uint8_t> sha1_buffer() const;
  496. Vector<uint8_t> sha256_buffer() const;
  497. _FORCE_INLINE_ bool contains(const char *p_str) const { return find(p_str) != -1; }
  498. _FORCE_INLINE_ bool contains(const String &p_str) const { return find(p_str) != -1; }
  499. _FORCE_INLINE_ bool contains_char(char32_t p_chr) const { return find_char(p_chr) != -1; }
  500. _FORCE_INLINE_ bool containsn(const char *p_str) const { return findn(p_str) != -1; }
  501. _FORCE_INLINE_ bool containsn(const String &p_str) const { return findn(p_str) != -1; }
  502. // path functions
  503. bool is_absolute_path() const;
  504. bool is_relative_path() const;
  505. bool is_resource_file() const;
  506. String path_to(const String &p_path) const;
  507. String path_to_file(const String &p_path) const;
  508. String get_base_dir() const;
  509. String get_file() const;
  510. static String humanize_size(uint64_t p_size);
  511. String simplify_path() const;
  512. bool is_network_share_path() const;
  513. String xml_escape(bool p_escape_quotes = false) const;
  514. String xml_unescape() const;
  515. String uri_encode() const;
  516. String uri_decode() const;
  517. String uri_file_decode() const;
  518. String c_escape() const;
  519. String c_escape_multiline() const;
  520. String c_unescape() const;
  521. String json_escape() const;
  522. Error parse_url(String &r_scheme, String &r_host, int &r_port, String &r_path, String &r_fragment) const;
  523. String property_name_encode() const;
  524. // node functions
  525. static String get_invalid_node_name_characters(bool p_allow_internal = false);
  526. String validate_node_name() const;
  527. String validate_ascii_identifier() const;
  528. String validate_unicode_identifier() const;
  529. String validate_filename() const;
  530. bool is_valid_ascii_identifier() const;
  531. bool is_valid_unicode_identifier() const;
  532. bool is_valid_int() const;
  533. bool is_valid_float() const;
  534. bool is_valid_hex_number(bool p_with_prefix) const;
  535. bool is_valid_html_color() const;
  536. bool is_valid_ip_address() const;
  537. bool is_valid_filename() const;
  538. // Use `is_valid_ascii_identifier()` instead. Kept for compatibility.
  539. bool is_valid_identifier() const { return is_valid_ascii_identifier(); }
  540. /**
  541. * The constructors must not depend on other overloads
  542. */
  543. _FORCE_INLINE_ String() {}
  544. _FORCE_INLINE_ String(const String &p_str) = default;
  545. _FORCE_INLINE_ String(String &&p_str) = default;
  546. #ifdef SIZE_EXTRA
  547. _NO_INLINE_ ~String() {}
  548. #endif
  549. _FORCE_INLINE_ void operator=(const String &p_str) { _cowdata = p_str._cowdata; }
  550. _FORCE_INLINE_ void operator=(String &&p_str) { _cowdata = std::move(p_str._cowdata); }
  551. Vector<uint8_t> to_ascii_buffer() const;
  552. Vector<uint8_t> to_utf8_buffer() const;
  553. Vector<uint8_t> to_utf16_buffer() const;
  554. Vector<uint8_t> to_utf32_buffer() const;
  555. Vector<uint8_t> to_wchar_buffer() const;
  556. Vector<uint8_t> to_multibyte_char_buffer(const String &p_encoding = String()) const;
  557. // Constructors for NULL terminated C strings.
  558. String(const char *p_cstr) {
  559. append_latin1(p_cstr);
  560. }
  561. String(const wchar_t *p_cstr) {
  562. append_wstring(p_cstr);
  563. }
  564. String(const char32_t *p_cstr) {
  565. append_utf32(p_cstr);
  566. }
  567. // Copy assignment for NULL terminated C strings.
  568. void operator=(const char *p_cstr) {
  569. clear();
  570. append_latin1(p_cstr);
  571. }
  572. void operator=(const wchar_t *p_cstr) {
  573. clear();
  574. append_wstring(p_cstr);
  575. }
  576. void operator=(const char32_t *p_cstr) {
  577. clear();
  578. append_utf32(p_cstr);
  579. }
  580. };
  581. // Zero-constructing String initializes _cowdata.ptr() to nullptr and thus empty.
  582. template <>
  583. struct is_zero_constructible<String> : std::true_type {};
  584. bool operator==(const char *p_chr, const String &p_str);
  585. bool operator==(const wchar_t *p_chr, const String &p_str);
  586. bool operator!=(const char *p_chr, const String &p_str);
  587. bool operator!=(const wchar_t *p_chr, const String &p_str);
  588. String operator+(const char *p_chr, const String &p_str);
  589. String operator+(const wchar_t *p_chr, const String &p_str);
  590. String operator+(char32_t p_chr, const String &p_str);
  591. String itos(int64_t p_val);
  592. String uitos(uint64_t p_val);
  593. String rtos(double p_val);
  594. String rtoss(double p_val); //scientific version
  595. struct NoCaseComparator {
  596. bool operator()(const String &p_a, const String &p_b) const {
  597. return p_a.nocasecmp_to(p_b) < 0;
  598. }
  599. };
  600. struct NaturalNoCaseComparator {
  601. bool operator()(const String &p_a, const String &p_b) const {
  602. return p_a.naturalnocasecmp_to(p_b) < 0;
  603. }
  604. };
  605. struct FileNoCaseComparator {
  606. bool operator()(const String &p_a, const String &p_b) const {
  607. return p_a.filenocasecmp_to(p_b) < 0;
  608. }
  609. };
  610. /* end of namespace */
  611. // Tool translate (TTR and variants) for the editor UI,
  612. // and doc translate for the class reference (DTR).
  613. #ifdef TOOLS_ENABLED
  614. // Gets parsed.
  615. String TTR(const String &p_text, const String &p_context = "");
  616. String TTRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context = "");
  617. String DTR(const String &p_text, const String &p_context = "");
  618. String DTRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context = "");
  619. // Use for C strings.
  620. #define TTRC(m_value) (m_value)
  621. // Use to avoid parsing (for use later with C strings).
  622. #define TTRGET(m_value) TTR(m_value)
  623. #else
  624. #define TTRC(m_value) (m_value)
  625. #define TTRGET(m_value) (m_value)
  626. #endif
  627. // Use this to mark property names for editor translation.
  628. // Often for dynamic properties defined in _get_property_list().
  629. // Property names defined directly inside EDITOR_DEF, GLOBAL_DEF, and ADD_PROPERTY macros don't need this.
  630. #define PNAME(m_value) (m_value)
  631. // Similar to PNAME, but to mark groups, i.e. properties with PROPERTY_USAGE_GROUP.
  632. // Groups defined directly inside ADD_GROUP macros don't need this.
  633. // The arguments are the same as ADD_GROUP. m_prefix is only used for extraction.
  634. #define GNAME(m_value, m_prefix) (m_value)
  635. // Runtime translate for the public node API.
  636. String RTR(const String &p_text, const String &p_context = "");
  637. String RTRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context = "");
  638. /**
  639. * "Extractable TRanslate". Used for strings that can appear inside an exported
  640. * project (such as the ones in nodes like `FileDialog`), which are made possible
  641. * to add in the POT generator. A translation context can optionally be specified
  642. * to disambiguate between identical source strings in translations.
  643. * When placeholders are desired, use vformat(ETR("Example: %s"), some_string)`.
  644. * If a string mentions a quantity (and may therefore need a dynamic plural form),
  645. * use `ETRN()` instead of `ETR()`.
  646. *
  647. * NOTE: This function is for string extraction only, and will just return the
  648. * string it was given. The translation itself should be done internally by nodes
  649. * with `atr()` instead.
  650. */
  651. _FORCE_INLINE_ String ETR(const String &p_text, const String &p_context = "") {
  652. return p_text;
  653. }
  654. /**
  655. * "Extractable TRanslate for N items". Used for strings that can appear inside an
  656. * exported project (such as the ones in nodes like `FileDialog`), which are made
  657. * possible to add in the POT generator. A translation context can optionally be
  658. * specified to disambiguate between identical source strings in translations.
  659. * Use `ETR()` if the string doesn't need dynamic plural form. When placeholders
  660. * are desired, use `vformat(ETRN("%d item", "%d items", some_integer), some_integer)`.
  661. * The placeholder must be present in both strings to avoid run-time warnings in `vformat()`.
  662. *
  663. * NOTE: This function is for string extraction only, and will just return the
  664. * string it was given. The translation itself should be done internally by nodes
  665. * with `atr()` instead.
  666. */
  667. _FORCE_INLINE_ String ETRN(const String &p_text, const String &p_text_plural, int p_n, const String &p_context = "") {
  668. if (p_n == 1) {
  669. return p_text;
  670. }
  671. return p_text_plural;
  672. }
  673. bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end);
  674. template <typename... P>
  675. _FORCE_INLINE_ Vector<String> sarray(P... p_args) {
  676. return Vector<String>({ String(p_args)... });
  677. }