|
@@ -38,116 +38,120 @@
|
|
#include <godot_cpp/godot.hpp>
|
|
#include <godot_cpp/godot.hpp>
|
|
|
|
|
|
#include <cmath>
|
|
#include <cmath>
|
|
|
|
+#include <string>
|
|
|
|
|
|
namespace godot {
|
|
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 <typename L, typename R>
|
|
|
|
+_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 <class T>
|
|
|
|
+bool CharStringT<T>::operator<(const CharStringT<T> &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 <class T>
|
|
|
|
+CharStringT<T> &CharStringT<T>::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 <class T>
|
|
|
|
+void CharStringT<T>::operator=(const T *p_cstr) {
|
|
|
|
+ copy_from(p_cstr);
|
|
|
|
+}
|
|
|
|
|
|
-Char16String::~Char16String() {
|
|
|
|
- if (_data != nullptr) {
|
|
|
|
- memdelete_arr(_data);
|
|
|
|
|
|
+template <>
|
|
|
|
+const char *CharStringT<char>::get_data() const {
|
|
|
|
+ if (size()) {
|
|
|
|
+ return &operator[](0);
|
|
|
|
+ } else {
|
|
|
|
+ return "";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-int Char32String::length() const {
|
|
|
|
- return _length;
|
|
|
|
|
|
+template <>
|
|
|
|
+const char16_t *CharStringT<char16_t>::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<char32_t>::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<wchar_t>::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 <class T>
|
|
|
|
+void CharStringT<T>::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<T>::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<char>;
|
|
|
|
+template class CharStringT<char16_t>;
|
|
|
|
+template class CharStringT<char32_t>;
|
|
|
|
+template class CharStringT<wchar_t>;
|
|
|
|
|
|
// Custom String functions that are not part of bound API.
|
|
// 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.
|
|
// 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 {
|
|
CharString String::utf8() const {
|
|
int length = internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), nullptr, 0);
|
|
int length = internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), nullptr, 0);
|
|
int size = length + 1;
|
|
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 {
|
|
CharString String::ascii() const {
|
|
int length = internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), nullptr, 0);
|
|
int length = internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), nullptr, 0);
|
|
int size = length + 1;
|
|
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 {
|
|
Char16String String::utf16() const {
|
|
int length = internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), nullptr, 0);
|
|
int length = internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), nullptr, 0);
|
|
int size = length + 1;
|
|
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 {
|
|
Char32String String::utf32() const {
|
|
int length = internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), nullptr, 0);
|
|
int length = internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), nullptr, 0);
|
|
int size = length + 1;
|
|
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 {
|
|
CharWideString String::wide_string() const {
|
|
int length = internal::gdextension_interface_string_to_wide_chars(_native_ptr(), nullptr, 0);
|
|
int length = internal::gdextension_interface_string_to_wide_chars(_native_ptr(), nullptr, 0);
|
|
int size = length + 1;
|
|
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) {
|
|
String &String::operator=(const char *p_str) {
|