diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/foosdk/sdk/pfc/string-lite.cpp	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,347 @@
+#include "pfc-lite.h"
+#include "string-lite.h"
+#include "string_base.h"
+
+namespace pfc {
+	const unsigned alloc_minimum = 128;
+
+	void stringLite::add_string(const char* p_string, t_size p_string_size) {
+		add_string_nc(p_string, strlen_max(p_string, p_string_size));
+	}
+
+	void stringLite::add_string_nc(const char* ptr, size_t length) {
+		if (length > 0) {
+			const size_t base = m_length;
+			const size_t newLen = base + length;
+			makeRoom(newLen);
+			auto p = (char*)m_mem.ptr();
+			memcpy(p + base, ptr, length);
+			p[newLen] = 0;
+			m_length = newLen;
+			m_ptr = p;
+		}
+
+	}
+
+	void stringLite::set_string(const char* p_string, t_size p_length) {
+		set_string_nc(p_string, strlen_max(p_string, p_length));
+	}
+
+	void stringLite::set_string_nc(const char* ptr, size_t length) {
+		if (length > 0) {
+			makeRoom(length);
+			auto p = (char*)m_mem.ptr();
+			memcpy(p, ptr, length);
+			p[length] = 0;
+			m_ptr = p;
+			m_length = length;
+		} else {
+			clear();
+		}
+	}
+
+	void stringLite::truncate(t_size len) {
+		if (len < m_length) {
+			makeRoom(len);
+			if (len > 0) {
+				auto p = (char*)m_mem.ptr();
+				p[len] = 0;
+				m_ptr = p;
+			} else {
+				m_ptr = "";
+			}
+			m_length = len;
+		}
+	}
+
+	char* stringLite::lock_buffer(t_size p_requested_length) {
+		makeRoom(p_requested_length);
+		memset(m_mem.ptr(), 0, m_mem.size());
+		return (char*)m_mem.ptr();
+	}
+	void stringLite::unlock_buffer() {
+		auto p = (char*)m_mem.ptr();
+		m_ptr = p;
+		m_length = strlen(p);
+	}
+
+	void stringLite::clear() noexcept {
+		m_ptr = "";
+		m_length = 0;
+		if (!m_noShrink && m_mem.size() > alloc_minimum) m_mem.clear();
+	}
+	void stringLite::copy(stringLite const& other) {
+		set_string_nc(other.m_ptr, other.m_length);
+		// m_noShrink deliberately NOT transferred
+	}
+	void stringLite::move(stringLite& other) noexcept {
+		m_ptr = other.m_ptr;
+		m_length = other.m_length;
+		m_mem = std::move(other.m_mem);
+		m_noShrink = other.m_noShrink;
+		other._clear();
+	}
+	void stringLite::_clear() noexcept {
+		m_ptr = "";
+		m_length = 0;
+	}
+	void stringLite::makeRoom(size_t newLength) {
+		size_t size = newLength + 1; // null term
+		if (m_mem.size() < size) {
+			size_t target = (size / 2) * 3;
+			if (target < alloc_minimum) target = alloc_minimum;
+			m_mem.resize(target);
+		} else if (!m_noShrink && m_mem.size() / 2 >= size) {
+			size_t target = size;
+			if (target < alloc_minimum) target = alloc_minimum;
+			m_mem.resize(target);
+		}
+	}
+
+	stringLite const& stringLite::operator=(const string_base& src) {
+		set_string_nc(src.c_str(), src.length());
+		return *this;
+	}
+
+	stringLite::stringLite(const string_base& src) {
+		set_string_nc(src.c_str(), src.length());
+	}
+
+	stringLite::stringLite(string_part_ref const& ref) {
+		set_string_nc(ref.m_ptr, ref.m_len);
+	}
+	stringLite const& stringLite::operator=(const string_part_ref& ref) {
+		set_string_nc(ref.m_ptr, ref.m_len); return *this;
+	}
+
+	size_t stringLite::replace_nontext_chars(char p_replace) {
+		auto p = (char*)m_mem.ptr();
+		size_t ret = 0;
+		for (size_t w = 0; w < m_length; ++w) {
+			if ((uint8_t)p[w] < 32) { p[w] = p_replace; ++ret; }
+		}
+		return ret;
+	}
+	size_t stringLite::replace_char(unsigned c1, unsigned c2) {
+		if (c1 < 128 && c2 < 128) return replace_byte((char)c1, (char)c2);
+		else {
+			unsigned start = 0;
+			stringLite temp(get_ptr() + start);
+			truncate(start);
+			const char* ptr = temp;
+			t_size rv = 0;
+			while (*ptr)
+			{
+				unsigned test;
+				t_size delta = utf8_decode_char(ptr, test);
+				if (delta == 0 || test == 0) break;
+				if (test == c1) { test = c2; rv++; }
+				add_char(test);
+				ptr += delta;
+			}
+			return rv;
+		}
+	}
+
+	size_t stringLite::replace_byte(char c1, char c2) {
+		auto p = (char*)m_mem.ptr();
+		size_t ret = 0;
+		for (size_t w = 0; w < m_length; ++w) {
+			if (p[w] == c1) { p[w] = c2; ++ret; }
+		}
+		return ret;
+	}
+
+	void stringLite::set_char(size_t offset, char c) {
+
+		if (offset < m_length) {
+			if (c == 0) {
+				truncate(offset);
+			} else {
+				auto p = (char*)m_mem.ptr();
+				p[offset] = c;
+			}
+		}
+	}
+	void stringLite::prealloc(size_t s) {
+		m_noShrink = true;
+		makeRoom(s);
+	}
+
+	void stringLite::remove_chars(t_size first, t_size count) {
+		if (count == 0) return;
+		if (count == m_length) {
+			clear();
+		} else {
+			PFC_ASSERT(first + count > first);
+			PFC_ASSERT(first + count <= m_length);
+
+			auto p = (char*)m_mem.ptr();
+			size_t last = first + count;
+			size_t trailing = m_length - last;
+			memmove(p + first, p + last, trailing + 1);
+
+			size_t newLen = m_length - count;
+			makeRoom(newLen);
+			m_length = newLen;
+			m_ptr = (char*)m_mem.ptr();
+		}
+	}
+	void stringLite::insert_chars_nc(t_size first, const char* src, t_size count) {
+		if (count == 0) return;
+		if (first > m_length) first = m_length;
+		size_t trailing = m_length - first;
+		size_t newLen = m_length + count;
+		makeRoom(newLen);
+		auto p = (char*)m_mem.ptr();
+		memmove(p + first + count, p + first, trailing + 1);
+		memcpy(p + first, src, count);
+		m_length = newLen;
+		m_ptr = p;
+	}
+	void stringLite::insert_chars(t_size first, const char* src, t_size count) {
+		insert_chars_nc(first, src, strlen_max(src, count));
+	}
+	void stringLite::insert_chars(t_size first, const char* src) {
+		insert_chars_nc(first, src, strlen(src));
+	}
+	bool stringLite::equals(const stringLite& other) const noexcept {
+		return equals(*this, other);
+	}
+	bool stringLite::equals(const char* other) const noexcept {
+		return strcmp(c_str(), other) == 0;
+	}
+	bool stringLite::equals(const stringLite& v1, const stringLite& v2) noexcept {
+		if (v1.m_length != v2.m_length) return false;
+		return memcmp(v1.m_ptr, v2.m_ptr, v1.m_length) == 0;
+	}
+	bool stringLite::greater(const char* v1, size_t s1, const char* v2, size_t s2) noexcept {
+		if (s1 > s2) return true;
+		if (s1 < s2) return false;
+		return memcmp(v1, v2, s1) > 0;
+	}
+	bool stringLite::greater(const stringLite& v1, const stringLite& v2) noexcept {
+		return greater(v1.m_ptr, v1.m_length, v2.m_ptr, v2.m_length);
+	}
+	stringLite stringLite::lowerCase() const {
+		stringLite ret;
+		pfc::stringToLowerAppend(ret, this->c_str(), this->length());
+		return ret;
+	}
+	stringLite stringLite::upperCase() const {
+		stringLite ret;
+		pfc::stringToUpperAppend(ret, this->c_str(), this->length());
+		return ret;
+	}
+
+	stringLite stringLite::subString(t_size base) const {
+		if (base > length()) throw exception_overflow();
+		return string(c_str() + base);
+	}
+	stringLite stringLite::subString(t_size base, t_size count) const {
+		return string(c_str() + base, count);
+	}
+
+
+	t_size stringLite::indexOf(char c, t_size base) const {
+		return pfc::string_find_first(ptr(), c, base);
+	}
+	t_size stringLite::lastIndexOf(char c, t_size base) const {
+		return pfc::string_find_last(ptr(), c, base);
+	}
+	t_size stringLite::indexOf(stringp s, t_size base) const {
+		return pfc::string_find_first(ptr(), s, base);
+	}
+	t_size stringLite::lastIndexOf(stringp s, t_size base) const {
+		return pfc::string_find_last(ptr(), s, base);
+	}
+	t_size stringLite::indexOfAnyChar(stringp _s, t_size base) const {
+		string s(_s);
+		const t_size len = length();
+		const char* content = ptr();
+		for (t_size walk = base; walk < len; ++walk) {
+			if (s.contains(content[walk])) return walk;
+		}
+		return SIZE_MAX;
+	}
+	t_size stringLite::lastIndexOfAnyChar(stringp _s, t_size base) const {
+		string s(_s);
+		const char* content = ptr();
+		for (t_size _walk = min_t<size_t>(base, length()); _walk > 0; --_walk) {
+			const t_size walk = _walk - 1;
+			if (s.contains(content[walk])) return walk;
+		}
+		return SIZE_MAX;
+	}
+	bool stringLite::startsWith(char c) const {
+		return (*this)[0] == c;
+	}
+	bool stringLite::startsWith(stringp s) const {
+		const char* walk = ptr();
+		const char* subWalk = s;
+		for (;;) {
+			if (*subWalk == 0) return true;
+			if (*walk != *subWalk) return false;
+			walk++; subWalk++;
+		}
+	}
+	bool stringLite::endsWith(char c) const {
+		const t_size len = length();
+		if (len == 0) return false;
+		return ptr()[len - 1] == c;
+	}
+	bool stringLite::endsWith(stringp s) const {
+		const t_size len = length(), subLen = stringp_length(s);
+		if (subLen > len) return false;
+		return subString(len - subLen) == s;
+	}
+
+	char stringLite::firstChar() const {
+		return (*this)[0];
+	}
+	char stringLite::lastChar() const {
+		const t_size len = length();
+		return len > 0 ? (*this)[len - 1] : (char)0;
+	}
+	bool stringLite::contains(char c) const { return indexOf(c) != SIZE_MAX; }
+	bool stringLite::contains(stringp s) const { return indexOf(s) != SIZE_MAX; }
+	bool stringLite::containsAnyChar(stringp s) const { return indexOfAnyChar(s) != SIZE_MAX; }
+
+	stringLite stringLite::replace(stringp strOld, stringp strNew) const {
+		stringLite ret;
+		size_t status = this->replace_string_ex(ret, strOld, strNew);
+		if (status == 0) ret = *this;
+		return ret;
+	}
+
+	stringLite stringLite::trim(char c) const {
+		size_t base = 0, end = 0;
+		const char* p = c_str();
+		size_t walk = 0;
+		while (p[walk] == c) ++walk;
+		base = end = walk;
+		while (p[walk] != 0) {
+			if (p[walk] != c) end = walk + 1;
+			++walk;
+		}
+		stringLite ret;
+		ret.set_string_nc(p + base, end - base);
+		return ret;
+	}
+
+	bool stringLite::operator==(const stringLite& other) const noexcept { return equals(*this, other); }
+	bool stringLite::operator!=(const stringLite& other) const noexcept { return !equals(*this, other); }
+	bool stringLite::operator==(const char* other) const noexcept { return strcmp(c_str(), other) == 0; }
+	bool stringLite::operator!=(const char* other) const noexcept { return strcmp(c_str(), other) != 0; }
+	bool stringLite::operator>(const stringLite& other) const noexcept { return greater(*this, other); }
+	bool stringLite::operator<(const stringLite& other) const noexcept { return greater(other, *this); }
+	bool stringLite::operator>(const char* other) const noexcept { return greater(m_ptr, m_length, other, strlen(other)); }
+	bool stringLite::operator<(const char* other) const noexcept { return greater(other, strlen(other), m_ptr, m_length); }
+	bool stringLite::operator>=(const stringLite& other) const noexcept { return !greater(other, *this); }
+	bool stringLite::operator<=(const stringLite& other) const noexcept { return !greater(*this, other); }
+	bool stringLite::operator>=(const char* other) const noexcept { return !greater(other, strlen(other), m_ptr, m_length); }
+	bool stringLite::operator<=(const char* other) const noexcept { return !greater(m_ptr, m_length, other, strlen(other)); }
+
+}
+
+