diff options
-rw-r--r-- | common/ustr.cpp | 101 | ||||
-rw-r--r-- | common/ustr.h | 32 |
2 files changed, 129 insertions, 4 deletions
diff --git a/common/ustr.cpp b/common/ustr.cpp index ecc91bb189..7f68f8a37a 100644 --- a/common/ustr.cpp +++ b/common/ustr.cpp @@ -72,6 +72,28 @@ U32String::U32String(const U32String &str) assert(_str != nullptr); } +U32String::U32String(const char *str) : _size(0), _str(_storage) { + if (str == nullptr) { + _storage[0] = 0; + _size = 0; + } else { + initWithCStr(str, strlen(str)); + } +} + +U32String::U32String(const char *str, uint32 len) : _size(0), _str(_storage) { + initWithCStr(str, len); +} + +U32String::U32String(const char *beginP, const char *endP) : _size(0), _str(_storage) { + assert(endP >= beginP); + initWithCStr(beginP, endP - beginP); +} + +U32String::U32String(const String &str) : _size(0) { + initWithCStr(str.c_str(), str.size()); +} + U32String::~U32String() { decRefCount(_extern._refCount); } @@ -98,6 +120,20 @@ U32String &U32String::operator=(const U32String &str) { return *this; } +U32String &U32String::operator=(const String &str) { + initWithCStr(str.c_str(), str.size()); + return *this; +} + +U32String &U32String::operator=(const value_type *str) { + return U32String::operator=(U32String(str)); +} + +U32String &U32String::operator=(const char *str) { + initWithCStr(str, strlen(str)); + return *this; +} + U32String &U32String::operator+=(const U32String &str) { if (&str == this) { return operator+=(U32String(str)); @@ -122,6 +158,38 @@ U32String &U32String::operator+=(value_type c) { return *this; } +bool U32String::operator==(const U32String &x) const { + return equals(x); +} + +bool U32String::operator==(const String &x) const { + return equals(x); +} + +bool U32String::operator==(const value_type *x) const { + return equals(U32String(x)); +} + +bool U32String::operator==(const char *x) const { + return equals(x); +} + +bool U32String::operator!=(const U32String &x) const { + return !equals(x); +} + +bool U32String::operator!=(const String &x) const { + return !equals(x); +} + +bool U32String::operator!=(const value_type *x) const { + return !equals(U32String(x)); +} + +bool U32String::operator!=(const char *x) const { + return !equals(x); +} + bool U32String::equals(const U32String &x) const { if (this == &x || _str == x._str) { return true; @@ -134,6 +202,17 @@ bool U32String::equals(const U32String &x) const { return !memcmp(_str, x._str, _size * sizeof(value_type)); } +bool U32String::equals(const String &x) const { + if (x.size() != _size) + return false; + + for (size_t idx = 0; idx < _size; ++idx) + if (_str[idx] != x[idx]) + return false; + + return true; +} + bool U32String::contains(value_type x) const { for (uint32 i = 0; i < _size; ++i) { if (_str[i] == x) { @@ -327,6 +406,28 @@ void U32String::initWithCStr(const value_type *str, uint32 len) { _str[len] = 0; } +void U32String::initWithCStr(const char *str, uint32 len) { + assert(str); + + _storage[0] = 0; + + _size = len; + + if (len >= _builtinCapacity) { + // Not enough internal storage, so allocate more + _extern._capacity = computeCapacity(len + 1); + _extern._refCount = nullptr; + _str = new value_type[_extern._capacity]; + assert(_str != nullptr); + } + + // Copy the string into the storage area + for (size_t idx = 0; idx < len; ++idx, ++str) + _str[idx] = *str; + + _str[len] = 0; +} + // This is a quick and dirty converter. // // More comprehensive one lives in wintermute/utils/convert_utf.cpp diff --git a/common/ustr.h b/common/ustr.h index d5e8f8298d..7f20207969 100644 --- a/common/ustr.h +++ b/common/ustr.h @@ -102,23 +102,46 @@ public: /** Construct a copy of the given string. */ U32String(const U32String &str); + /** Construct a new string from the given NULL-terminated C string. */ + explicit U32String(const char *str); + + /** Construct a new string containing exactly len characters read from address str. */ + U32String(const char *str, uint32 len); + + /** Construct a new string containing the characters between beginP (including) and endP (excluding). */ + U32String(const char *beginP, const char *endP); + + /** Construct a copy of the given string. */ + U32String(const String &str); + ~U32String(); U32String &operator=(const U32String &str); + U32String &operator=(const String &str); + U32String &operator=(const value_type *str); + U32String &operator=(const char *str); U32String &operator+=(const U32String &str); U32String &operator+=(value_type c); + bool operator==(const U32String &x) const; + bool operator==(const String &x) const; + bool operator==(const value_type *x) const; + bool operator==(const char *x) const; + bool operator!=(const U32String &x) const; + bool operator!=(const String &x) const; + bool operator!=(const value_type *x) const; + bool operator!=(const char *x) const; /** - * Equivalence comparison operator. - * @see equals + * Compares whether two U32String are the same based on memory comparison. + * This does *not* do comparison based on canonical equivalence. */ - bool operator==(const U32String &x) const { return equals(x); } + bool equals(const U32String &x) const; /** * Compares whether two U32String are the same based on memory comparison. * This does *not* do comparison based on canonical equivalence. */ - bool equals(const U32String &x) const; + bool equals(const String &x) const; bool contains(value_type x) const; @@ -191,6 +214,7 @@ private: void incRefCount() const; void decRefCount(int *oldRefCount); void initWithCStr(const value_type *str, uint32 len); + void initWithCStr(const char *str, uint32 len); }; U32String convertUtf8ToUtf32(const String &str); |