[Scummvm-cvs-logs] SF.net SVN: scummvm:[34313] scummvm/trunk/common/str.cpp

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Wed Sep 3 19:39:21 CEST 2008


Revision: 34313
          http://scummvm.svn.sourceforge.net/scummvm/?rev=34313&view=rev
Author:   fingolfin
Date:     2008-09-03 17:39:18 +0000 (Wed, 03 Sep 2008)

Log Message:
-----------
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)

Modified Paths:
--------------
    scummvm/trunk/common/str.cpp

Modified: scummvm/trunk/common/str.cpp
===================================================================
--- scummvm/trunk/common/str.cpp	2008-09-03 17:07:13 UTC (rev 34312)
+++ scummvm/trunk/common/str.cpp	2008-09-03 17:39:18 UTC (rev 34313)
@@ -34,13 +34,12 @@
 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 @@
 		// 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 @@
  : _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 @@
 
 	if (isStorageIntern()) {
 		isShared = false;
-		curCapacity = _builtinCapacity - 1;
+		curCapacity = _builtinCapacity;
 	} else {
 		isShared = (oldRefCount && *oldRefCount > 1);
 		curCapacity = _extern._capacity;
@@ -140,24 +139,24 @@
 	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;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list