From 4df112cd95840313600d0f850ec52a56d0961386 Mon Sep 17 00:00:00 2001 From: David Snopek Date: Tue, 20 Jun 2023 10:03:15 -0500 Subject: Attempt to fully implement CharString --- src/variant/char_string.cpp | 205 +++++++++++++++++++++++--------------------- 1 file changed, 107 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/variant/char_string.cpp b/src/variant/char_string.cpp index 0c8cd0f..856037c 100644 --- a/src/variant/char_string.cpp +++ b/src/variant/char_string.cpp @@ -38,116 +38,120 @@ #include #include +#include namespace godot { -int CharString::length() const { - return _length; -} - -const char *CharString::get_data() const { - return _data; -} - -CharString::CharString(CharString &&p_str) { - SWAP(_length, p_str._length); - SWAP(_data, p_str._data); -} +template +_FORCE_INLINE_ bool is_str_less(const L *l_ptr, const R *r_ptr) { + while (true) { + const char32_t l = *l_ptr; + const char32_t r = *r_ptr; + + if (l == 0 && r == 0) { + return false; + } else if (l == 0) { + return true; + } else if (r == 0) { + return false; + } else if (l < r) { + return true; + } else if (l > r) { + return false; + } -void CharString::operator=(CharString &&p_str) { - SWAP(_length, p_str._length); - SWAP(_data, p_str._data); + l_ptr++; + r_ptr++; + } } -CharString::CharString(const char *str, int length) : - _data(str), _length(length) {} - -CharString::~CharString() { - if (_data != nullptr) { - memdelete_arr(_data); +template +bool CharStringT::operator<(const CharStringT &p_right) const { + if (length() == 0) { + return p_right.length() != 0; } -} -int Char16String::length() const { - return _length; + return is_str_less(get_data(), p_right.get_data()); } -const char16_t *Char16String::get_data() const { - return _data; -} +template +CharStringT &CharStringT::operator+=(T p_char) { + const int lhs_len = length(); + resize(lhs_len + 2); -Char16String::Char16String(Char16String &&p_str) { - SWAP(_length, p_str._length); - SWAP(_data, p_str._data); -} + T *dst = ptrw(); + dst[lhs_len] = p_char; + dst[lhs_len + 1] = 0; -void Char16String::operator=(Char16String &&p_str) { - SWAP(_length, p_str._length); - SWAP(_data, p_str._data); + return *this; } -Char16String::Char16String(const char16_t *str, int length) : - _data(str), _length(length) {} +template +void CharStringT::operator=(const T *p_cstr) { + copy_from(p_cstr); +} -Char16String::~Char16String() { - if (_data != nullptr) { - memdelete_arr(_data); +template <> +const char *CharStringT::get_data() const { + if (size()) { + return &operator[](0); + } else { + return ""; } } -int Char32String::length() const { - return _length; +template <> +const char16_t *CharStringT::get_data() const { + if (size()) { + return &operator[](0); + } else { + return u""; + } } -const char32_t *Char32String::get_data() const { - return _data; +template <> +const char32_t *CharStringT::get_data() const { + if (size()) { + return &operator[](0); + } else { + return U""; + } } -Char32String::Char32String(Char32String &&p_str) { - SWAP(_length, p_str._length); - SWAP(_data, p_str._data); +template <> +const wchar_t *CharStringT::get_data() const { + if (size()) { + return &operator[](0); + } else { + return L""; + } } -void Char32String::operator=(Char32String &&p_str) { - SWAP(_length, p_str._length); - SWAP(_data, p_str._data); -} +template +void CharStringT::copy_from(const T *p_cstr) { + if (!p_cstr) { + resize(0); + return; + } -Char32String::Char32String(const char32_t *str, int length) : - _data(str), _length(length) {} + size_t len = std::char_traits::length(p_cstr); -Char32String::~Char32String() { - if (_data != nullptr) { - memdelete_arr(_data); + if (len == 0) { + resize(0); + return; } -} -int CharWideString::length() const { - return _length; -} + Error err = resize(++len); // include terminating null char -const wchar_t *CharWideString::get_data() const { - return _data; -} - -CharWideString::CharWideString(CharWideString &&p_str) { - SWAP(_length, p_str._length); - SWAP(_data, p_str._data); -} + ERR_FAIL_COND_MSG(err != OK, "Failed to copy C-string."); -void CharWideString::operator=(CharWideString &&p_str) { - SWAP(_length, p_str._length); - SWAP(_data, p_str._data); + memcpy(ptrw(), p_cstr, len); } -CharWideString::CharWideString(const wchar_t *str, int length) : - _data(str), _length(length) {} - -CharWideString::~CharWideString() { - if (_data != nullptr) { - memdelete_arr(_data); - } -} +template class CharStringT; +template class CharStringT; +template class CharStringT; +template class CharStringT; // Custom String functions that are not part of bound API. // It's easier to have them written in C++ directly than in a Python script that generates them. @@ -228,56 +232,61 @@ String rtoss(double p_val) { CharString String::utf8() const { int length = internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), nullptr, 0); int size = length + 1; - char *cstr = memnew_arr(char, size); - internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), cstr, length); + CharString str; + str.resize(size); + internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), str.ptrw(), length); - cstr[length] = '\0'; + str[length] = '\0'; - return CharString(cstr, length); + return str; } CharString String::ascii() const { int length = internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), nullptr, 0); int size = length + 1; - char *cstr = memnew_arr(char, size); - internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), cstr, length); + CharString str; + str.resize(size); + internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), str.ptrw(), length); - cstr[length] = '\0'; + str[length] = '\0'; - return CharString(cstr, length); + return str; } Char16String String::utf16() const { int length = internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), nullptr, 0); int size = length + 1; - char16_t *cstr = memnew_arr(char16_t, size); - internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), cstr, length); + Char16String str; + str.resize(size); + internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), str.ptrw(), length); - cstr[length] = '\0'; + str[length] = '\0'; - return Char16String(cstr, length); + return str; } Char32String String::utf32() const { int length = internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), nullptr, 0); int size = length + 1; - char32_t *cstr = memnew_arr(char32_t, size); - internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), cstr, length); + Char32String str; + str.resize(size); + internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), str.ptrw(), length); - cstr[length] = '\0'; + str[length] = '\0'; - return Char32String(cstr, length); + return str; } CharWideString String::wide_string() const { int length = internal::gdextension_interface_string_to_wide_chars(_native_ptr(), nullptr, 0); int size = length + 1; - wchar_t *cstr = memnew_arr(wchar_t, size); - internal::gdextension_interface_string_to_wide_chars(_native_ptr(), cstr, length); + CharWideString str; + str.resize(size); + internal::gdextension_interface_string_to_wide_chars(_native_ptr(), str.ptrw(), length); - cstr[length] = '\0'; + str[length] = '\0'; - return CharWideString(cstr, length); + return str; } String &String::operator=(const char *p_str) { -- cgit v1.2.3