summaryrefslogtreecommitdiff
path: root/core/variant
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/variant_op.h24
-rw-r--r--core/variant/variant_parser.cpp73
-rw-r--r--core/variant/variant_parser.h32
3 files changed, 96 insertions, 33 deletions
diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h
index ec1ce67445..34858540ec 100644
--- a/core/variant/variant_op.h
+++ b/core/variant/variant_op.h
@@ -890,10 +890,12 @@ public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left);
*r_ret = do_mod(a, &r_valid);
- r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
- *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), nullptr);
+ bool valid = true;
+ String result = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), &valid);
+ ERR_FAIL_COND_MSG(!valid, result);
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), nullptr), r_ret);
@@ -913,10 +915,12 @@ public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left);
*r_ret = do_mod(a, *VariantGetInternalPtr<Array>::get_ptr(&p_right), &r_valid);
- r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
- *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), nullptr);
+ bool valid = true;
+ String result = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), &valid);
+ ERR_FAIL_COND_MSG(!valid, result);
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Array>::convert(right), nullptr), r_ret);
@@ -939,10 +943,12 @@ public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left);
*r_ret = do_mod(a, p_right.get_validated_object(), &r_valid);
- r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
- *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), right->get_validated_object(), nullptr);
+ bool valid = true;
+ String result = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), right->get_validated_object(), &valid);
+ ERR_FAIL_COND_MSG(!valid, result);
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Object *>::convert(right), nullptr), r_ret);
@@ -965,10 +971,12 @@ public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left);
*r_ret = do_mod(a, *VariantGetInternalPtr<T>::get_ptr(&p_right), &r_valid);
- r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
- *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), nullptr);
+ bool valid = true;
+ String result = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), &valid);
+ ERR_FAIL_COND_MSG(!valid, result);
+ *VariantGetInternalPtr<String>::get_ptr(r_ret) = result;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<T>::convert(right), nullptr), r_ret);
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index 17d41ca95e..9f500dbf5e 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -35,37 +35,76 @@
#include "core/os/keyboard.h"
#include "core/string/string_buffer.h"
-char32_t VariantParser::StreamFile::get_char() {
- return f->get_8();
+char32_t VariantParser::Stream::get_char() {
+ // is within buffer?
+ if (readahead_pointer < readahead_filled) {
+ return readahead_buffer[readahead_pointer++];
+ }
+
+ // attempt to readahead
+ readahead_filled = _read_buffer(readahead_buffer, READAHEAD_SIZE);
+ if (readahead_filled) {
+ readahead_pointer = 0;
+ } else {
+ // EOF
+ readahead_pointer = 1;
+ eof = true;
+ return 0;
+ }
+ return get_char();
}
bool VariantParser::StreamFile::is_utf8() const {
return true;
}
-bool VariantParser::StreamFile::is_eof() const {
- return f->eof_reached();
-}
+uint32_t VariantParser::StreamFile::_read_buffer(char32_t *p_buffer, uint32_t p_num_chars) {
+ // The buffer is assumed to include at least one character (for null terminator)
+ ERR_FAIL_COND_V(!p_num_chars, 0);
-char32_t VariantParser::StreamString::get_char() {
- if (pos > s.length()) {
- return 0;
- } else if (pos == s.length()) {
- // You need to try to read again when you have reached the end for EOF to be reported,
- // so this works the same as files (like StreamFile does)
- pos++;
- return 0;
- } else {
- return s[pos++];
+ uint8_t *temp = (uint8_t *)alloca(p_num_chars);
+ uint64_t num_read = f->get_buffer(temp, p_num_chars);
+ ERR_FAIL_COND_V(num_read == UINT64_MAX, 0);
+
+ // translate to wchar
+ for (uint32_t n = 0; n < num_read; n++) {
+ p_buffer[n] = temp[n];
}
+
+ // could be less than p_num_chars, or zero
+ return num_read;
}
bool VariantParser::StreamString::is_utf8() const {
return false;
}
-bool VariantParser::StreamString::is_eof() const {
- return pos > s.length();
+uint32_t VariantParser::StreamString::_read_buffer(char32_t *p_buffer, uint32_t p_num_chars) {
+ // The buffer is assumed to include at least one character (for null terminator)
+ ERR_FAIL_COND_V(!p_num_chars, 0);
+
+ int available = MAX(s.length() - pos, 0);
+ if (available >= (int)p_num_chars) {
+ const char32_t *src = s.ptr();
+ src += pos;
+ memcpy(p_buffer, src, p_num_chars * sizeof(char32_t));
+ pos += p_num_chars;
+
+ return p_num_chars;
+ }
+
+ // going to reach EOF
+ if (available) {
+ const char32_t *src = s.ptr();
+ src += pos;
+ memcpy(p_buffer, src, available * sizeof(char32_t));
+ pos += available;
+ }
+
+ // add a zero
+ p_buffer[available] = 0;
+
+ return available;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h
index 56b484c8bc..6b1d095ab5 100644
--- a/core/variant/variant_parser.h
+++ b/core/variant/variant_parser.h
@@ -38,34 +38,50 @@
class VariantParser {
public:
struct Stream {
- virtual char32_t get_char() = 0;
- virtual bool is_utf8() const = 0;
- virtual bool is_eof() const = 0;
+ private:
+ enum { READAHEAD_SIZE = 2048 };
+ char32_t readahead_buffer[READAHEAD_SIZE];
+ uint32_t readahead_pointer = 0;
+ uint32_t readahead_filled = 0;
+ bool eof = false;
+
+ protected:
+ virtual uint32_t _read_buffer(char32_t *p_buffer, uint32_t p_num_chars) = 0;
+ public:
char32_t saved = 0;
+ char32_t get_char();
+ virtual bool is_utf8() const = 0;
+ bool is_eof() const { return eof; }
+
Stream() {}
virtual ~Stream() {}
};
struct StreamFile : public Stream {
+ protected:
+ virtual uint32_t _read_buffer(char32_t *p_buffer, uint32_t p_num_chars) override;
+
+ public:
Ref<FileAccess> f;
- virtual char32_t get_char() override;
virtual bool is_utf8() const override;
- virtual bool is_eof() const override;
StreamFile() {}
};
struct StreamString : public Stream {
String s;
+
+ private:
int pos = 0;
- virtual char32_t get_char() override;
- virtual bool is_utf8() const override;
- virtual bool is_eof() const override;
+ protected:
+ virtual uint32_t _read_buffer(char32_t *p_buffer, uint32_t p_num_chars) override;
+ public:
+ virtual bool is_utf8() const override;
StreamString() {}
};