diff options
author | Max Horn | 2002-07-18 18:17:58 +0000 |
---|---|---|
committer | Max Horn | 2002-07-18 18:17:58 +0000 |
commit | c3e1f8779be5b03b58189553e4719ca21e018a45 (patch) | |
tree | 0c02a9d942dbce1a88765259b0ffd4b9bf3a1946 | |
parent | 37921ed5b7ce5a73192ced632693fd69e70e6592 (diff) | |
download | scummvm-rg350-c3e1f8779be5b03b58189553e4719ca21e018a45.tar.gz scummvm-rg350-c3e1f8779be5b03b58189553e4719ca21e018a45.tar.bz2 scummvm-rg350-c3e1f8779be5b03b58189553e4719ca21e018a45.zip |
String class now uses ref counting for its data, which allows efficient copying of strings
svn-id: r4588
-rw-r--r-- | util.cpp | 116 | ||||
-rw-r--r-- | util.h | 4 |
2 files changed, 75 insertions, 45 deletions
@@ -82,9 +82,9 @@ void ClearBlendCache(byte *palette, int weight) #pragma mark - - String::String(const char *str) { + _refCount = new int(1); _capacity = _len = strlen(str); _str = (char *)calloc(1, _capacity+1); memcpy(_str, str, _len+1); @@ -92,38 +92,58 @@ String::String(const char *str) String::String(const String &str) { + ++(*str._refCount); + + _refCount = str._refCount; _capacity = str._capacity; - _len = str._len; - _str = (char *)calloc(1, _capacity+1); - memcpy(_str, str._str, _len+1); + _len = str._capacity; + _str = str._str; } String::~String() { - if (_str) - free(_str); + decRefCount(); +} + +void String::decRefCount() +{ + --(*_refCount); + if (*_refCount <= 0) { + delete _refCount; + if (_str) + free(_str); + } } String& String::operator =(const char* str) { int len = strlen(str); - ensureCapacity(len, false); - - _len = len; - if (_str) + if (len > 0) { + ensureCapacity(len, false); + + _len = len; memcpy(_str, str, _len + 1); - + } if (_len > 0) { + decRefCount(); + + _refCount = new int(1); + _capacity = 0; + _len = 0; + _str = 0; + } return *this; } String& String::operator =(const String& str) { - int len = str._len; - ensureCapacity(len, false); + ++(*str._refCount); + + decRefCount(); - _len = len; - if (_str) - memcpy(_str, str._str, _len + 1); + _refCount = str._refCount; + _capacity = str._capacity; + _len = str._len; + _str = str._str; return *this; } @@ -131,31 +151,30 @@ String& String::operator =(const String& str) String& String::operator +=(const char* str) { int len = strlen(str); - ensureCapacity(_len + len, true); - - if (_str) - memcpy(_str + _len, str, len + 1); - _len += len; + if (len > 0) { + ensureCapacity(_len + len, true); + memcpy(_str + _len, str, len + 1); + _len += len; + } return *this; } String& String::operator +=(const String& str) { int len = str._len; - ensureCapacity(_len + len, true); - - if (_str && str._str) - memcpy(_str + _len, str._str, len + 1); - _len += len; + if (len > 0) { + ensureCapacity(_len + len, true); + memcpy(_str + _len, str._str, len + 1); + _len += len; + } return *this; } String& String::operator +=(char c) { - int len = _len + 1; - ensureCapacity(len, true); + ensureCapacity(_len + 1, true); _str[_len++] = c; _str[_len] = 0; @@ -165,33 +184,42 @@ String& String::operator +=(char c) void String::deleteLastChar() { if (_len > 0) { - _len--; - _str[_len]=0; + ensureCapacity(_len - 1, true); + _str[--_len] = 0; } } void String::clear() { - if (_str) - free(_str); - _capacity = 0; - _len = 0; - _str = 0; + if (_capacity) { + decRefCount(); + + _refCount = new int(1); + _capacity = 0; + _len = 0; + _str = 0; + } } void String::ensureCapacity(int new_len, bool keep_old) { - if (new_len <= _capacity) + // If there is not enough space, or if we are not the only owner + // of the current data, then we have to reallocate it. + if (new_len <= _capacity && *_refCount == 1) return; - char *old_str = _str; - _capacity = new_len + 32; - _str = (char *)calloc(1, _capacity+1); + int newCapacity = (new_len <= _capacity) ? _capacity : new_len + 32; + char *newStr = (char *)calloc(1, newCapacity+1); - if (old_str) { - if (keep_old) - memcpy(_str, old_str, _len+1); - free(old_str); - } + if (keep_old && _str) + memcpy(newStr, _str, _len + 1); + else + _len = 0; + + decRefCount(); + + _refCount = new int(1); + _capacity = newCapacity; + _str = newStr; } @@ -119,11 +119,12 @@ protected: class String { protected: + int *_refCount; int _capacity; int _len; char *_str; public: - String() : _capacity(0), _len(0), _str(0) {} + String() : _capacity(0), _len(0), _str(0) { _refCount = new int(1); } String(const char *str); String(const String &str); ~String(); @@ -144,6 +145,7 @@ public: protected: void ensureCapacity(int new_len, bool keep_old); + void decRefCount(); }; class StringList : public List<String> { |