Mercurial > foo_out_sdl
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 |
