Mercurial > foo_out_sdl
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/pfc/splitString.h Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,144 @@ +#pragma once +#include "array.h" +#include "string_base.h" + +namespace pfc { + template<typename t_output, typename t_splitCheck> + void splitStringEx(t_output& p_output, const t_splitCheck& p_check, const char* p_string, t_size p_stringLen = SIZE_MAX) { + t_size walk = 0, splitBase = 0; + const t_size max = strlen_max(p_string, p_stringLen); + for (; walk < max;) { + t_size delta = p_check(p_string + walk, max - walk); + if (delta > 0) { + if (walk > splitBase) p_output(p_string + splitBase, walk - splitBase); + splitBase = walk + delta; + } else { + delta = utf8_char_len(p_string + walk, max - walk); + if (delta == 0) break; + } + walk += delta; + } + if (walk > splitBase) p_output(p_string + splitBase, walk - splitBase); + } + + class __splitStringSimple_calculateSubstringCount { + public: + __splitStringSimple_calculateSubstringCount() : m_count() {} + void operator() (const char*, t_size) { ++m_count; } + t_size get() const { return m_count; } + private: + t_size m_count; + }; + + template<typename t_param> class _splitStringSimple_check; + + template<> class _splitStringSimple_check<const char*> { + public: + _splitStringSimple_check(const char* p_chars) { + m_chars.set_size(strlen_utf8(p_chars)); + for (t_size walk = 0, ptr = 0; walk < m_chars.get_size(); ++walk) { + ptr += utf8_decode_char(p_chars + ptr, m_chars[walk]); + } + } + t_size operator()(const char* p_string, t_size p_stringLen) const { + t_uint32 c; + t_size delta = utf8_decode_char(p_string, c, p_stringLen); + if (delta > 0) { + for (t_size walk = 0; walk < m_chars.get_size(); ++walk) { + if (m_chars[walk] == c) return delta; + } + } + return 0; + } + private: + array_t<t_uint32> m_chars; + }; + template<> class _splitStringSimple_check<char> { + public: + _splitStringSimple_check(char c) : m_char(c) {} + t_size operator()(const char* str, t_size len) const { + PFC_ASSERT(len > 0); (void)len; + if (*str == m_char) return 1; + else return 0; + } + private: + const char m_char; + }; + template<typename t_array> + class __splitStringSimple_arrayWrapper { + public: + __splitStringSimple_arrayWrapper(t_array& p_array) : m_walk(), m_array(p_array) {} + void operator()(const char* p_string, t_size p_stringLen) { + m_array[m_walk++] = string_part(p_string, p_stringLen); + } + private: + t_size m_walk; + t_array& m_array; + }; + template<typename t_list> + class __splitStringSimple_listWrapper { + public: + __splitStringSimple_listWrapper(t_list& p_list) : m_list(p_list) {} + void operator()(const char* p_string, t_size p_stringLen) { + m_list += string_part(p_string, p_stringLen); + } + private: + t_list& m_list; + }; + + template<typename t_array, typename t_split> + void splitStringSimple_toArray(t_array& p_output, t_split p_split, const char* p_string, t_size p_stringLen = SIZE_MAX) { + _splitStringSimple_check<t_split> strCheck(p_split); + + { + __splitStringSimple_calculateSubstringCount wrapper; + splitStringEx(wrapper, strCheck, p_string, p_stringLen); + p_output.set_size(wrapper.get()); + } + + { + __splitStringSimple_arrayWrapper<t_array> wrapper(p_output); + splitStringEx(wrapper, strCheck, p_string, p_stringLen); + } + } + template<typename t_list, typename t_split> + void splitStringSimple_toList(t_list& p_output, t_split p_split, const char* p_string, t_size p_stringLen = SIZE_MAX) { + _splitStringSimple_check<t_split> strCheck(p_split); + + __splitStringSimple_listWrapper<t_list> wrapper(p_output); + splitStringEx(wrapper, strCheck, p_string, p_stringLen); + } + + template<typename t_out> void splitStringByLines(t_out& out, const char* str) { + for (;;) { + const char* next = strchr(str, '\n'); + if (next == NULL) { + out += string_part(str, strlen(str)); break; + } + const char* walk = next; + while (walk > str && walk[-1] == '\r') --walk; + out += string_part(str, walk - str); + str = next + 1; + } + } + template<typename t_out> void splitStringByChar(t_out& out, const char* str, char c) { + for (;;) { + const char* next = strchr(str, c); + if (next == NULL) { + out += string_part(str, strlen(str)); break; + } + out += string_part(str, next - str); + str = next + 1; + } + } + template<typename t_out> void splitStringBySubstring(t_out& out, const char* str, const char* split) { + for (;;) { + const char* next = strstr(str, split); + if (next == NULL) { + out += string_part(str, strlen(str)); break; + } + out += string_part(str, next - str); + str = next + strlen(split); + } + } +}
