diff options
Diffstat (limited to 'core/string_buffer.h')
-rw-r--r-- | core/string_buffer.h | 88 |
1 files changed, 86 insertions, 2 deletions
diff --git a/core/string_buffer.h b/core/string_buffer.h index f0ead66bb8..7e9b151bea 100644 --- a/core/string_buffer.h +++ b/core/string_buffer.h @@ -32,13 +32,14 @@ #define STRING_BUFFER_H #include "ustring.h" +#include <string.h> +template <int SHORT_BUFFER_SIZE = 64> class StringBuffer { - static const int SHORT_BUFFER_SIZE = 64; CharType short_buffer[SHORT_BUFFER_SIZE]; String buffer; - int string_length = 0; + int string_length; _FORCE_INLINE_ CharType *current_buffer_ptr() { return static_cast<Vector<CharType> &>(buffer).empty() ? short_buffer : buffer.ptrw(); @@ -78,6 +79,89 @@ public: _FORCE_INLINE_ operator String() { return as_string(); } + + StringBuffer() { + string_length = 0; + } }; +template <int SHORT_BUFFER_SIZE> +StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(CharType p_char) { + reserve(string_length + 2); + current_buffer_ptr()[string_length++] = p_char; + return *this; +} + +template <int SHORT_BUFFER_SIZE> +StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(const String &p_string) { + return append(p_string.c_str()); +} + +template <int SHORT_BUFFER_SIZE> +StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(const char *p_str) { + int len = strlen(p_str); + reserve(string_length + len + 1); + + CharType *buf = current_buffer_ptr(); + for (const char *c_ptr = p_str; *c_ptr; ++c_ptr) { + buf[string_length++] = *c_ptr; + } + return *this; +} + +template <int SHORT_BUFFER_SIZE> +StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(const CharType *p_str, int p_clip_to_len) { + int len = 0; + while ((p_clip_to_len < 0 || len < p_clip_to_len) && p_str[len]) { + ++len; + } + reserve(string_length + len + 1); + memcpy(&(current_buffer_ptr()[string_length]), p_str, len * sizeof(CharType)); + string_length += len; + + return *this; +} + +template <int SHORT_BUFFER_SIZE> +StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::reserve(int p_size) { + if (p_size < SHORT_BUFFER_SIZE || p_size < buffer.size()) + return *this; + + bool need_copy = string_length > 0 && buffer.empty(); + buffer.resize(next_power_of_2(p_size)); + if (need_copy) { + memcpy(buffer.ptrw(), short_buffer, string_length * sizeof(CharType)); + } + + return *this; +} + +template <int SHORT_BUFFER_SIZE> +int StringBuffer<SHORT_BUFFER_SIZE>::length() const { + return string_length; +} + +template <int SHORT_BUFFER_SIZE> +String StringBuffer<SHORT_BUFFER_SIZE>::as_string() { + current_buffer_ptr()[string_length] = '\0'; + if (buffer.empty()) { + return String(short_buffer); + } else { + buffer.resize(string_length + 1); + return buffer; + } +} + +template <int SHORT_BUFFER_SIZE> +double StringBuffer<SHORT_BUFFER_SIZE>::as_double() { + current_buffer_ptr()[string_length] = '\0'; + return String::to_double(current_buffer_ptr()); +} + +template <int SHORT_BUFFER_SIZE> +int64_t StringBuffer<SHORT_BUFFER_SIZE>::as_int() { + current_buffer_ptr()[string_length] = '\0'; + return String::to_int(current_buffer_ptr()); +} + #endif |