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