From 916ddc2020cb0e0057667b40b6c6dd91e22d428f Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Mon, 5 Dec 2022 19:18:03 -0800 Subject: [PATCH] adding a few utility methods to blah string --- include/blah_string.h | 83 ++++++++++++++++++++++++++----------------- src/blah_string.cpp | 22 +++++++----- 2 files changed, 64 insertions(+), 41 deletions(-) diff --git a/include/blah_string.h b/include/blah_string.h index 395a731..9554b1b 100644 --- a/include/blah_string.h +++ b/include/blah_string.h @@ -105,33 +105,43 @@ namespace Blah return *this; } - StackString operator+(const BaseString& rhs) - { - StackString str(*this); - str += rhs; - return str; - } - - StackString operator+(const char* rhs) - { - StackString str(*this); - str += rhs; - return str; - } - - StackString operator+(const char& rhs) - { - StackString str(*this); - str += rhs; - return str; - } - StackString substr(int start, int len = 0) const { if (len == 0) len = length() - start; return StackString(cstr() + start, cstr() + start + len); } + StackString replace(const StackString& term, const StackString& replacement) const + { + StackString result; + int term_length = term.length(); + for (int i = 0, n = length() - term_length; i < n; i ++) + { + bool match = false; + for (int j = 0; j < term_length; j ++) + if (operator[](i) != term[j]) { match = true; break; } + if (match) + { + result.append(replacement); + i += term_length - 1; + } + else + result.append(operator[](i)); + } + return result; + } + + void set_length(int new_length) + { + new_length++; + if (s_len() < new_length) + append('\0', new_length - s_len()); + else if (m_heap_buffer.size() > 0) + m_heap_buffer.erase(new_length, s_len() - new_length); + else + m_stack_buffer.erase(new_length, s_len() - new_length); + } + StackString trim() const { if (length() > 0) @@ -256,29 +266,36 @@ namespace Blah StackVector m_stack_buffer; }; - template - StackString operator+(const StackString& lhs, const BaseString& rhs) + template + StackString operator+(const StackString& lhs, const StackString& rhs) { - StackString str(lhs); - str += rhs; - return str; + StackString str(lhs); str.append(rhs); return str; + } + + template + StackString operator+(const char* lhs, const StackString& rhs) + { + StackString str(lhs); str.append(rhs); return str; } template StackString operator+(const StackString& lhs, const char* rhs) { - StackString str(lhs); - str += rhs; - return str; + StackString str(lhs); str.append(rhs); return str; } - + template StackString operator+(const StackString& lhs, const char& rhs) { - StackString str(lhs); - str += rhs; - return str; + StackString str(lhs); str.append(rhs); return str; } + + template + StackString operator+(const char& lhs, const StackString& rhs) + { + StackString str(lhs); str.append(rhs); return str; + } + // Stores enough for an empty string on the stack, and afterwards allocates on the heap using HeapString = StackString<1>; diff --git a/src/blah_string.cpp b/src/blah_string.cpp index 60ca76d..5ec3bfe 100644 --- a/src/blah_string.cpp +++ b/src/blah_string.cpp @@ -20,30 +20,36 @@ namespace constexpr bool blah_compare_ignore_case(char a, char b) { return blah_to_lower(a) == blah_to_lower(b); }; constexpr bool blah_compare_with_case(char a, char b) { return a == b; }; + + #define BLAH_ASSERT_INPUT_STRING(input) \ + BLAH_ASSERT(!(input >= cstr() && input < cstr() + length()), "Assigning string to itself is bad news!") } -void BaseString::assign(const char* cstr, const char* cstr_end) +void BaseString::assign(const char* cstr_start, const char* cstr_end) { + BLAH_ASSERT_INPUT_STRING(cstr_start); s_clear(); - append(cstr, cstr_end); + append(cstr_start, cstr_end); } -void BaseString::append(const char* cstr, const char* cstr_end) +void BaseString::append(const char* cstr_start, const char* cstr_end) { + BLAH_ASSERT_INPUT_STRING(cstr_start); + // make sure values are valid - if (cstr == nullptr || *cstr == '\0') + if (cstr_start == nullptr || *cstr_start == '\0') return; if (cstr_end == nullptr) - cstr_end = cstr + blah_strlen(cstr); + cstr_end = cstr_start + blah_strlen(cstr_start); // reserve (+1 for null-terminator) auto len = length(); - s_ensure(len + (cstr_end - cstr) + 1); + s_ensure(len + (cstr_end - cstr_start) + 1); // copy value over to our buffer char* dst = s_ptr() + len; - while (cstr < cstr_end) - *(dst++) = *(cstr++); + while (cstr_start < cstr_end) + *(dst++) = *(cstr_start++); } void BaseString::append(const u16* u16_cstr, const u16* u16_cstr_end, bool swap_endian)