Mercurial > foo_out_sdl
comparison foosdk/sdk/pfc/splitString.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 #include "array.h" | |
| 3 #include "string_base.h" | |
| 4 | |
| 5 namespace pfc { | |
| 6 template<typename t_output, typename t_splitCheck> | |
| 7 void splitStringEx(t_output& p_output, const t_splitCheck& p_check, const char* p_string, t_size p_stringLen = SIZE_MAX) { | |
| 8 t_size walk = 0, splitBase = 0; | |
| 9 const t_size max = strlen_max(p_string, p_stringLen); | |
| 10 for (; walk < max;) { | |
| 11 t_size delta = p_check(p_string + walk, max - walk); | |
| 12 if (delta > 0) { | |
| 13 if (walk > splitBase) p_output(p_string + splitBase, walk - splitBase); | |
| 14 splitBase = walk + delta; | |
| 15 } else { | |
| 16 delta = utf8_char_len(p_string + walk, max - walk); | |
| 17 if (delta == 0) break; | |
| 18 } | |
| 19 walk += delta; | |
| 20 } | |
| 21 if (walk > splitBase) p_output(p_string + splitBase, walk - splitBase); | |
| 22 } | |
| 23 | |
| 24 class __splitStringSimple_calculateSubstringCount { | |
| 25 public: | |
| 26 __splitStringSimple_calculateSubstringCount() : m_count() {} | |
| 27 void operator() (const char*, t_size) { ++m_count; } | |
| 28 t_size get() const { return m_count; } | |
| 29 private: | |
| 30 t_size m_count; | |
| 31 }; | |
| 32 | |
| 33 template<typename t_param> class _splitStringSimple_check; | |
| 34 | |
| 35 template<> class _splitStringSimple_check<const char*> { | |
| 36 public: | |
| 37 _splitStringSimple_check(const char* p_chars) { | |
| 38 m_chars.set_size(strlen_utf8(p_chars)); | |
| 39 for (t_size walk = 0, ptr = 0; walk < m_chars.get_size(); ++walk) { | |
| 40 ptr += utf8_decode_char(p_chars + ptr, m_chars[walk]); | |
| 41 } | |
| 42 } | |
| 43 t_size operator()(const char* p_string, t_size p_stringLen) const { | |
| 44 t_uint32 c; | |
| 45 t_size delta = utf8_decode_char(p_string, c, p_stringLen); | |
| 46 if (delta > 0) { | |
| 47 for (t_size walk = 0; walk < m_chars.get_size(); ++walk) { | |
| 48 if (m_chars[walk] == c) return delta; | |
| 49 } | |
| 50 } | |
| 51 return 0; | |
| 52 } | |
| 53 private: | |
| 54 array_t<t_uint32> m_chars; | |
| 55 }; | |
| 56 template<> class _splitStringSimple_check<char> { | |
| 57 public: | |
| 58 _splitStringSimple_check(char c) : m_char(c) {} | |
| 59 t_size operator()(const char* str, t_size len) const { | |
| 60 PFC_ASSERT(len > 0); (void)len; | |
| 61 if (*str == m_char) return 1; | |
| 62 else return 0; | |
| 63 } | |
| 64 private: | |
| 65 const char m_char; | |
| 66 }; | |
| 67 template<typename t_array> | |
| 68 class __splitStringSimple_arrayWrapper { | |
| 69 public: | |
| 70 __splitStringSimple_arrayWrapper(t_array& p_array) : m_walk(), m_array(p_array) {} | |
| 71 void operator()(const char* p_string, t_size p_stringLen) { | |
| 72 m_array[m_walk++] = string_part(p_string, p_stringLen); | |
| 73 } | |
| 74 private: | |
| 75 t_size m_walk; | |
| 76 t_array& m_array; | |
| 77 }; | |
| 78 template<typename t_list> | |
| 79 class __splitStringSimple_listWrapper { | |
| 80 public: | |
| 81 __splitStringSimple_listWrapper(t_list& p_list) : m_list(p_list) {} | |
| 82 void operator()(const char* p_string, t_size p_stringLen) { | |
| 83 m_list += string_part(p_string, p_stringLen); | |
| 84 } | |
| 85 private: | |
| 86 t_list& m_list; | |
| 87 }; | |
| 88 | |
| 89 template<typename t_array, typename t_split> | |
| 90 void splitStringSimple_toArray(t_array& p_output, t_split p_split, const char* p_string, t_size p_stringLen = SIZE_MAX) { | |
| 91 _splitStringSimple_check<t_split> strCheck(p_split); | |
| 92 | |
| 93 { | |
| 94 __splitStringSimple_calculateSubstringCount wrapper; | |
| 95 splitStringEx(wrapper, strCheck, p_string, p_stringLen); | |
| 96 p_output.set_size(wrapper.get()); | |
| 97 } | |
| 98 | |
| 99 { | |
| 100 __splitStringSimple_arrayWrapper<t_array> wrapper(p_output); | |
| 101 splitStringEx(wrapper, strCheck, p_string, p_stringLen); | |
| 102 } | |
| 103 } | |
| 104 template<typename t_list, typename t_split> | |
| 105 void splitStringSimple_toList(t_list& p_output, t_split p_split, const char* p_string, t_size p_stringLen = SIZE_MAX) { | |
| 106 _splitStringSimple_check<t_split> strCheck(p_split); | |
| 107 | |
| 108 __splitStringSimple_listWrapper<t_list> wrapper(p_output); | |
| 109 splitStringEx(wrapper, strCheck, p_string, p_stringLen); | |
| 110 } | |
| 111 | |
| 112 template<typename t_out> void splitStringByLines(t_out& out, const char* str) { | |
| 113 for (;;) { | |
| 114 const char* next = strchr(str, '\n'); | |
| 115 if (next == NULL) { | |
| 116 out += string_part(str, strlen(str)); break; | |
| 117 } | |
| 118 const char* walk = next; | |
| 119 while (walk > str && walk[-1] == '\r') --walk; | |
| 120 out += string_part(str, walk - str); | |
| 121 str = next + 1; | |
| 122 } | |
| 123 } | |
| 124 template<typename t_out> void splitStringByChar(t_out& out, const char* str, char c) { | |
| 125 for (;;) { | |
| 126 const char* next = strchr(str, c); | |
| 127 if (next == NULL) { | |
| 128 out += string_part(str, strlen(str)); break; | |
| 129 } | |
| 130 out += string_part(str, next - str); | |
| 131 str = next + 1; | |
| 132 } | |
| 133 } | |
| 134 template<typename t_out> void splitStringBySubstring(t_out& out, const char* str, const char* split) { | |
| 135 for (;;) { | |
| 136 const char* next = strstr(str, split); | |
| 137 if (next == NULL) { | |
| 138 out += string_part(str, strlen(str)); break; | |
| 139 } | |
| 140 out += string_part(str, next - str); | |
| 141 str = next + strlen(split); | |
| 142 } | |
| 143 } | |
| 144 } |
