diff options
author | Max Horn | 2008-09-03 17:39:18 +0000 |
---|---|---|
committer | Max Horn | 2008-09-03 17:39:18 +0000 |
commit | c3d7c908e8542ad2934d9cba0660a69aa00b2a01 (patch) | |
tree | 01903033f34a7437143a528476ef55f7934d42c0 | |
parent | e1918341afd6f7a8f1fa3db8838e582f8e8a511c (diff) | |
download | scummvm-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
-rw-r--r-- | common/str.cpp | 21 |
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; |