sal/rtl/strtmpl.hxx |   34 ++++++++++++++
 sal/rtl/ustring.cxx |  121 +---------------------------------------------------
 2 files changed, 38 insertions(+), 117 deletions(-)

New commits:
commit ffb2e5520eff008d4e784fa6b15f4e2baa534e7a
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Fri Feb 25 20:41:15 2022 +0100
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Fri Feb 25 22:55:05 2022 +0100

    Deduplicate rtl_uString_newReplaceFirst*
    
    Change-Id: I6e09fd8e8acc06290423c1c44cc0c175b0c47e0a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130547
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sal/rtl/strtmpl.hxx b/sal/rtl/strtmpl.hxx
index 287e6987e36e..598d214878d6 100644
--- a/sal/rtl/strtmpl.hxx
+++ b/sal/rtl/strtmpl.hxx
@@ -1726,6 +1726,40 @@ void newReplaceAllFromIndex(S** s, S* s1, CharTypeFrom 
const* from, sal_Int32 fr
     RTL_LOG_STRING_NEW(*s);
 }
 
+template <class S, typename CharTypeFrom, typename CharTypeTo>
+void newReplaceFirst(S** s, S* s1, CharTypeFrom const* from, sal_Int32 
fromLength,
+                     CharTypeTo const* to, sal_Int32 toLength, sal_Int32& 
fromIndex)
+{
+    assert(s != nullptr);
+    assert(s1 != nullptr);
+    assert(fromLength >= 0);
+    assert(from != nullptr || fromLength == 0);
+    assert(toLength >= 0);
+    assert(to != nullptr || toLength == 0);
+    assert(fromIndex >= 0 && fromIndex <= s1->length);
+    sal_Int32 i = detail::indexOf(s1->buffer + fromIndex, s1->length - 
fromIndex, from, fromLength);
+    if (i >= 0)
+    {
+        if (s1->length - fromLength > SAL_MAX_INT32 - toLength)
+            std::abort();
+        i += fromIndex;
+        const sal_Int32 n = s1->length + (toLength - fromLength);
+        const auto pOld = *s;
+        *s = Alloc<S>(n);
+        if (i)
+            Copy((*s)->buffer, s1->buffer, i);
+        if (toLength)
+            Copy((*s)->buffer + i, to, toLength);
+        Copy((*s)->buffer + i + toLength, s1->buffer + i + fromLength, 
s1->length - i - fromLength);
+        if (pOld)
+            release(pOld); // Must be last in case *s == s1
+    }
+    else
+        assign(s, s1);
+
+    fromIndex = i;
+}
+
 template <class IMPL_RTL_STRINGDATA>
 using doubleToString_t
     = void(SAL_CALL*)(IMPL_RTL_STRINGDATA** pResult, sal_Int32* 
pResultCapacity,
diff --git a/sal/rtl/ustring.cxx b/sal/rtl/ustring.cxx
index 1f81dc3fd902..b289ae2a3f21 100644
--- a/sal/rtl/ustring.cxx
+++ b/sal/rtl/ustring.cxx
@@ -984,43 +984,8 @@ void rtl_uString_newReplaceFirstAsciiLAsciiL(
     sal_Int32 fromLength, char const * to, sal_Int32 toLength,
     sal_Int32 * index) SAL_THROW_EXTERN_C()
 {
-    assert(str != nullptr);
     assert(index != nullptr);
-    assert(*index >= 0 && *index <= str->length);
-    assert(fromLength >= 0);
-    assert(to != nullptr);
-    assert(toLength >= 0);
-    sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
-        str->buffer + *index, str->length - *index, from, fromLength);
-    if (i == -1) {
-        rtl_uString_assign(newStr, str);
-    } else {
-        assert(i <= str->length - *index);
-        i += *index;
-        assert(fromLength <= str->length);
-        if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
-            std::abort();
-        }
-        sal_Int32 n = str->length - fromLength + toLength;
-        rtl_uString_acquire(str); // in case *newStr == str
-        rtl_uString_new_WithLength(newStr, n);
-        if (n != 0) {
-            (*newStr)->length = n;
-            assert(i >= 0 && i < str->length);
-            memcpy(
-                (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
-            for (sal_Int32 j = 0; j != toLength; ++j) {
-                assert(static_cast< unsigned char >(to[j]) <= 0x7F);
-                (*newStr)->buffer[i + j] = to[j];
-            }
-            memcpy(
-                (*newStr)->buffer + i + toLength,
-                str->buffer + i + fromLength,
-                (str->length - i - fromLength) * sizeof (sal_Unicode));
-        }
-        rtl_uString_release(str);
-    }
-    *index = i;
+    rtl::str::newReplaceFirst(newStr, str, from, fromLength, to, toLength, 
*index);
 }
 
 void rtl_uString_newReplaceFirstAsciiLUtf16L(
@@ -1028,28 +993,8 @@ void rtl_uString_newReplaceFirstAsciiLUtf16L(
     sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength,
     sal_Int32 * index) SAL_THROW_EXTERN_C()
 {
-    assert(str != nullptr);
     assert(index != nullptr);
-    assert(*index >= 0 && *index <= str->length);
-    assert(fromLength >= 0);
-    assert(to != nullptr || toLength == 0);
-    assert(toLength >= 0);
-    sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
-        str->buffer + *index, str->length - *index, from, fromLength);
-    if (i == -1) {
-        rtl_uString_assign(newStr, str);
-    } else {
-        assert(i <= str->length - *index);
-        i += *index;
-        assert(fromLength <= str->length);
-        if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
-            rtl_uString_release(*newStr);
-            *newStr = nullptr;
-        } else {
-            rtl::str::newReplaceStrAt(newStr, str, i, fromLength, to, 
toLength);
-        }
-    }
-    *index = i;
+    rtl::str::newReplaceFirst(newStr, str, from, fromLength, to, toLength, 
*index);
 }
 
 void rtl_uString_newReplaceFirstUtf16LAsciiL(
@@ -1057,45 +1002,8 @@ void rtl_uString_newReplaceFirstUtf16LAsciiL(
     sal_Int32 fromLength, char const * to, sal_Int32 toLength,
     sal_Int32 * index) SAL_THROW_EXTERN_C()
 {
-    assert(str != nullptr);
     assert(index != nullptr);
-    assert(*index >= 0 && *index <= str->length);
-    assert(fromLength >= 0);
-    assert(to != nullptr);
-    assert(toLength >= 0);
-    sal_Int32 i = rtl_ustr_indexOfStr_WithLength(
-        str->buffer + *index, str->length - *index, from, fromLength);
-    if (i == -1) {
-        rtl_uString_assign(newStr, str);
-    } else {
-        assert(i <= str->length - *index);
-        i += *index;
-        assert(fromLength <= str->length);
-        if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
-            rtl_uString_release(*newStr);
-            *newStr = nullptr;
-        } else {
-            sal_Int32 n = str->length - fromLength + toLength;
-            rtl_uString_acquire(str); // in case *newStr == str
-            rtl_uString_new_WithLength(newStr, n);
-            if (n != 0 && /*TODO:*/ *newStr != nullptr) {
-                (*newStr)->length = n;
-                assert(i >= 0 && i < str->length);
-                memcpy(
-                    (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
-                for (sal_Int32 j = 0; j != toLength; ++j) {
-                    assert(static_cast< unsigned char >(to[j]) <= 0x7F);
-                    (*newStr)->buffer[i + j] = to[j];
-                }
-                memcpy(
-                    (*newStr)->buffer + i + toLength,
-                    str->buffer + i + fromLength,
-                    (str->length - i - fromLength) * sizeof (sal_Unicode));
-            }
-            rtl_uString_release(str);
-        }
-    }
-    *index = i;
+    rtl::str::newReplaceFirst(newStr, str, from, fromLength, to, toLength, 
*index);
 }
 
 void rtl_uString_newReplaceFirstUtf16LUtf16L(
@@ -1103,29 +1011,8 @@ void rtl_uString_newReplaceFirstUtf16LUtf16L(
     sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength,
     sal_Int32 * index) SAL_THROW_EXTERN_C()
 {
-    assert(str != nullptr);
     assert(index != nullptr);
-    assert(*index >= 0 && *index <= str->length);
-    assert(from != nullptr || fromLength == 0);
-    assert(fromLength >= 0);
-    assert(to != nullptr || toLength == 0);
-    assert(toLength >= 0);
-    sal_Int32 i = rtl_ustr_indexOfStr_WithLength(
-        str->buffer + *index, str->length - *index, from, fromLength);
-    if (i == -1) {
-        rtl_uString_assign(newStr, str);
-    } else {
-        assert(i <= str->length - *index);
-        i += *index;
-        assert(fromLength <= str->length);
-        if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
-            rtl_uString_release(*newStr);
-            *newStr = nullptr;
-        } else {
-            rtl::str::newReplaceStrAt(newStr, str, i, fromLength, to, 
toLength);
-        }
-    }
-    *index = i;
+    rtl::str::newReplaceFirst(newStr, str, from, fromLength, to, toLength, 
*index);
 }
 
 void rtl_uString_newReplaceAll(

Reply via email to