comparison foosdk/sdk/pfc/string-lite.cpp @ 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 #include "pfc-lite.h"
2 #include "string-lite.h"
3 #include "string_base.h"
4
5 namespace pfc {
6 const unsigned alloc_minimum = 128;
7
8 void stringLite::add_string(const char* p_string, t_size p_string_size) {
9 add_string_nc(p_string, strlen_max(p_string, p_string_size));
10 }
11
12 void stringLite::add_string_nc(const char* ptr, size_t length) {
13 if (length > 0) {
14 const size_t base = m_length;
15 const size_t newLen = base + length;
16 makeRoom(newLen);
17 auto p = (char*)m_mem.ptr();
18 memcpy(p + base, ptr, length);
19 p[newLen] = 0;
20 m_length = newLen;
21 m_ptr = p;
22 }
23
24 }
25
26 void stringLite::set_string(const char* p_string, t_size p_length) {
27 set_string_nc(p_string, strlen_max(p_string, p_length));
28 }
29
30 void stringLite::set_string_nc(const char* ptr, size_t length) {
31 if (length > 0) {
32 makeRoom(length);
33 auto p = (char*)m_mem.ptr();
34 memcpy(p, ptr, length);
35 p[length] = 0;
36 m_ptr = p;
37 m_length = length;
38 } else {
39 clear();
40 }
41 }
42
43 void stringLite::truncate(t_size len) {
44 if (len < m_length) {
45 makeRoom(len);
46 if (len > 0) {
47 auto p = (char*)m_mem.ptr();
48 p[len] = 0;
49 m_ptr = p;
50 } else {
51 m_ptr = "";
52 }
53 m_length = len;
54 }
55 }
56
57 char* stringLite::lock_buffer(t_size p_requested_length) {
58 makeRoom(p_requested_length);
59 memset(m_mem.ptr(), 0, m_mem.size());
60 return (char*)m_mem.ptr();
61 }
62 void stringLite::unlock_buffer() {
63 auto p = (char*)m_mem.ptr();
64 m_ptr = p;
65 m_length = strlen(p);
66 }
67
68 void stringLite::clear() noexcept {
69 m_ptr = "";
70 m_length = 0;
71 if (!m_noShrink && m_mem.size() > alloc_minimum) m_mem.clear();
72 }
73 void stringLite::copy(stringLite const& other) {
74 set_string_nc(other.m_ptr, other.m_length);
75 // m_noShrink deliberately NOT transferred
76 }
77 void stringLite::move(stringLite& other) noexcept {
78 m_ptr = other.m_ptr;
79 m_length = other.m_length;
80 m_mem = std::move(other.m_mem);
81 m_noShrink = other.m_noShrink;
82 other._clear();
83 }
84 void stringLite::_clear() noexcept {
85 m_ptr = "";
86 m_length = 0;
87 }
88 void stringLite::makeRoom(size_t newLength) {
89 size_t size = newLength + 1; // null term
90 if (m_mem.size() < size) {
91 size_t target = (size / 2) * 3;
92 if (target < alloc_minimum) target = alloc_minimum;
93 m_mem.resize(target);
94 } else if (!m_noShrink && m_mem.size() / 2 >= size) {
95 size_t target = size;
96 if (target < alloc_minimum) target = alloc_minimum;
97 m_mem.resize(target);
98 }
99 }
100
101 stringLite const& stringLite::operator=(const string_base& src) {
102 set_string_nc(src.c_str(), src.length());
103 return *this;
104 }
105
106 stringLite::stringLite(const string_base& src) {
107 set_string_nc(src.c_str(), src.length());
108 }
109
110 stringLite::stringLite(string_part_ref const& ref) {
111 set_string_nc(ref.m_ptr, ref.m_len);
112 }
113 stringLite const& stringLite::operator=(const string_part_ref& ref) {
114 set_string_nc(ref.m_ptr, ref.m_len); return *this;
115 }
116
117 size_t stringLite::replace_nontext_chars(char p_replace) {
118 auto p = (char*)m_mem.ptr();
119 size_t ret = 0;
120 for (size_t w = 0; w < m_length; ++w) {
121 if ((uint8_t)p[w] < 32) { p[w] = p_replace; ++ret; }
122 }
123 return ret;
124 }
125 size_t stringLite::replace_char(unsigned c1, unsigned c2) {
126 if (c1 < 128 && c2 < 128) return replace_byte((char)c1, (char)c2);
127 else {
128 unsigned start = 0;
129 stringLite temp(get_ptr() + start);
130 truncate(start);
131 const char* ptr = temp;
132 t_size rv = 0;
133 while (*ptr)
134 {
135 unsigned test;
136 t_size delta = utf8_decode_char(ptr, test);
137 if (delta == 0 || test == 0) break;
138 if (test == c1) { test = c2; rv++; }
139 add_char(test);
140 ptr += delta;
141 }
142 return rv;
143 }
144 }
145
146 size_t stringLite::replace_byte(char c1, char c2) {
147 auto p = (char*)m_mem.ptr();
148 size_t ret = 0;
149 for (size_t w = 0; w < m_length; ++w) {
150 if (p[w] == c1) { p[w] = c2; ++ret; }
151 }
152 return ret;
153 }
154
155 void stringLite::set_char(size_t offset, char c) {
156
157 if (offset < m_length) {
158 if (c == 0) {
159 truncate(offset);
160 } else {
161 auto p = (char*)m_mem.ptr();
162 p[offset] = c;
163 }
164 }
165 }
166 void stringLite::prealloc(size_t s) {
167 m_noShrink = true;
168 makeRoom(s);
169 }
170
171 void stringLite::remove_chars(t_size first, t_size count) {
172 if (count == 0) return;
173 if (count == m_length) {
174 clear();
175 } else {
176 PFC_ASSERT(first + count > first);
177 PFC_ASSERT(first + count <= m_length);
178
179 auto p = (char*)m_mem.ptr();
180 size_t last = first + count;
181 size_t trailing = m_length - last;
182 memmove(p + first, p + last, trailing + 1);
183
184 size_t newLen = m_length - count;
185 makeRoom(newLen);
186 m_length = newLen;
187 m_ptr = (char*)m_mem.ptr();
188 }
189 }
190 void stringLite::insert_chars_nc(t_size first, const char* src, t_size count) {
191 if (count == 0) return;
192 if (first > m_length) first = m_length;
193 size_t trailing = m_length - first;
194 size_t newLen = m_length + count;
195 makeRoom(newLen);
196 auto p = (char*)m_mem.ptr();
197 memmove(p + first + count, p + first, trailing + 1);
198 memcpy(p + first, src, count);
199 m_length = newLen;
200 m_ptr = p;
201 }
202 void stringLite::insert_chars(t_size first, const char* src, t_size count) {
203 insert_chars_nc(first, src, strlen_max(src, count));
204 }
205 void stringLite::insert_chars(t_size first, const char* src) {
206 insert_chars_nc(first, src, strlen(src));
207 }
208 bool stringLite::equals(const stringLite& other) const noexcept {
209 return equals(*this, other);
210 }
211 bool stringLite::equals(const char* other) const noexcept {
212 return strcmp(c_str(), other) == 0;
213 }
214 bool stringLite::equals(const stringLite& v1, const stringLite& v2) noexcept {
215 if (v1.m_length != v2.m_length) return false;
216 return memcmp(v1.m_ptr, v2.m_ptr, v1.m_length) == 0;
217 }
218 bool stringLite::greater(const char* v1, size_t s1, const char* v2, size_t s2) noexcept {
219 if (s1 > s2) return true;
220 if (s1 < s2) return false;
221 return memcmp(v1, v2, s1) > 0;
222 }
223 bool stringLite::greater(const stringLite& v1, const stringLite& v2) noexcept {
224 return greater(v1.m_ptr, v1.m_length, v2.m_ptr, v2.m_length);
225 }
226 stringLite stringLite::lowerCase() const {
227 stringLite ret;
228 pfc::stringToLowerAppend(ret, this->c_str(), this->length());
229 return ret;
230 }
231 stringLite stringLite::upperCase() const {
232 stringLite ret;
233 pfc::stringToUpperAppend(ret, this->c_str(), this->length());
234 return ret;
235 }
236
237 stringLite stringLite::subString(t_size base) const {
238 if (base > length()) throw exception_overflow();
239 return string(c_str() + base);
240 }
241 stringLite stringLite::subString(t_size base, t_size count) const {
242 return string(c_str() + base, count);
243 }
244
245
246 t_size stringLite::indexOf(char c, t_size base) const {
247 return pfc::string_find_first(ptr(), c, base);
248 }
249 t_size stringLite::lastIndexOf(char c, t_size base) const {
250 return pfc::string_find_last(ptr(), c, base);
251 }
252 t_size stringLite::indexOf(stringp s, t_size base) const {
253 return pfc::string_find_first(ptr(), s, base);
254 }
255 t_size stringLite::lastIndexOf(stringp s, t_size base) const {
256 return pfc::string_find_last(ptr(), s, base);
257 }
258 t_size stringLite::indexOfAnyChar(stringp _s, t_size base) const {
259 string s(_s);
260 const t_size len = length();
261 const char* content = ptr();
262 for (t_size walk = base; walk < len; ++walk) {
263 if (s.contains(content[walk])) return walk;
264 }
265 return SIZE_MAX;
266 }
267 t_size stringLite::lastIndexOfAnyChar(stringp _s, t_size base) const {
268 string s(_s);
269 const char* content = ptr();
270 for (t_size _walk = min_t<size_t>(base, length()); _walk > 0; --_walk) {
271 const t_size walk = _walk - 1;
272 if (s.contains(content[walk])) return walk;
273 }
274 return SIZE_MAX;
275 }
276 bool stringLite::startsWith(char c) const {
277 return (*this)[0] == c;
278 }
279 bool stringLite::startsWith(stringp s) const {
280 const char* walk = ptr();
281 const char* subWalk = s;
282 for (;;) {
283 if (*subWalk == 0) return true;
284 if (*walk != *subWalk) return false;
285 walk++; subWalk++;
286 }
287 }
288 bool stringLite::endsWith(char c) const {
289 const t_size len = length();
290 if (len == 0) return false;
291 return ptr()[len - 1] == c;
292 }
293 bool stringLite::endsWith(stringp s) const {
294 const t_size len = length(), subLen = stringp_length(s);
295 if (subLen > len) return false;
296 return subString(len - subLen) == s;
297 }
298
299 char stringLite::firstChar() const {
300 return (*this)[0];
301 }
302 char stringLite::lastChar() const {
303 const t_size len = length();
304 return len > 0 ? (*this)[len - 1] : (char)0;
305 }
306 bool stringLite::contains(char c) const { return indexOf(c) != SIZE_MAX; }
307 bool stringLite::contains(stringp s) const { return indexOf(s) != SIZE_MAX; }
308 bool stringLite::containsAnyChar(stringp s) const { return indexOfAnyChar(s) != SIZE_MAX; }
309
310 stringLite stringLite::replace(stringp strOld, stringp strNew) const {
311 stringLite ret;
312 size_t status = this->replace_string_ex(ret, strOld, strNew);
313 if (status == 0) ret = *this;
314 return ret;
315 }
316
317 stringLite stringLite::trim(char c) const {
318 size_t base = 0, end = 0;
319 const char* p = c_str();
320 size_t walk = 0;
321 while (p[walk] == c) ++walk;
322 base = end = walk;
323 while (p[walk] != 0) {
324 if (p[walk] != c) end = walk + 1;
325 ++walk;
326 }
327 stringLite ret;
328 ret.set_string_nc(p + base, end - base);
329 return ret;
330 }
331
332 bool stringLite::operator==(const stringLite& other) const noexcept { return equals(*this, other); }
333 bool stringLite::operator!=(const stringLite& other) const noexcept { return !equals(*this, other); }
334 bool stringLite::operator==(const char* other) const noexcept { return strcmp(c_str(), other) == 0; }
335 bool stringLite::operator!=(const char* other) const noexcept { return strcmp(c_str(), other) != 0; }
336 bool stringLite::operator>(const stringLite& other) const noexcept { return greater(*this, other); }
337 bool stringLite::operator<(const stringLite& other) const noexcept { return greater(other, *this); }
338 bool stringLite::operator>(const char* other) const noexcept { return greater(m_ptr, m_length, other, strlen(other)); }
339 bool stringLite::operator<(const char* other) const noexcept { return greater(other, strlen(other), m_ptr, m_length); }
340 bool stringLite::operator>=(const stringLite& other) const noexcept { return !greater(other, *this); }
341 bool stringLite::operator<=(const stringLite& other) const noexcept { return !greater(*this, other); }
342 bool stringLite::operator>=(const char* other) const noexcept { return !greater(other, strlen(other), m_ptr, m_length); }
343 bool stringLite::operator<=(const char* other) const noexcept { return !greater(m_ptr, m_length, other, strlen(other)); }
344
345 }
346
347