aboutsummaryrefslogtreecommitdiff
path: root/common/str.cpp
diff options
context:
space:
mode:
authorMax Horn2008-09-03 17:39:18 +0000
committerMax Horn2008-09-03 17:39:18 +0000
commitc3d7c908e8542ad2934d9cba0660a69aa00b2a01 (patch)
tree01903033f34a7437143a528476ef55f7934d42c0 /common/str.cpp
parente1918341afd6f7a8f1fa3db8838e582f8e8a511c (diff)
downloadscummvm-rg350-c3d7c908e8542ad2934d9cba0660a69aa00b2a01.tar.gz
scummvm-rg350-c3d7c908e8542ad2934d9cba0660a69aa00b2a01.tar.bz2
scummvm-rg350-c3d7c908e8542ad2934d9cba0660a69aa00b2a01.zip
Modified Common::Str to use exponential growth for its storage; also changed the meaning of 'capacity' from 'max length of string' to 'size of storage' (i.e. added one)
svn-id: r34313
Diffstat (limited to 'common/str.cpp')
-rw-r--r--common/str.cpp21
1 files changed, 10 insertions, 11 deletions
diff --git a/common/str.cpp b/common/str.cpp
index e70835a132..f24780cd6e 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -34,13 +34,12 @@ const String String::emptyString;
const char *String::emptyString = "";
#endif
-static int computeCapacity(int len) {
+static uint32 computeCapacity(uint32 len) {
// By default, for the capacity we use the nearest multiple of 32
// that leaves at least 16 chars of extra space (in case the string
// grows a bit).
- // Finally, we subtract 1 to compensate for the trailing zero byte.
len += 16;
- return ((len + 32 - 1) & ~0x1F) - 1;
+ return ((len + 32 - 1) & ~0x1F);
}
String::String(const char *str) : _size(0), _str(_storage) {
@@ -73,7 +72,7 @@ void String::initWithCStr(const char *str, uint32 len) {
// Not enough internal storage, so allocate more
_extern._capacity = computeCapacity(len);
_extern._refCount = 0;
- _str = (char *)malloc(_extern._capacity+1);
+ _str = (char *)malloc(_extern._capacity);
assert(_str != 0);
}
@@ -86,7 +85,7 @@ String::String(const String &str)
: _size(str._size), _str(str.isStorageIntern() ? _storage : str._str) {
if (str.isStorageIntern()) {
// String in internal storage: just copy it
- memcpy(_storage, str._storage, _builtinCapacity);
+ memcpy(_storage, str._storage, sizeof(_storage));
} else {
// String in external storage: use refcount mechanism
str.incRefCount();
@@ -129,7 +128,7 @@ void String::ensureCapacity(uint32 new_size, bool keep_old) {
if (isStorageIntern()) {
isShared = false;
- curCapacity = _builtinCapacity - 1;
+ curCapacity = _builtinCapacity;
} else {
isShared = (oldRefCount && *oldRefCount > 1);
curCapacity = _extern._capacity;
@@ -140,24 +139,24 @@ void String::ensureCapacity(uint32 new_size, bool keep_old) {
if (!isShared && new_size <= curCapacity)
return;
- if (isShared && new_size <= _builtinCapacity - 1) {
+ if (isShared && new_size < _builtinCapacity) {
// We share the storage, but there is enough internal storage: Use that.
newStorage = _storage;
- newCapacity = _builtinCapacity - 1;
+ newCapacity = _builtinCapacity;
} else {
// We need to allocate storage on the heap!
// Compute a suitable new capacity limit
- newCapacity = computeCapacity(new_size);
+ newCapacity = MAX(curCapacity * 2, computeCapacity(new_size));
// Allocate new storage
- newStorage = (char *)malloc(newCapacity+1);
+ newStorage = (char *)malloc(newCapacity);
assert(newStorage);
}
// Copy old data if needed, elsewise reset the new storage.
if (keep_old) {
- assert(_size <= newCapacity);
+ assert(_size < newCapacity);
memcpy(newStorage, _str, _size + 1);
} else {
_size = 0;