String Functions.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /******************************************************************************
  2. Following functions accept 'CChar*' and 'CChar8*' parameters,
  3. however you can also use 'Str' and 'Str8' parameters
  4. as string classes support auto casting to 'CChar*' and 'CChar8*' respectively.
  5. /******************************************************************************/
  6. inline Bool Is (CChar *t) {return t && t[0];} // if text has any data
  7. inline Bool Is (CChar8 *t) {return t && t[0];} // if text has any data
  8. Int Length (CChar *t); // get text length (number of characters)
  9. Int Length (CChar8 *t); // get text length (number of characters)
  10. Bool HasUnicode(CChar *t); // if text contains unicode characters
  11. Bool HasUnicode(CChar8 *t); // if text contains unicode characters
  12. Bool HasUnicode(C Str &s); // if text contains unicode characters
  13. Bool HasUnicode(C Str8 &s); // if text contains unicode characters
  14. #if EE_PRIVATE
  15. Int SetReturnLength(Char *dest, CChar *src, Int dest_elms); // set text, return written length, 'dest_elms'=maximum available elements in the 'dest' pointer
  16. Int SetReturnLength(Char8 *dest, CChar8 *src, Int dest_elms); // set text, return written length, 'dest_elms'=maximum available elements in the 'dest' pointer
  17. void MergePath(Char *dest, CChar *first, CChar *second, Int dest_elms); // merge paths: dest=first; dest.tailSlash(true); dest+=second;
  18. void MergePath(Char8 *dest, CChar8 *first, CChar8 *second, Int dest_elms); // merge paths: dest=first; dest.tailSlash(true); dest+=second;
  19. #endif
  20. Char * Set (Char *dest, CChar *src, Int dest_elms); // set 'dest' text from 'src' and return 'dest', 'dest_elms'=maximum available elements in the 'dest' pointer
  21. Char * Set (Char *dest, CChar8 *src, Int dest_elms); // set 'dest' text from 'src' and return 'dest', 'dest_elms'=maximum available elements in the 'dest' pointer
  22. Char8* Set (Char8 *dest, CChar *src, Int dest_elms); // set 'dest' text from 'src' and return 'dest', 'dest_elms'=maximum available elements in the 'dest' pointer
  23. Char8* Set (Char8 *dest, CChar8 *src, Int dest_elms); // set 'dest' text from 'src' and return 'dest', 'dest_elms'=maximum available elements in the 'dest' pointer
  24. Char * Append(Char *dest, CChar *src, Int dest_elms); // append 'dest' text from 'src' and return 'dest', 'dest_elms'=maximum available elements in the 'dest' pointer
  25. Char * Append(Char *dest, CChar8 *src, Int dest_elms); // append 'dest' text from 'src' and return 'dest', 'dest_elms'=maximum available elements in the 'dest' pointer
  26. Char8* Append(Char8 *dest, CChar *src, Int dest_elms); // append 'dest' text from 'src' and return 'dest', 'dest_elms'=maximum available elements in the 'dest' pointer
  27. Char8* Append(Char8 *dest, CChar8 *src, Int dest_elms); // append 'dest' text from 'src' and return 'dest', 'dest_elms'=maximum available elements in the 'dest' pointer
  28. #if EE_PRIVATE
  29. inline Bool Is (C wchar_t *t) {return t && t[0];} // if text has any data
  30. Int Length(C wchar_t *t); // get text length (number of characters)
  31. Char * _Set(Char *dest, C wchar_t *src, Int dest_elms); // set 'dest' text from 'src' and return 'dest', 'dest_elms'=maximum available elements in the 'dest' pointer
  32. Char8* _Set(Char8 *dest, C wchar_t *src, Int dest_elms); // set 'dest' text from 'src' and return 'dest', 'dest_elms'=maximum available elements in the 'dest' pointer
  33. template<Int elms> Int SetReturnLength(Char (&dest)[elms], CChar *src) {return SetReturnLength(dest, src, elms);} // set text, return written length (autodetect dest_elms)
  34. template<Int elms> Int SetReturnLength(Char8 (&dest)[elms], CChar8 *src) {return SetReturnLength(dest, src, elms);} // set text, return written length (autodetect dest_elms)
  35. template<Int elms> void MergePath(Char (&dest)[elms], CChar *first, CChar *second) {return MergePath(dest, first, second, elms);} // merge paths (autodetect dest_elms)
  36. template<Int elms> void MergePath(Char8 (&dest)[elms], CChar8 *first, CChar8 *second) {return MergePath(dest, first, second, elms);} // merge paths (autodetect dest_elms)
  37. #endif
  38. template<Int elms> Char * Set (Char (&dest)[elms], CChar *src) {return Set (dest, src, elms);} // set 'dest' text from 'src' and return 'dest' (autodetect 'dest_elms')
  39. template<Int elms> Char * Set (Char (&dest)[elms], CChar8 *src) {return Set (dest, src, elms);} // set 'dest' text from 'src' and return 'dest' (autodetect 'dest_elms')
  40. template<Int elms> Char8* Set (Char8 (&dest)[elms], CChar *src) {return Set (dest, src, elms);} // set 'dest' text from 'src' and return 'dest' (autodetect 'dest_elms')
  41. template<Int elms> Char8* Set (Char8 (&dest)[elms], CChar8 *src) {return Set (dest, src, elms);} // set 'dest' text from 'src' and return 'dest' (autodetect 'dest_elms')
  42. template<Int elms> Char * Append(Char (&dest)[elms], CChar *src) {return Append(dest, src, elms);} // append 'dest' text from 'src' and return 'dest' (autodetect 'dest_elms')
  43. template<Int elms> Char * Append(Char (&dest)[elms], CChar8 *src) {return Append(dest, src, elms);} // append 'dest' text from 'src' and return 'dest' (autodetect 'dest_elms')
  44. template<Int elms> Char8* Append(Char8 (&dest)[elms], CChar *src) {return Append(dest, src, elms);} // append 'dest' text from 'src' and return 'dest' (autodetect 'dest_elms')
  45. template<Int elms> Char8* Append(Char8 (&dest)[elms], CChar8 *src) {return Append(dest, src, elms);} // append 'dest' text from 'src' and return 'dest' (autodetect 'dest_elms')
  46. Int CompareCI(Char8 a, Char8 b); // compare characters Case-Insensitive, returns -1, 0, +1
  47. Int CompareCI(Char8 a, Char b); // compare characters Case-Insensitive, returns -1, 0, +1
  48. Int CompareCI(Char a, Char8 b); // compare characters Case-Insensitive, returns -1, 0, +1
  49. Int CompareCI(Char a, Char b); // compare characters Case-Insensitive, returns -1, 0, +1
  50. Int CompareCS(Char8 a, Char8 b); // compare characters Case-Sensitive, returns -1, 0, +1
  51. Int CompareCS(Char8 a, Char b); // compare characters Case-Sensitive, returns -1, 0, +1
  52. Int CompareCS(Char a, Char8 b); // compare characters Case-Sensitive, returns -1, 0, +1
  53. Int CompareCS(Char a, Char b); // compare characters Case-Sensitive, returns -1, 0, +1
  54. Int Compare(CChar *a, CChar *b, Bool case_sensitive=false); // compare texts, returns -1, 0, +1
  55. Int Compare(CChar *a, CChar8 *b, Bool case_sensitive=false); // compare texts, returns -1, 0, +1
  56. Int Compare(CChar8 *a, CChar *b, Bool case_sensitive=false); // compare texts, returns -1, 0, +1
  57. Int Compare(CChar8 *a, CChar8 *b, Bool case_sensitive=false); // compare texts, returns -1, 0, +1
  58. inline Bool Equal(CChar *a, CChar *b, Bool case_sensitive=false) {return !Compare(a, b, case_sensitive);} // if texts are equal
  59. inline Bool Equal(CChar *a, CChar8 *b, Bool case_sensitive=false) {return !Compare(a, b, case_sensitive);} // if texts are equal
  60. inline Bool Equal(CChar8 *a, CChar *b, Bool case_sensitive=false) {return !Compare(a, b, case_sensitive);} // if texts are equal
  61. inline Bool Equal(CChar8 *a, CChar8 *b, Bool case_sensitive=false) {return !Compare(a, b, case_sensitive);} // if texts are equal
  62. inline Int CompareCI(C Str &a, C Str &b) {return Compare(a, b, false);} // compare texts Case-Insensitive, you can use this function directly to other parts of the engine which require comparison functions in this format
  63. inline Int CompareCI(C Str8 &a, C Str8 &b) {return Compare(a, b, false);} // compare texts Case-Insensitive, you can use this function directly to other parts of the engine which require comparison functions in this format
  64. inline Int CompareCS(C Str &a, C Str &b) {return Compare(a, b, true );} // compare texts Case- Sensitive, you can use this function directly to other parts of the engine which require comparison functions in this format
  65. inline Int CompareCS(C Str8 &a, C Str8 &b) {return Compare(a, b, true );} // compare texts Case- Sensitive, you can use this function directly to other parts of the engine which require comparison functions in this format
  66. Int ComparePath(CChar *a, CChar *b, Bool case_sensitive=false); // compare paths, returns -1, 0, +1 (this function works the same as comparing texts, except that '/' is treated as equal to '\\')
  67. Int ComparePath(CChar *a, CChar8 *b, Bool case_sensitive=false); // compare paths, returns -1, 0, +1 (this function works the same as comparing texts, except that '/' is treated as equal to '\\')
  68. Int ComparePath(CChar8 *a, CChar *b, Bool case_sensitive=false); // compare paths, returns -1, 0, +1 (this function works the same as comparing texts, except that '/' is treated as equal to '\\')
  69. Int ComparePath(CChar8 *a, CChar8 *b, Bool case_sensitive=false); // compare paths, returns -1, 0, +1 (this function works the same as comparing texts, except that '/' is treated as equal to '\\')
  70. inline Bool EqualPath(CChar *a, CChar *b, Bool case_sensitive=false) {return !ComparePath(a, b, case_sensitive);} // if paths are equal (this function works the same as comparing texts, except that '/' is treated as equal to '\\')
  71. inline Bool EqualPath(CChar *a, CChar8 *b, Bool case_sensitive=false) {return !ComparePath(a, b, case_sensitive);} // if paths are equal (this function works the same as comparing texts, except that '/' is treated as equal to '\\')
  72. inline Bool EqualPath(CChar8 *a, CChar *b, Bool case_sensitive=false) {return !ComparePath(a, b, case_sensitive);} // if paths are equal (this function works the same as comparing texts, except that '/' is treated as equal to '\\')
  73. inline Bool EqualPath(CChar8 *a, CChar8 *b, Bool case_sensitive=false) {return !ComparePath(a, b, case_sensitive);} // if paths are equal (this function works the same as comparing texts, except that '/' is treated as equal to '\\')
  74. inline Int ComparePathCI(C Str &a, C Str &b) {return ComparePath(a, b, false);} // compare paths Case-Insensitive, you can use this function directly to other parts of the engine which require comparison functions in this format
  75. inline Int ComparePathCS(C Str &a, C Str &b) {return ComparePath(a, b, true );} // compare paths Case- Sensitive, you can use this function directly to other parts of the engine which require comparison functions in this format
  76. Int CompareNumber (CChar *a, CChar *b, Bool case_sensitive=false); // compare texts with correct number support, for example "value 2" and "value 10" will be sorted according to the number value (2 vs 10) and not the first different character ('2' vs '1'), returns -1, 0, +1
  77. Int CompareNumber (CChar8 *a, CChar8 *b, Bool case_sensitive=false); // compare texts with correct number support, for example "value 2" and "value 10" will be sorted according to the number value (2 vs 10) and not the first different character ('2' vs '1'), returns -1, 0, +1
  78. Int ComparePathNumber(CChar *a, CChar *b, Bool case_sensitive=false); // compare paths with correct number support, for example "value 2" and "value 10" will be sorted according to the number value (2 vs 10) and not the first different character ('2' vs '1'), returns -1, 0, +1 (this function works the same as 'CompareNumber', except that '/' is treated as equal to '\\')
  79. Int ComparePathNumber(CChar8 *a, CChar8 *b, Bool case_sensitive=false); // compare paths with correct number support, for example "value 2" and "value 10" will be sorted according to the number value (2 vs 10) and not the first different character ('2' vs '1'), returns -1, 0, +1 (this function works the same as 'CompareNumber', except that '/' is treated as equal to '\\')
  80. inline Int ComparePathNumberCI(C Str &a, C Str &b) {return ComparePathNumber(a, b, false);} // compare paths using 'ComparePathNumber' Case-Insensitive, you can use this function directly to other parts of the engine which require comparison functions in this format
  81. inline Int ComparePathNumberCS(C Str &a, C Str &b) {return ComparePathNumber(a, b, true );} // compare paths using 'ComparePathNumber' Case- Sensitive, you can use this function directly to other parts of the engine which require comparison functions in this format
  82. Bool Starts (CChar *t, CChar *start, Bool case_sensitive=false, Bool whole_words=false); // if 't' starts with 'start'
  83. Bool Starts (CChar *t, CChar8 *start, Bool case_sensitive=false, Bool whole_words=false); // if 't' starts with 'start'
  84. Bool Starts (CChar8 *t, CChar *start, Bool case_sensitive=false, Bool whole_words=false); // if 't' starts with 'start'
  85. Bool Starts (CChar8 *t, CChar8 *start, Bool case_sensitive=false, Bool whole_words=false); // if 't' starts with 'start'
  86. Bool Ends (CChar *t, CChar *end , Bool case_sensitive=false ); // if 't' ends with 'end'
  87. Bool Ends (CChar *t, CChar8 *end , Bool case_sensitive=false ); // if 't' ends with 'end'
  88. Bool Ends (CChar8 *t, CChar *end , Bool case_sensitive=false ); // if 't' ends with 'end'
  89. Bool Ends (CChar8 *t, CChar8 *end , Bool case_sensitive=false ); // if 't' ends with 'end'
  90. Bool StartsPath(CChar *t, CChar *start ); // if 't' starts with 'start' path, (this function works the same as 'Starts', except that '/' is treated as equal to '\\')
  91. Bool StartsPath(CChar *t, CChar8 *start ); // if 't' starts with 'start' path, (this function works the same as 'Starts', except that '/' is treated as equal to '\\')
  92. Bool StartsPath(CChar8 *t, CChar *start ); // if 't' starts with 'start' path, (this function works the same as 'Starts', except that '/' is treated as equal to '\\')
  93. Bool StartsPath(CChar8 *t, CChar8 *start ); // if 't' starts with 'start' path, (this function works the same as 'Starts', except that '/' is treated as equal to '\\')
  94. Bool Contains (CChar *src, Char c ); // if 'src' contains 'c' character
  95. Bool Contains (CChar8 *src, Char8 c ); // if 'src' contains 'c' character
  96. Bool Contains (CChar *src, CChar *t, Bool case_sensitive=false, Bool whole_words=false); // if 'src' contains 't' text
  97. Bool Contains (CChar *src, CChar8 *t, Bool case_sensitive=false, Bool whole_words=false); // if 'src' contains 't' text
  98. Bool Contains (CChar8 *src, CChar *t, Bool case_sensitive=false, Bool whole_words=false); // if 'src' contains 't' text
  99. Bool Contains (CChar8 *src, CChar8 *t, Bool case_sensitive=false, Bool whole_words=false); // if 'src' contains 't' text
  100. Bool ContainsAny(CChar *src, CChar *t, Bool case_sensitive=false, Bool whole_words=false); // if 'src' contains any words from 't' (words are separated by spaces)
  101. Bool ContainsAll(CChar *src, CChar *t, Bool case_sensitive=false, Bool whole_words=false); // if 'src' contains all words from 't' (words are separated by spaces)
  102. Bool ContainsAll(CChar *src, CChar8 *t, Bool case_sensitive=false, Bool whole_words=false); // if 'src' contains all words from 't' (words are separated by spaces)
  103. Bool ContainsAll(CChar8 *src, CChar *t, Bool case_sensitive=false, Bool whole_words=false); // if 'src' contains all words from 't' (words are separated by spaces)
  104. Bool ContainsAll(CChar8 *src, CChar8 *t, Bool case_sensitive=false, Bool whole_words=false); // if 'src' contains all words from 't' (words are separated by spaces)
  105. #if EE_PRIVATE
  106. inline CChar * _SkipChar (CChar *t ) {return Is(t) ? t+1 : null;} // return next character in the text
  107. inline CChar8* _SkipChar (CChar8 *t ) {return Is(t) ? t+1 : null;} // return next character in the text
  108. CChar * _SkipWhiteChars(CChar *t ); // skip all starting white chars, Sample Usage: SkipWhiteChars(" a b c") -> "a b c"
  109. CChar8* _SkipWhiteChars(CChar8 *t ); // skip all starting white chars, Sample Usage: SkipWhiteChars(" a b c") -> "a b c"
  110. CChar * _SkipStart (CChar *t, CChar *start); // if 't' starts with 'start' then return 't' after 'start', in other case return full 't', Sample Usage: _SkipStart ("abcd", "ab") -> "cd", SkipStart("abcd", "ef") -> "abcd"
  111. CChar * _SkipStart (CChar *t, CChar8 *start); // if 't' starts with 'start' then return 't' after 'start', in other case return full 't', Sample Usage: _SkipStart ("abcd", "ab") -> "cd", SkipStart("abcd", "ef") -> "abcd"
  112. CChar8* _SkipStart (CChar8 *t, CChar *start); // if 't' starts with 'start' then return 't' after 'start', in other case return full 't', Sample Usage: _SkipStart ("abcd", "ab") -> "cd", SkipStart("abcd", "ef") -> "abcd"
  113. CChar8* _SkipStart (CChar8 *t, CChar8 *start); // if 't' starts with 'start' then return 't' after 'start', in other case return full 't', Sample Usage: _SkipStart ("abcd", "ab") -> "cd", SkipStart("abcd", "ef") -> "abcd"
  114. CChar * _SkipStartPath (CChar *t, CChar *start); // if 't' starts with 'start' path then return 't' after 'start', in other case return full 't', Sample Usage: _SkipStartPath("C:/Folder/temp/file.ext", "C:/Folder") -> "temp/file.ext" (treats '/' as equal to '\\')
  115. CChar8* _SkipStartPath (CChar8 *t, CChar8 *start); // if 't' starts with 'start' path then return 't' after 'start', in other case return full 't', Sample Usage: _SkipStartPath("C:/Folder/temp/file.ext", "C:/Folder") -> "temp/file.ext" (treats '/' as equal to '\\')
  116. CChar * _AfterPath (CChar *t, CChar *start); // if 't' starts with 'start' path then return 't' after 'start', in other case return null , Sample Usage: _AfterPath ("C:/Folder/temp/file.ext", "C:/Folder") -> "temp/file.ext" (treats '/' as equal to '\\')
  117. #endif
  118. Str SkipWhiteChars(C Str &t ); // skip all starting white chars, Sample Usage: SkipWhiteChars(" a b c") -> "a b c"
  119. Str SkipStartPath (C Str &t, C Str &start); // if 't' starts with 'start' path then return 't' after 'start', in other case return full 't', Sample Usage: SkipStartPath("C:/Folder/Temp/file.ext", "C:/Folder") -> "Temp/file.ext" (treats '/' as equal to '\\')
  120. Str SkipStart (C Str &t, C Str &start); // if 't' starts with 'start' then return 't' after 'start', in other case return full 't', Sample Usage: SkipStart ("abcd", "ab") -> "cd", SkipStart("abcd", "ef") -> "abcd"
  121. Str SkipEnd (C Str &t, C Str &end ); // if 't' ends with 'end' then return 't' without 'end' , in other case return full 't', Sample Usage: SkipEnd ("abcd", "cd") -> "ab", SkipEnd ("abcd", "ef") -> "abcd"
  122. #if EE_PRIVATE
  123. Char * ReplaceSelf(Char *text, Char from, Char to);
  124. Char8* ReplaceSelf(Char8 *text, Char8 from, Char8 to);
  125. #endif
  126. Str Replace(C Str &text, Char from, Char to ); // replace 'from' -> 'to' in 'text', Sample Usage: Replace("abcde", 'd', '7') -> "abc7e"
  127. Str Replace(C Str &text, C Str &from, C Str &to, Bool case_sensitive=false, Bool whole_words=false); // replace 'from' -> 'to' in 'text', Sample Usage: Replace("This is not a cat", "not ", "") -> "This is a cat"
  128. Str Trim(C Str &text, Int pos, Int length); // trim string by removing start and end, to keep only the part starting at 'pos' of 'length' length
  129. Str8 Trim(C Str8 &text, Int pos, Int length); // trim string by removing start and end, to keep only the part starting at 'pos' of 'length' length
  130. Str CaseDown(C Str &t); // return case down version of the string, Sample Usage: CaseDown("AbCdEFG") -> "abcdefg"
  131. Str CaseUp (C Str &t); // return case up version of the string, Sample Usage: CaseUp ("AbCdEFG") -> "ABCDEFG"
  132. void Split(MemPtr<Str> splits, C Str &string, Char separator); // split 'string' into an array of strings separated by 'separator', Sample Usage: Split("123:45::6:", ':') -> {"123", "45", "", "6", ""}
  133. Memc<Str> Split( C Str &string, Char separator); // split 'string' into an array of strings separated by 'separator', Sample Usage: Split("123:45::6:", ':') -> {"123", "45", "", "6", ""}
  134. void Tokenize(MemPtr<Str> tokens, C Str &string); // tokenize 'string' into tokens, this works by removing all white chars and making sure that symbols are separate from words, Sample Usage: Split("Sample value = 15") -> {"Sample", "value", "=", "15"}
  135. Int TextPosI(CChar *src, Char c); // get position of first 'c' character in 'src' text (-1 if none)
  136. Int TextPosI(CChar8 *src, Char8 c); // get position of first 'c' character in 'src' text (-1 if none)
  137. CChar * TextPos (CChar *src, Char c); // get pointer to position of first 'c' character in 'src' text (null if none)
  138. CChar8* TextPos (CChar8 *src, Char8 c); // get pointer to position of first 'c' character in 'src' text (null if none)
  139. Char * TextPos ( Char *src, Char c); // get pointer to position of first 'c' character in 'src' text (null if none)
  140. Char8* TextPos ( Char8 *src, Char8 c); // get pointer to position of first 'c' character in 'src' text (null if none)
  141. Int TextPosI(CChar *src, CChar *t, Bool case_sensitive=false, Bool whole_words=false); // get position of first 't' text in 'src' text (-1 if none)
  142. Int TextPosI(CChar *src, CChar8 *t, Bool case_sensitive=false, Bool whole_words=false); // get position of first 't' text in 'src' text (-1 if none)
  143. Int TextPosI(CChar8 *src, CChar8 *t, Bool case_sensitive=false, Bool whole_words=false); // get position of first 't' text in 'src' text (-1 if none)
  144. CChar * TextPos (CChar *src, CChar *t, Bool case_sensitive=false, Bool whole_words=false); // get pointer to position of first 't' text in 'src' text (null if none)
  145. CChar * TextPos (CChar *src, CChar8 *t, Bool case_sensitive=false, Bool whole_words=false); // get pointer to position of first 't' text in 'src' text (null if none)
  146. CChar8* TextPos (CChar8 *src, CChar8 *t, Bool case_sensitive=false, Bool whole_words=false); // get pointer to position of first 't' text in 'src' text (null if none)
  147. #if EE_PRIVATE
  148. Int TextPosIN(CChar *src, Char c, Int i); // get position of i-th 'c' character in 'src' text (-1 if none)
  149. Int TextPosIN(CChar8 *src, Char8 c, Int i); // get position of i-th 'c' character in 'src' text (-1 if none)
  150. Int TextPosIN(CChar8 *src, CChar8 *t, Int i, Bool case_sensitive=false, Bool whole_words=false); // get position of i-th 't' text in 'src' text (-1 if none)
  151. Int TextPosSkipSpaceI(CChar *src, CChar *t, Int &match_length, Bool case_sensitive=false, Bool whole_words=false); // get position of 't' text in 'src' text (-1 if none)
  152. #endif
  153. Str StrInside(C Str &str, C Str &from, C Str &to, Bool case_sensitive=false, Bool whole_words=false); // get part of the string located between 'from' and 'to' strings, 'S' is returned if not found
  154. // convert from value to text, 'digits'=number of digits to generate (-1=autodetect), 'separate'=number of digits to be separated with a space ' ', 'prefix'=if insert a prefix ("0b" for binary and "0x" for hexadecimal)
  155. CChar8* TextBool(Bool b ); // return b ? "true" : "false";
  156. Str TextInt (Int i, Int digits =-1, Int separate=0 );
  157. Str TextInt (Long i, Int digits =-1, Int separate=0 );
  158. Str TextInt (UInt u, Int digits =-1, Int separate=0 );
  159. Str TextInt (ULong u, Int digits =-1, Int separate=0 );
  160. Str TextBin (UInt u, Int digits =-1, Int separate=0, Bool prefix=false);
  161. Str TextBin (ULong u, Int digits =-1, Int separate=0, Bool prefix=false);
  162. Str TextHex (UInt u, Int digits =-1, Int separate=0, Bool prefix=false);
  163. Str TextHex (ULong u, Int digits =-1, Int separate=0, Bool prefix=false);
  164. Str TextHex (Flt r );
  165. Str TextHex (Dbl r );
  166. Str TextReal(Dbl r, Int precision=-6, Int separate=0 );
  167. inline Str TextFlt (Dbl r, Int separate=0 ) {return TextReal(r, 3, separate);}
  168. inline Str TextDbl (Dbl r, Int separate=0 ) {return TextReal(r, 9, separate);}
  169. Str TextHexMem(CPtr data, Int size, Bool prefix=false); // convert memory to its hex representation, 'prefix'=if include "0x" prefix at the start
  170. // convert from text to value
  171. #if EE_PRIVATE
  172. CChar * TextValue(CChar *t, CalcValue &value, Bool allow_real=true); // sets 'value' according to 't' input, returns pointer to the place in 't' after it stopped reading, 'allow_real'=if allow parsing floating point values
  173. CChar8* TextValue(CChar8 *t, CalcValue &value, Bool allow_real=true); // sets 'value' according to 't' input, returns pointer to the place in 't' after it stopped reading, 'allow_real'=if allow parsing floating point values
  174. Bool TextHexMem(C Str &t, Ptr data, Int size); // convert text hex representation to memory, this function assumes that there's no "0x" prefix at the start, false on fail
  175. #endif
  176. Bool TextBool (CChar *t); Bool TextBool (CChar8 *t); // false on fail (if 't' string is empty, then 'false' is returned)
  177. Bool TextBool1 (CChar *t); Bool TextBool1 (CChar8 *t); // false on fail (if 't' string is empty, then 'true' is returned)
  178. Int TextInt (CChar *t); Int TextInt (CChar8 *t); // 0 on fail
  179. UInt TextUInt (CChar *t); UInt TextUInt (CChar8 *t); // 0 on fail
  180. Long TextLong (CChar *t); Long TextLong (CChar8 *t); // 0 on fail
  181. ULong TextULong (CChar *t); ULong TextULong (CChar8 *t); // 0 on fail
  182. Flt TextFlt (CChar *t); Flt TextFlt (CChar8 *t); // 0 on fail
  183. Dbl TextDbl (CChar *t); Dbl TextDbl (CChar8 *t); // 0 on fail
  184. Vec2 TextVec2 (CChar *t); Vec2 TextVec2 (CChar8 *t); // (0,0) on fail
  185. VecD2 TextVecD2 (CChar *t); VecD2 TextVecD2 (CChar8 *t); // (0,0) on fail
  186. VecI2 TextVecI2 (CChar *t); VecI2 TextVecI2 (CChar8 *t); // (0,0) on fail
  187. VecB2 TextVecB2 (CChar *t); VecB2 TextVecB2 (CChar8 *t); // (0,0) on fail
  188. VecSB2 TextVecSB2(CChar *t); VecSB2 TextVecSB2(CChar8 *t); // (0,0) on fail
  189. VecUS2 TextVecUS2(CChar *t); VecUS2 TextVecUS2(CChar8 *t); // (0,0) on fail
  190. Vec TextVec (CChar *t); Vec TextVec (CChar8 *t); // (0,0,0) on fail
  191. VecD TextVecD (CChar *t); VecD TextVecD (CChar8 *t); // (0,0,0) on fail
  192. VecI TextVecI (CChar *t); VecI TextVecI (CChar8 *t); // (0,0,0) on fail
  193. VecB TextVecB (CChar *t); VecB TextVecB (CChar8 *t); // (0,0,0) on fail
  194. VecSB TextVecSB (CChar *t); VecSB TextVecSB (CChar8 *t); // (0,0,0) on fail
  195. VecUS TextVecUS (CChar *t); VecUS TextVecUS (CChar8 *t); // (0,0,0) on fail
  196. Vec4 TextVec4 (CChar *t); Vec4 TextVec4 (CChar8 *t); // (0,0,0,0) on fail
  197. VecD4 TextVecD4 (CChar *t); VecD4 TextVecD4 (CChar8 *t); // (0,0,0,0) on fail
  198. VecI4 TextVecI4 (CChar *t); VecI4 TextVecI4 (CChar8 *t); // (0,0,0,0) on fail
  199. VecB4 TextVecB4 (CChar *t); VecB4 TextVecB4 (CChar8 *t); // (0,0,0,0) on fail
  200. VecSB4 TextVecSB4(CChar *t); VecSB4 TextVecSB4(CChar8 *t); // (0,0,0,0) on fail
  201. Color TextColor (CChar *t); Color TextColor (CChar8 *t); // (0,0,0,0) on fail
  202. UID TextUID (CChar *t); UID TextUID (CChar8 *t); // 'UIDZero' on fail
  203. Str FromUTF8(CChar8 *text); // convert 'text' from UTF-8 format into Str
  204. Str8 UTF8 (C Str &text); // convert 'text' from Str into UTF-8 format
  205. // compare strings
  206. // Str == (Str, Str8, CChar*, CChar8*, Char, Char8)
  207. inline Bool operator==(C Str &a, C Str &b) {return Equal(a, b);}
  208. inline Bool operator==(C Str &a, C Str8 &b) {return Equal(a, b);}
  209. inline Bool operator==(C Str &s, CChar *t) {return Equal(s, t);}
  210. inline Bool operator==(C Str &s, CChar8 *t) {return Equal(s, t);}
  211. inline Bool operator==(CChar *t, C Str &s) {return Equal(s, t);}
  212. inline Bool operator==(CChar8 *t, C Str &s) {return Equal(s, t);}
  213. inline Bool operator==(C Str &s, Char c) {return s.length()==1 && !Compare(s[0], c);}
  214. inline Bool operator==(C Str &s, Char8 c) {return s.length()==1 && !Compare(s[0], c);}
  215. inline Bool operator==(Char c, C Str &s) {return s.length()==1 && !Compare(s[0], c);}
  216. inline Bool operator==(Char8 c, C Str &s) {return s.length()==1 && !Compare(s[0], c);}
  217. // Str != (Str, Str8, CChar*, CChar8*, Char, Char8)
  218. inline Bool operator!=(C Str &a, C Str &b) {return !Equal(a, b);}
  219. inline Bool operator!=(C Str &a, C Str8 &b) {return !Equal(a, b);}
  220. inline Bool operator!=(C Str &s, CChar *t) {return !Equal(s, t);}
  221. inline Bool operator!=(C Str &s, CChar8 *t) {return !Equal(s, t);}
  222. inline Bool operator!=(CChar *t, C Str &s) {return !Equal(s, t);}
  223. inline Bool operator!=(CChar8 *t, C Str &s) {return !Equal(s, t);}
  224. inline Bool operator!=(C Str &s, Char c) {return s.length()!=1 || Compare(s[0], c);}
  225. inline Bool operator!=(C Str &s, Char8 c) {return s.length()!=1 || Compare(s[0], c);}
  226. inline Bool operator!=(Char c, C Str &s) {return s.length()!=1 || Compare(s[0], c);}
  227. inline Bool operator!=(Char8 c, C Str &s) {return s.length()!=1 || Compare(s[0], c);}
  228. // Str8 == (Str, Str8, CChar*, CChar8*, Char, Char8)
  229. inline Bool operator==(C Str8 &a, C Str &b) {return Equal(a, b);}
  230. inline Bool operator==(C Str8 &a, C Str8 &b) {return Equal(a, b);}
  231. inline Bool operator==(C Str8 &s, CChar *t) {return Equal(s, t);}
  232. inline Bool operator==(C Str8 &s, CChar8 *t) {return Equal(s, t);}
  233. inline Bool operator==(CChar *t, C Str8 &s) {return Equal(s, t);}
  234. inline Bool operator==(CChar8 *t, C Str8 &s) {return Equal(s, t);}
  235. inline Bool operator==(C Str8 &s, Char c) {return s.length()==1 && !Compare(s[0], c);}
  236. inline Bool operator==(C Str8 &s, Char8 c) {return s.length()==1 && !Compare(s[0], c);}
  237. inline Bool operator==(Char c, C Str8 &s) {return s.length()==1 && !Compare(s[0], c);}
  238. inline Bool operator==(Char8 c, C Str8 &s) {return s.length()==1 && !Compare(s[0], c);}
  239. // Str8 != (Str, Str8, CChar*, CChar8*, Char, Char8)
  240. inline Bool operator!=(C Str8 &a, C Str &b) {return !Equal(a, b);}
  241. inline Bool operator!=(C Str8 &a, C Str8 &b) {return !Equal(a, b);}
  242. inline Bool operator!=(C Str8 &s, CChar *t) {return !Equal(s, t);}
  243. inline Bool operator!=(C Str8 &s, CChar8 *t) {return !Equal(s, t);}
  244. inline Bool operator!=(CChar *t, C Str8 &s) {return !Equal(s, t);}
  245. inline Bool operator!=(CChar8 *t, C Str8 &s) {return !Equal(s, t);}
  246. inline Bool operator!=(C Str8 &s, Char c) {return s.length()!=1 || Compare(s[0], c);}
  247. inline Bool operator!=(C Str8 &s, Char8 c) {return s.length()!=1 || Compare(s[0], c);}
  248. inline Bool operator!=(Char c, C Str8 &s) {return s.length()!=1 || Compare(s[0], c);}
  249. inline Bool operator!=(Char8 c, C Str8 &s) {return s.length()!=1 || Compare(s[0], c);}
  250. /******************************************************************************/
  251. #if EE_PRIVATE
  252. Str8 MultiByte(Int code_page, C Str &text);
  253. typedef Str StrO; // String that doesn't require 16-bit wide-char support, but is also optimal in performance, for example 'Str' is used instead of 'Str8', because 'Str' is more widely used across the engine (in most class members and function parameters) allowing to do fast copying through Rvalue References, and fast passing to function params
  254. struct Str8Temp // allows casts from 'CChar8*' to 'Str8' without any memory allocations, however in read-only mode
  255. {
  256. operator C Str8&()C {return _;} // cast to C Str8&
  257. explicit Str8Temp(CChar8 *name)
  258. {
  259. if(name)
  260. {
  261. _._length=Length(name);
  262. _._d.setTemp(ConstCast(name), _._length+1); // including null character
  263. }
  264. }
  265. ~Str8Temp() {_._d.setTemp(null, 0);}
  266. private:
  267. Str8 _;
  268. };
  269. #define PRECISION_HALF 2
  270. #define PRECISION_FLT 3
  271. #define PRECISION_DBL 9
  272. template<Int size> struct TempChar8 { Char8 c[size]; };
  273. template<Int size> struct TempChar { Char c[size]; };
  274. Str FixNewLine(C Str &text); // remove existing '\r' and then replace '\n' with "\r\n"
  275. Int CompareCS(C Str &a, C BStr &b);
  276. Str TextHexMem(File &file, Bool prefix=false);
  277. CChar8* TextInt (Int i, Char8 (&temp)[256], Int digits=-1, Int separate=0 );
  278. CChar8* TextInt (Long i, Char8 (&temp)[256], Int digits=-1, Int separate=0 );
  279. CChar8* TextInt (UInt u, Char8 (&temp)[256], Int digits=-1, Int separate=0 );
  280. CChar8* TextInt (ULong u, Char8 (&temp)[256], Int digits=-1, Int separate=0 );
  281. CChar8* TextBin (UInt u, Char8 (&temp)[256], Int digits=-1, Int separate=0, Bool prefix=false);
  282. CChar8* TextBin (ULong u, Char8 (&temp)[256], Int digits=-1, Int separate=0, Bool prefix=false);
  283. CChar8* TextHex (UInt u, Char8 (&temp)[256], Int digits=-1, Int separate=0, Bool prefix=false);
  284. CChar8* TextHex (ULong u, Char8 (&temp)[256], Int digits=-1, Int separate=0, Bool prefix=false);
  285. CChar8* _TextHex (Flt f, Char8 (&temp)[17]=ConstCast(TempChar8<17>()).c);
  286. CChar8* _TextHex (Dbl d, Char8 (&temp)[25]=ConstCast(TempChar8<25>()).c);
  287. CChar8* TextReal (Dbl r, Char8 (&temp)[256], Int precision, Int separate=0 );
  288. inline CChar8* TextFlt (Dbl r, Char8 (&temp)[256], Int separate=0 ) {return TextReal(r, temp, PRECISION_FLT, separate);}
  289. inline CChar8* TextDbl (Dbl r, Char8 (&temp)[256], Int separate=0 ) {return TextReal(r, temp, PRECISION_DBL, separate);}
  290. #if WINDOWS
  291. ASSERT(SIZE(wchar_t)==SIZE(Char));
  292. inline wchar_t* WChar( Char *t) {return (wchar_t*)t;}
  293. inline C wchar_t* WChar(C Char *t) {return (wchar_t*)t;}
  294. inline Char * WChar( wchar_t *t) {return ( Char *)t;}
  295. inline C Char * WChar(C wchar_t *t) {return ( Char *)t;}
  296. #endif
  297. #if APPLE
  298. NSString* AppleString(C Str &str);
  299. Str AppleString(NSString *str);
  300. inline Str::Str (NSString *s) : Str(AppleString(s)) {}
  301. inline Str& Str::operator =(NSString *s) {return T =AppleString(s);}
  302. inline Str& Str::operator+=(NSString *s) {return T+=AppleString(s);}
  303. inline Str Str::operator+ (NSString *s)C{return T+ AppleString(s);}
  304. struct NSStringAuto // 'NSString' with auto-release
  305. {
  306. operator NSString*()C {return str;}
  307. NSString* operator()()C {return str;}
  308. ~NSStringAuto() {[str release]; /*str=null;*/} // it's safe to call "[null release]"
  309. NSStringAuto() {str=null;}
  310. NSStringAuto(C Str &str) {T.str=AppleString(str);}
  311. NSStringAuto(C Str8 &str) {T.str=AppleString(str);}
  312. NSStringAuto(CChar *str) {T.str=AppleString(str);}
  313. NSStringAuto(CChar chr) {T.str=AppleString(chr);}
  314. private:
  315. NSString *str;
  316. NO_COPY_CONSTRUCTOR(NSStringAuto);
  317. };
  318. struct NSURLAuto : NSStringAuto // 'NSURL' with auto-release
  319. {
  320. operator Bool ()C {return url!=null;}
  321. operator NSURL*()C {return url;}
  322. NSURL* operator()()C {return url;}
  323. //~NSURLAuto() {[url release]; /*url=null;*/} this is always created using 'URLWithString' and it can't be released because that would cause crash (probably it reuses the same memory from 'NSString')
  324. NSURLAuto(C Str &str);
  325. private:
  326. NSURL *url;
  327. NO_COPY_CONSTRUCTOR(NSURLAuto);
  328. };
  329. #endif
  330. #endif
  331. /******************************************************************************/