#include "utils/String.h" #include #include Core::String::String() : length(0), hash(0) { data[0] = '\0'; } bool Core::String::operator==(const char* s) const { return *this == String(s); } bool Core::String::operator==(const String& other) const { if(length != other.length) { return false; } for(int i = 0; i < length; i++) { if(data[i] != other[i]) { return false; } } return true; } bool Core::String::operator!=(const char* s) const { return !((*this) == s); } bool Core::String::operator!=(const String& other) const { return !((*this) == other); } u32 Core::String::operator[](int index) const { return data[index]; } int Core::String::getLength() const { return length; } Core::String& Core::String::append(char c) { return appendUnicode(static_cast(c < 0 ? '?' : c)); } Core::String& Core::String::append(signed char c) { return appendUnicode(static_cast(c < 0 ? '?' : c)); } Core::String& Core::String::append(unsigned char c) { return appendUnicode(c); } static u32 read(const char*& s) { if(*s == '\0') { return 0; } return static_cast(*(s++)); } Core::String& Core::String::append(const char* s) { while(true) { u32 u = read(s); if(u == 0) { break; } else if((u & 0xE0) == 0xC0) { u = ((u & 0x1F) << 6) | (read(s) & 0x3F); } else if((u & 0xF0) == 0xE0) { u = ((u & 0xF) << 12) | ((read(s) & 0x3F) << 6); u |= read(s) & 0x3F; } else if((u & 0xF8) == 0xF0) { u = ((u & 0x07) << 18) | ((read(s) & 0x3F) << 12); u |= (read(s) & 0x3F) << 6; u |= read(s) & 0x3F; } appendUnicode(u); } return *this; } Core::String& Core::String::append(const signed char* s) { return append(reinterpret_cast(s)); } Core::String& Core::String::append(const unsigned char* s) { return append(reinterpret_cast(s)); } Core::String& Core::String::append(signed short s) { return appendFormat("%hd", s); } Core::String& Core::String::append(unsigned short s) { return appendFormat("%hu", s); } Core::String& Core::String::append(signed int i) { return appendFormat("%d", i); } Core::String& Core::String::append(unsigned int i) { return appendFormat("%u", i); } Core::String& Core::String::append(signed long l) { return appendFormat("%ld", l); } Core::String& Core::String::append(unsigned long l) { return appendFormat("%lu", l); } Core::String& Core::String::append(signed long long ll) { return appendFormat("%lld", ll); } Core::String& Core::String::append(unsigned long long ll) { return appendFormat("%llu", ll); } Core::String& Core::String::append(float f) { return appendFormat("%.2f", static_cast(f)); } Core::String& Core::String::append(double d) { return appendFormat("%.2f", d); } Core::String& Core::String::append(long double ld) { return appendFormat("%.2Lf", ld); } Core::String& Core::String::append(bool b) { return b ? append("true") : append("false"); } Core::String& Core::String::appendUnicode(u32 c) { if(length < DATA_LENGTH) { data[length++] = c; addToHash(c); } return *this; } check_format(2, 3) Core::String& Core::String::appendFormat(const char* format, ...) { constexpr int BUFFER_SIZE = 64; char buffer[BUFFER_SIZE]; va_list args; va_start(args, format); vsnprintf(buffer, BUFFER_SIZE, format, args); va_end(args); append(static_cast(buffer)); return *this; } void Core::String::toString(String& s) const { if(this == &s) { return; } for(int i = 0; i < length; i++) { s.appendUnicode(data[i]); } } Core::String& Core::String::clear() { length = 0; hash = 0; data[0] = '\0'; return *this; } Hash Core::String::hashCode() const { return hash; } void Core::String::print() const { for(int i = 0; i < length; i++) { u32 c = data[i]; if(c < (1 << 7)) { putchar(static_cast(c & 0x7F)); } else if(c < (1 << 11)) { putchar(static_cast(((c >> 6) & 0x1F) | 0xC0)); putchar(static_cast(((c >> 0) & 0x3F) | 0x80)); } else if(c < (1 << 16)) { putchar(static_cast(((c >> 12) & 0x0F) | 0xE0)); putchar(static_cast(((c >> 6) & 0x3F) | 0x80)); putchar(static_cast(((c >> 0) & 0x3F) | 0x80)); } else if(c < (1 << 21)) { putchar(static_cast(((c >> 18) & 0x07) | 0xF0)); putchar(static_cast(((c >> 12) & 0x3F) | 0x80)); putchar(static_cast(((c >> 6) & 0x3F) | 0x80)); putchar(static_cast(((c >> 0) & 0x3F) | 0x80)); } } } void Core::String::printLine() const { print(); putchar('\n'); } void Core::String::addToHash(u32 u) { hash = static_cast(2120251889) * hash + static_cast(u); } bool operator==(const char* cs, const Core::String& s) { return s == cs; } bool operator!=(const char* cs, const Core::String& s) { return s != cs; }