aboutsummaryrefslogtreecommitdiff
path: root/common/str.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/str.cpp')
-rw-r--r--common/str.cpp87
1 files changed, 67 insertions, 20 deletions
diff --git a/common/str.cpp b/common/str.cpp
index ae3a965c70..c41e958349 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -75,7 +75,7 @@ void String::initWithCStr(const char *str, uint32 len) {
}
String::String(const String &str)
- : _size(str._size) {
+ : _size(str._size) {
if (str.isStorageIntern()) {
// String in internal storage: just copy it
memcpy(_storage, str._storage, _builtinCapacity);
@@ -91,7 +91,7 @@ String::String(const String &str)
}
String::String(char c)
- : _size(0), _str(_storage) {
+ : _size(0), _str(_storage) {
_storage[0] = c;
_storage[1] = 0;
@@ -132,24 +132,19 @@ void String::ensureCapacity(uint32 new_size, bool keep_old) {
if (!isShared && new_size < curCapacity)
return;
- if (isShared && new_size < _builtinCapacity) {
- // We share the storage, but there is enough internal storage: Use that.
- newStorage = _storage;
- newCapacity = _builtinCapacity;
- } else {
- // We need to allocate storage on the heap!
-
- // Compute a suitable new capacity limit
- // If the current capacity is sufficient we use the same capacity
- if (new_size < curCapacity)
- newCapacity = curCapacity;
- else
- newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1));
-
- // Allocate new storage
- newStorage = new char[newCapacity];
- assert(newStorage);
- }
+ // We need to allocate storage on the heap!
+
+ // Compute a suitable new capacity limit
+ // If the current capacity is sufficient we use the same capacity
+ if (new_size < curCapacity)
+ newCapacity = curCapacity;
+ else
+ newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1));
+
+ // Allocate new storage
+ newStorage = new char[newCapacity];
+ assert(newStorage);
+
// Copy old data if needed, elsewise reset the new storage.
if (keep_old) {
@@ -444,6 +439,58 @@ uint String::hash() const {
return hashit(c_str());
}
+void String::replace(uint32 pos, uint32 count, const String &str) {
+ replace(pos, count, str, 0, str._size);
+}
+
+void String::replace(uint32 pos, uint32 count, const char *str) {
+ replace(pos, count, str, 0, strlen(str));
+}
+
+void String::replace(iterator begin, iterator end, const String &str) {
+ replace(begin - _str, end - begin, str._str, 0, str._size);
+}
+
+void String::replace(iterator begin, iterator end, const char *str) {
+ replace(begin - _str, end - begin, str, 0, strlen(str));
+}
+
+void String::replace(uint32 posOri, uint32 countOri, const String &str,
+ uint32 posDest, uint32 countDest) {
+ replace(posOri, countOri, str._str, posDest, countDest);
+}
+
+void String::replace(uint32 posOri, uint32 countOri, const char *str,
+ uint32 posDest, uint32 countDest) {
+
+ ensureCapacity(_size + countDest - countOri, true);
+
+ // Prepare string for the replaced text.
+ if (countOri < countDest) {
+ uint32 offset = countDest - countOri; ///< Offset to copy the characters
+ uint32 newSize = _size + offset;
+ _size = newSize;
+
+ // Push the old characters to the end of the string
+ for (uint32 i = _size; i >= posOri + countDest; i--)
+ _str[i] = _str[i - offset];
+
+ } else if (countOri > countDest){
+ uint32 offset = countOri - countDest; ///< Number of positions that we have to pull back
+
+ // Pull the remainder string back
+ for (uint32 i = posOri + countDest; i < _size; i++)
+ _str[i] = _str[i + offset];
+
+ _size -= offset;
+ }
+
+ // Copy the replaced part of the string
+ for (uint32 i = 0; i < countDest; i++)
+ _str[posOri + i] = str[posDest + i];
+
+}
+
// static
String String::format(const char *fmt, ...) {
String output;