| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 | #include "core/utils/ArrayString.hpp"#include <limits.h>#include <stdlib.h>#include <uchar.h>#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<size_t>(c - i);}using C32Buffer = Core::Array<char, MB_LEN_MAX + 1>;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<char>(c));}BufferString& BufferString::append(unsigned char c) {    return append(static_cast<char>(c));}BufferString& BufferString::append(wchar_t c) {    return append(static_cast<c32>(c));}BufferString& BufferString::append(c32 c) {    return append(static_cast<const char*>(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<const char*>(s));}BufferString& BufferString::append(const unsigned char* s) {    return append(reinterpret_cast<const char*>(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<size_t>(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<size_t>(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;}
 |