aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/ustr.cpp101
-rw-r--r--common/ustr.h32
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);