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);
+		}
+	}
+}