#include "core/utils/ArrayString.hpp" #include #include #include #include "core/data/Array.hpp" #include "core/math/Math.hpp" #include "core/utils/Error.hpp" #include "core/utils/Utility.hpp" using BufferString = Core::BufferString; using Error = Core::Error; constexpr size_t stringLength(const c32* c) { const c32* i = c + 1; while(*(c++) != '\0') {} return static_cast(c - i); } using C32Buffer = Core::Array; static C32Buffer convertC32(c32 c) { C32Buffer buffer; size_t n = c32rtomb(buffer.begin(), c, nullptr); if(n >= buffer.getLength()) { buffer[0] = '?'; buffer[1] = '\0'; } else { buffer[n] = '\0'; } return buffer; } BufferString::BufferString(char* buffer, size_t bufferSize) : length(0), capacity(bufferSize <= 0 ? 0 : bufferSize - 1), data(buffer) { data[0] = '\0'; } BufferString& BufferString::operator=(const BufferString& other) { clear(); other.toString(*this); return *this; } bool BufferString::operator==(const char* s) const { return strcmp(data, s) == 0; } bool BufferString::operator==(const BufferString& other) const { return length == other.length && strcmp(data, other.data) == 0; } bool BufferString::operator!=(const char* s) const { return !((*this) == s); } bool BufferString::operator!=(const BufferString& other) const { return !((*this) == other); } char BufferString::operator[](size_t index) const { return data[index]; } size_t BufferString::getLength() const { return length; } size_t BufferString::getCapacity() const { return capacity; } BufferString& BufferString::append(char c) { if(length < capacity) { data[length++] = c; data[length] = '\0'; } return *this; } BufferString& BufferString::append(signed char c) { return append(static_cast(c)); } BufferString& BufferString::append(unsigned char c) { return append(static_cast(c)); } BufferString& BufferString::append(wchar_t c) { return append(static_cast(c)); } BufferString& BufferString::append(c32 c) { return append(static_cast(convertC32(c).begin())); } BufferString& BufferString::append(const char* s) { // stringLength as s could be some part of data for(size_t i = strlen(s); i > 0; i--) { append(*(s++)); } return *this; } BufferString& BufferString::append(const c32* s) { // stringLength as s could be some part of data for(size_t i = stringLength(s); i > 0; i--) { append(*(s++)); } return *this; } BufferString& BufferString::append(const signed char* s) { return append(reinterpret_cast(s)); } BufferString& BufferString::append(const unsigned char* s) { return append(reinterpret_cast(s)); } BufferString& BufferString::append(bool b) { return b ? append("true") : append("false"); } void BufferString::toString(BufferString& s) const { size_t l = length; // length changes if &s == this for(size_t i = 0; i < l; i++) { s.append(data[i]); } } void BufferString::clear() { length = 0; data[0] = '\0'; } void BufferString::print() const { Core::print(data); } void BufferString::printLine() const { Core::printLine(data); } bool BufferString::startsWith(const BufferString& other, size_t from) const { return length >= from + other.getLength() && strncmp(data + from, other.data, other.getLength()) == 0; } size_t BufferString::search(const BufferString& other, size_t from) const { char* f = strstr(data + from, other.data); return f == nullptr ? SIZE_MAX : static_cast(f - data); } bool BufferString::contains(const BufferString& other, size_t from) const { return search(other, from) != SIZE_MAX; } size_t BufferString::search(char u, size_t from) const { char* f = strchr(data + from, u); return f == nullptr ? SIZE_MAX : static_cast(f - data); } bool BufferString::contains(char u, size_t from) const { return search(u, from) != SIZE_MAX; } void BufferString::substring(BufferString& s, size_t from, size_t to) const { s.clear(); to = Math::min(to + 1, length); for(size_t i = from; i < to; i++) { s.append(data[i]); } } void BufferString::substring(BufferString& s, size_t from) const { substring(s, from, length - 1); } void BufferString::replace(BufferString& s, const BufferString& search, const BufferString& replace) { size_t i = 0; while(i < length) { if(startsWith(search, i)) { s.append(replace); i += search.getLength(); } else { s.append(data[i]); i++; } } *this = s; } void BufferString::replace(char search, char replace) { for(size_t i = 0; i < length; i++) { if(data[i] == search) { data[i] = replace; } } } BufferString::operator const char*() const { return data; }