|
@@ -661,6 +661,91 @@ struct VariantIndexedSetGet_Array {
|
|
|
static uint64_t get_indexed_size(const Variant *base) { return 0; }
|
|
|
};
|
|
|
|
|
|
+struct VariantIndexedSetGet_String {
|
|
|
+ static void get(const Variant *base, int64_t index, Variant *value, bool *oob) {
|
|
|
+ int64_t length = VariantGetInternalPtr<String>::get_ptr(base)->length();
|
|
|
+ if (index < 0) {
|
|
|
+ index += length;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= length) {
|
|
|
+ *oob = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ char32_t result = (*VariantGetInternalPtr<String>::get_ptr(base))[index];
|
|
|
+ *value = String(&result, 1);
|
|
|
+ *oob = false;
|
|
|
+ }
|
|
|
+ static void ptr_get(const void *base, int64_t index, void *member) {
|
|
|
+ /* avoid ptrconvert for performance*/
|
|
|
+ const String &v = *reinterpret_cast<const String *>(base);
|
|
|
+ if (index < 0) {
|
|
|
+ index += v.length();
|
|
|
+ }
|
|
|
+ OOB_TEST(index, v.length());
|
|
|
+ char32_t c = v[index];
|
|
|
+ PtrToArg<String>::encode(String(&c, 1), member);
|
|
|
+ }
|
|
|
+ static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) {
|
|
|
+ if (value->get_type() != Variant::STRING) {
|
|
|
+ *oob = false;
|
|
|
+ *valid = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ int64_t length = VariantGetInternalPtr<String>::get_ptr(base)->length();
|
|
|
+ if (index < 0) {
|
|
|
+ index += length;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= length) {
|
|
|
+ *oob = true;
|
|
|
+ *valid = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String *b = VariantGetInternalPtr<String>::get_ptr(base);
|
|
|
+ const String *v = VariantInternal::get_string(value);
|
|
|
+ if (v->length() == 0) {
|
|
|
+ b->remove(index);
|
|
|
+ } else {
|
|
|
+ b->set(index, v->get(0));
|
|
|
+ }
|
|
|
+ *oob = false;
|
|
|
+ *valid = true;
|
|
|
+ }
|
|
|
+ static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) {
|
|
|
+ int64_t length = VariantGetInternalPtr<String>::get_ptr(base)->length();
|
|
|
+ if (index < 0) {
|
|
|
+ index += length;
|
|
|
+ }
|
|
|
+ if (index < 0 || index >= length) {
|
|
|
+ *oob = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String *b = VariantGetInternalPtr<String>::get_ptr(base);
|
|
|
+ const String *v = VariantInternal::get_string(value);
|
|
|
+ if (v->length() == 0) {
|
|
|
+ b->remove(index);
|
|
|
+ } else {
|
|
|
+ b->set(index, v->get(0));
|
|
|
+ }
|
|
|
+ *oob = false;
|
|
|
+ }
|
|
|
+ static void ptr_set(void *base, int64_t index, const void *member) {
|
|
|
+ /* avoid ptrconvert for performance*/
|
|
|
+ String &v = *reinterpret_cast<String *>(base);
|
|
|
+ if (index < 0) {
|
|
|
+ index += v.length();
|
|
|
+ }
|
|
|
+ OOB_TEST(index, v.length());
|
|
|
+ const String &m = *reinterpret_cast<const String *>(member);
|
|
|
+ if (unlikely(m.length() == 0)) {
|
|
|
+ v.remove(index);
|
|
|
+ } else {
|
|
|
+ v.set(index, m.unicode_at(0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ static Variant::Type get_index_type() { return Variant::STRING; }
|
|
|
+ static uint64_t get_indexed_size(const Variant *base) { return VariantInternal::get_string(base)->length(); }
|
|
|
+};
|
|
|
+
|
|
|
#define INDEXED_SETGET_STRUCT_DICT(m_base_type) \
|
|
|
struct VariantIndexedSetGet_##m_base_type { \
|
|
|
static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \
|
|
@@ -758,6 +843,7 @@ static void register_indexed_member(Variant::Type p_type) {
|
|
|
void register_indexed_setters_getters() {
|
|
|
#define REGISTER_INDEXED_MEMBER(m_base_type) register_indexed_member<VariantIndexedSetGet_##m_base_type>(GetTypeInfo<m_base_type>::VARIANT_TYPE)
|
|
|
|
|
|
+ REGISTER_INDEXED_MEMBER(String);
|
|
|
REGISTER_INDEXED_MEMBER(Vector2);
|
|
|
REGISTER_INDEXED_MEMBER(Vector2i);
|
|
|
REGISTER_INDEXED_MEMBER(Vector3);
|