aboutsummaryrefslogtreecommitdiff
path: root/common/str.cpp
diff options
context:
space:
mode:
authorStephen Kennedy2008-07-30 14:40:54 +0000
committerStephen Kennedy2008-07-30 14:40:54 +0000
commita4ac44875e6bdb9fd0a5f5e69d6fc8cff0bd461c (patch)
tree29a0a9e87a6e195529f2b0c3dc3dc3f3434e5eb4 /common/str.cpp
parente2a2a672f591f36fb596bb6cb849978c70611c3e (diff)
parent81cb4931582f5839cca2958a634525ffb81a1714 (diff)
downloadscummvm-rg350-a4ac44875e6bdb9fd0a5f5e69d6fc8cff0bd461c.tar.gz
scummvm-rg350-a4ac44875e6bdb9fd0a5f5e69d6fc8cff0bd461c.tar.bz2
scummvm-rg350-a4ac44875e6bdb9fd0a5f5e69d6fc8cff0bd461c.zip
Merged revisions 33188-33189,33191-33193,33196,33198,33202-33203,33206,33210,33212,33218-33220,33222,33224-33226,33229-33243,33246,33248-33250,33252,33258-33261,33263,33266,33270,33272-33283,33285,33287-33290,33295-33298,33321,33325-33330,33332-33335,33337-33340,33342,33345,33347,33349-33350,33352-33357,33359-33367,33369-33371,33373,33375-33377,33379-33380,33383-33385,33387-33389,33392-33394,33400-33402,33404-33405,33407-33410,33412-33416,33418-33419,33425-33427,33432,33436-33438,33444,33446 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk svn-id: r33450
Diffstat (limited to 'common/str.cpp')
-rw-r--r--common/str.cpp152
1 files changed, 88 insertions, 64 deletions
diff --git a/common/str.cpp b/common/str.cpp
index a2e6e0c66d..5f8d4ffb7e 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -111,6 +111,74 @@ String::~String() {
decRefCount(_extern._refCount);
}
+void String::makeUnique() {
+ ensureCapacity(_len, true);
+}
+
+/**
+ * Ensure that enough storage is available to store at least new_len
+ * characters plus a null byte. In addition, if we currently share
+ * the storage with another string, unshare it, so that we can safely
+ * write to the storage.
+ */
+void String::ensureCapacity(uint32 new_len, bool keep_old) {
+ bool isShared;
+ uint32 curCapacity, newCapacity;
+ char *newStorage;
+ int *oldRefCount = _extern._refCount;
+
+ if (isStorageIntern()) {
+ isShared = false;
+ curCapacity = _builtinCapacity - 1;
+ } else {
+ isShared = (oldRefCount && *oldRefCount > 1);
+ curCapacity = _extern._capacity;
+ }
+
+ // Special case: If there is enough space, and we do not share
+ // the storage, then there is nothing to do.
+ if (!isShared && new_len <= curCapacity)
+ return;
+
+ if (isShared && new_len <= _builtinCapacity - 1) {
+ // We share the storage, but there is enough internal storage: Use that.
+ newStorage = _storage;
+ newCapacity = _builtinCapacity - 1;
+ } else {
+ // We need to allocate storage on the heap!
+
+ // Compute a suitable new capacity limit
+ newCapacity = computeCapacity(new_len);
+
+ // Allocate new storage
+ newStorage = (char *)malloc(newCapacity+1);
+ assert(newStorage);
+ }
+
+ // Copy old data if needed, elsewise reset the new storage.
+ if (keep_old) {
+ assert(_len <= newCapacity);
+ memcpy(newStorage, _str, _len + 1);
+ } else {
+ _len = 0;
+ newStorage[0] = 0;
+ }
+
+ // Release hold on the old storage ...
+ decRefCount(oldRefCount);
+
+ // ... in favor of the new storage
+ _str = newStorage;
+
+ if (!isStorageIntern()) {
+ // Set the ref count & capacity if we use an external storage.
+ // It is important to do this *after* copying any old content,
+ // else we would override data that has not yet been copied!
+ _extern._refCount = 0;
+ _extern._capacity = newCapacity;
+ }
+}
+
void String::incRefCount() const {
assert(!isStorageIntern());
if (_extern._refCount == 0) {
@@ -170,7 +238,8 @@ String &String::operator =(const String &str) {
}
String& String::operator =(char c) {
- ensureCapacity(1, false);
+ decRefCount(_extern._refCount);
+ _str = _storage;
_len = 1;
_str[0] = c;
_str[1] = 0;
@@ -253,10 +322,7 @@ void String::deleteLastChar() {
void String::deleteChar(uint32 p) {
assert(p < _len);
- // Call ensureCapacity to make sure we actually *own* the storage
- // to which _str points to -- we wouldn't want to modify a storage
- // which other string objects are sharing, after all.
- ensureCapacity(_len, true);
+ makeUnique();
while (p++ < _len)
_str[p-1] = _str[p];
_len--;
@@ -273,7 +339,7 @@ void String::clear() {
void String::setChar(char c, uint32 p) {
assert(p <= _len);
- ensureCapacity(_len, true);
+ makeUnique();
_str[p] = c;
}
@@ -288,78 +354,36 @@ void String::insertChar(char c, uint32 p) {
}
void String::toLowercase() {
- ensureCapacity(_len, true);
+ makeUnique();
for (uint32 i = 0; i < _len; ++i)
_str[i] = tolower(_str[i]);
}
void String::toUppercase() {
- ensureCapacity(_len, true);
+ makeUnique();
for (uint32 i = 0; i < _len; ++i)
_str[i] = toupper(_str[i]);
}
-/**
- * Ensure that enough storage is available to store at least new_len
- * characters plus a null byte. In addition, if we currently share
- * the storage with another string, unshare it, so that we can safely
- * write to the storage.
- */
-void String::ensureCapacity(uint32 new_len, bool keep_old) {
- bool isShared;
- uint32 curCapacity, newCapacity;
- char *newStorage;
- int *oldRefCount = _extern._refCount;
-
- if (isStorageIntern()) {
- isShared = false;
- curCapacity = _builtinCapacity - 1;
- } else {
- isShared = (oldRefCount && *oldRefCount > 1);
- curCapacity = _extern._capacity;
- }
-
- // Special case: If there is enough space, and we do not share
- // the storage, then there is nothing to do.
- if (!isShared && new_len <= curCapacity)
+void String::trim() {
+ if (_len == 0)
return;
- if (isShared && new_len <= _builtinCapacity - 1) {
- // We share the storage, but there is enough internal storage: Use that.
- newStorage = _storage;
- newCapacity = _builtinCapacity - 1;
- } else {
- // We need to allocate storage on the heap!
-
- // Compute a suitable new capacity limit
- newCapacity = computeCapacity(new_len);
+ makeUnique();
- // Allocate new storage
- newStorage = (char *)malloc(newCapacity+1);
- assert(newStorage);
- }
-
- // Copy old data if needed, elsewise reset the new storage.
- if (keep_old) {
- assert(_len <= newCapacity);
- memcpy(newStorage, _str, _len + 1);
- } else {
- _len = 0;
- newStorage[0] = 0;
- }
-
- // Release hold on the old storage ...
- decRefCount(oldRefCount);
+ // Trim trailing whitespace
+ while (_len >= 1 && isspace(_str[_len-1]))
+ _len--;
+ _str[_len] = 0;
- // ... in favor of the new storage
- _str = newStorage;
+ // Trim leading whitespace
+ char *t = _str;
+ while (isspace(*t))
+ t++;
- if (!isStorageIntern()) {
- // Set the ref count & capacity if we use an external storage.
- // It is important to do this *after* copying any old content,
- // else we would override data that has not yet been copied!
- _extern._refCount = 0;
- _extern._capacity = newCapacity;
+ if (t != _str) {
+ _len -= t - _str;
+ memmove(_str, t, _len + 1);
}
}