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 }