]> granicus.if.org Git - icu/commitdiff
ICU-11317 split out a new doAppend() from the more general doReplace(), each optimizi...
authorMarkus Scherer <markus.icu@gmail.com>
Thu, 18 Jun 2015 14:09:54 +0000 (14:09 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Thu, 18 Jun 2015 14:09:54 +0000 (14:09 +0000)
X-SVN-Rev: 37601

icu4c/source/common/unicode/unistr.h
icu4c/source/common/unistr.cpp

index eda044f14c0f26cba61a2661c839714c3558d68e..93e3048aaed4e24a3042a96e754e3cce29267f36 100644 (file)
@@ -3494,6 +3494,9 @@ private:
                int32_t srcStart,
                int32_t srcLength);
 
+  UnicodeString& doAppend(const UnicodeString& src, int32_t srcStart, int32_t srcLength);
+  UnicodeString& doAppend(const UChar *srcChars, int32_t srcStart, int32_t srcLength);
+
   UnicodeString& doReverse(int32_t start,
                int32_t length);
 
@@ -4529,30 +4532,30 @@ inline UnicodeString&
 UnicodeString::append(const UnicodeString& srcText,
               int32_t srcStart,
               int32_t srcLength)
-{ return doReplace(length(), 0, srcText, srcStart, srcLength); }
+{ return doAppend(srcText, srcStart, srcLength); }
 
 inline UnicodeString&
 UnicodeString::append(const UnicodeString& srcText)
-{ return doReplace(length(), 0, srcText, 0, srcText.length()); }
+{ return doAppend(srcText, 0, srcText.length()); }
 
 inline UnicodeString&
 UnicodeString::append(const UChar *srcChars,
               int32_t srcStart,
               int32_t srcLength)
-{ return doReplace(length(), 0, srcChars, srcStart, srcLength); }
+{ return doAppend(srcChars, srcStart, srcLength); }
 
 inline UnicodeString&
 UnicodeString::append(const UChar *srcChars,
               int32_t srcLength)
-{ return doReplace(length(), 0, srcChars, 0, srcLength); }
+{ return doAppend(srcChars, 0, srcLength); }
 
 inline UnicodeString&
 UnicodeString::append(UChar srcChar)
-{ return doReplace(length(), 0, &srcChar, 0, 1); }
+{ return doAppend(&srcChar, 0, 1); }
 
 inline UnicodeString&
 UnicodeString::operator+= (UChar ch)
-{ return doReplace(length(), 0, &ch, 0, 1); }
+{ return doAppend(&ch, 0, 1); }
 
 inline UnicodeString&
 UnicodeString::operator+= (UChar32 ch) {
@@ -4561,7 +4564,7 @@ UnicodeString::operator+= (UChar32 ch) {
 
 inline UnicodeString&
 UnicodeString::operator+= (const UnicodeString& srcText)
-{ return doReplace(length(), 0, srcText, 0, srcText.length()); }
+{ return doAppend(srcText, 0, srcText.length()); }
 
 inline UnicodeString&
 UnicodeString::insert(int32_t start,
index 4b4a53eafba67c48654e51b10b7373dd7fb36c32..3b4bbffb8a1e7c457421e9d766e0b006e854f5cc 100644 (file)
@@ -208,13 +208,13 @@ UnicodeString::UnicodeString(UChar32 ch) {
 
 UnicodeString::UnicodeString(const UChar *text) {
   fUnion.fFields.fLengthAndFlags = kShortString;
-  doReplace(0, 0, text, 0, -1);
+  doAppend(text, 0, -1);
 }
 
 UnicodeString::UnicodeString(const UChar *text,
                              int32_t textLength) {
   fUnion.fFields.fLengthAndFlags = kShortString;
-  doReplace(0, 0, text, 0, textLength);
+  doAppend(text, 0, textLength);
 }
 
 UnicodeString::UnicodeString(UBool isTerminated,
@@ -1357,8 +1357,8 @@ UnicodeString::append(UChar32 srcChar) {
   UBool isError = FALSE;
   U16_APPEND(buffer, _length, U16_MAX_LENGTH, srcChar, isError);
   // We test isError so that the compiler does not complain that we don't.
-  // If isError then _length==0 which turns the doReplace() into a no-op anyway.
-  return isError ? *this : doReplace(length(), 0, buffer, 0, _length);
+  // If isError then _length==0 which turns the doAppend() into a no-op anyway.
+  return isError ? *this : doAppend(buffer, 0, _length);
 }
 
 UnicodeString&
@@ -1368,17 +1368,12 @@ UnicodeString::doReplace( int32_t start,
               int32_t srcStart,
               int32_t srcLength)
 {
-  if(!src.isBogus()) {
-    // pin the indices to legal values
-    src.pinIndices(srcStart, srcLength);
+  // pin the indices to legal values
+  src.pinIndices(srcStart, srcLength);
 
-    // get the characters from src
-    // and replace the range in ourselves with them
-    return doReplace(start, length, src.getArrayStart(), srcStart, srcLength);
-  } else {
-    // remove the range
-    return doReplace(start, length, 0, 0, 0);
-  }
+  // get the characters from src
+  // and replace the range in ourselves with them
+  return doReplace(start, length, src.getArrayStart(), srcStart, srcLength);
 }
 
 UnicodeString&
@@ -1414,6 +1409,10 @@ UnicodeString::doReplace(int32_t start,
     }
   }
 
+  if(start == oldLength) {
+    return doAppend(srcChars, srcStart, srcLength);
+  }
+
   if(srcChars == 0) {
     srcStart = srcLength = 0;
   } else if(srcLength < 0) {
@@ -1421,42 +1420,13 @@ UnicodeString::doReplace(int32_t start,
     srcLength = u_strlen(srcChars + srcStart);
   }
 
-  // calculate the size of the string after the replace
-  int32_t newLength;
-
-  // optimize append() onto a large-enough, owned string
-  if(start >= oldLength) {
-    if(srcLength == 0) {
-      return *this;
-    }
-    newLength = oldLength + srcLength;
-    if(newLength <= getCapacity() && isBufferWritable()) {
-      UChar *oldArray = getArrayStart();
-      // Do not copy characters when
-      //   UChar *buffer=str.getAppendBuffer(...);
-      // is followed by
-      //   str.append(buffer, length);
-      // or
-      //   str.appendString(buffer, length)
-      // or similar.
-      if(srcChars + srcStart != oldArray + start || start > oldLength) {
-        us_arrayCopy(srcChars, srcStart, oldArray, oldLength, srcLength);
-      }
-      setLength(newLength);
-      return *this;
-    } else {
-      // pin the indices to legal values
-      start = oldLength;
-      length = 0;
-    }
-  } else {
-    // pin the indices to legal values
-    pinIndices(start, length);
+  // pin the indices to legal values
+  pinIndices(start, length);
 
-    newLength = oldLength - length + srcLength;
-  }
+  // calculate the size of the string after the replace
+  int32_t newLength = oldLength - length + srcLength;
 
-  // the following may change fArray but will not copy the current contents;
+  // cloneArrayIfNeeded(doCopyArray=FALSE) may change fArray but will not copy the current contents;
   // therefore we need to keep the current fArray
   UChar oldStackBuffer[US_STACKBUF_SIZE];
   UChar *oldArray;
@@ -1507,6 +1477,54 @@ UnicodeString::doReplace(int32_t start,
   return *this;
 }
 
+// Versions of doReplace() only for append() variants.
+// doReplace() and doAppend() optimize for different cases.
+
+UnicodeString&
+UnicodeString::doAppend(const UnicodeString& src, int32_t srcStart, int32_t srcLength) {
+  if(srcLength == 0) {
+    return *this;
+  }
+
+  // pin the indices to legal values
+  src.pinIndices(srcStart, srcLength);
+  return doAppend(src.getArrayStart(), srcStart, srcLength);
+}
+
+UnicodeString&
+UnicodeString::doAppend(const UChar *srcChars, int32_t srcStart, int32_t srcLength) {
+  if(!isWritable() || srcLength == 0 || srcChars == NULL) {
+    return *this;
+  }
+
+  if(srcLength < 0) {
+    // get the srcLength if necessary
+    if((srcLength = u_strlen(srcChars + srcStart)) == 0) {
+      return *this;
+    }
+  }
+
+  int32_t oldLength = length();
+  int32_t newLength = oldLength + srcLength;
+  // optimize append() onto a large-enough, owned string
+  if((newLength <= getCapacity() && isBufferWritable()) ||
+      cloneArrayIfNeeded(newLength, newLength + (newLength >> 2) + kGrowSize)) {
+    UChar *newArray = getArrayStart();
+    // Do not copy characters when
+    //   UChar *buffer=str.getAppendBuffer(...);
+    // is followed by
+    //   str.append(buffer, length);
+    // or
+    //   str.appendString(buffer, length)
+    // or similar.
+    if(srcChars + srcStart != newArray + oldLength) {
+      us_arrayCopy(srcChars, srcStart, newArray, oldLength, srcLength);
+    }
+    setLength(newLength);
+  }
+  return *this;
+}
+
 /**
  * Replaceable API
  */
@@ -1806,7 +1824,7 @@ UnicodeStringAppendable::~UnicodeStringAppendable() {}
 
 UBool
 UnicodeStringAppendable::appendCodeUnit(UChar c) {
-  return str.doReplace(str.length(), 0, &c, 0, 1).isWritable();
+  return str.doAppend(&c, 0, 1).isWritable();
 }
 
 UBool
@@ -1815,12 +1833,12 @@ UnicodeStringAppendable::appendCodePoint(UChar32 c) {
   int32_t cLength = 0;
   UBool isError = FALSE;
   U16_APPEND(buffer, cLength, U16_MAX_LENGTH, c, isError);
-  return !isError && str.doReplace(str.length(), 0, buffer, 0, cLength).isWritable();
+  return !isError && str.doAppend(buffer, 0, cLength).isWritable();
 }
 
 UBool
 UnicodeStringAppendable::appendString(const UChar *s, int32_t length) {
-  return str.doReplace(str.length(), 0, s, 0, length).isWritable();
+  return str.doAppend(s, 0, length).isWritable();
 }
 
 UBool