sal/rtl/string.cxx  |   24 --------------
 sal/rtl/strtmpl.hxx |   86 +++++++++++++++++++++++++++++++++++++++-------------
 sal/rtl/ustring.cxx |   47 +---------------------------
 3 files changed, 68 insertions(+), 89 deletions(-)

New commits:
commit 089ce740f9f97f9c7b13e37a31acfc94984e9a3e
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Feb 24 17:45:18 2022 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Feb 24 17:57:14 2022 +0100

    Deduplicate rtl_*String_newConcat*L
    
    Change-Id: I9712cd8a2798fe5493dffd557e68239d9db3b7aa
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130501
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sal/rtl/string.cxx b/sal/rtl/string.cxx
index ab59eab78c77..de8cabff4c91 100644
--- a/sal/rtl/string.cxx
+++ b/sal/rtl/string.cxx
@@ -622,29 +622,7 @@ static void rtl_string_newConcatL(
     rtl_String ** newString, rtl_String * left, char const * right,
     sal_Int32 rightLength)
 {
-    assert(newString != nullptr);
-    assert(left != nullptr);
-    assert(right != nullptr || rightLength == 0);
-    assert(rightLength >= 0);
-    if (left->length > std::numeric_limits<sal_Int32>::max() - rightLength) {
-#if !defined(__COVERITY__)
-        throw std::length_error("rtl_string_newConcatL");
-#else
-        //coverity doesn't report std::bad_alloc as an unhandled exception when
-        //potentially thrown from destructors but does report std::length_error
-        throw std::bad_alloc();
-#endif
-    }
-    sal_Int32 n = left->length + rightLength;
-    rtl_string_assign(newString, left);
-    rtl_string_ensureCapacity(newString, n);
-    if (rightLength != 0) {
-        memcpy(
-            (*newString)->buffer + (*newString)->length, right,
-            rightLength);
-    }
-    (*newString)->buffer[n] = 0;
-    (*newString)->length = n;
+    rtl::str::newConcat(newString, left, right, rightLength);
 }
 
 void SAL_CALL rtl_string_ensureCapacity(rtl_String** ppThis, sal_Int32 size) 
SAL_THROW_EXTERN_C()
diff --git a/sal/rtl/strtmpl.hxx b/sal/rtl/strtmpl.hxx
index 8901f3ace2b2..90d9547170ec 100644
--- a/sal/rtl/strtmpl.hxx
+++ b/sal/rtl/strtmpl.hxx
@@ -52,6 +52,16 @@ void Copy( IMPL_RTL_STRCODE* _pDest,
     memcpy( _pDest, _pSrc, _nCount * sizeof(IMPL_RTL_STRCODE));
 }
 
+inline void Copy(sal_Unicode* _pDest, const char* _pSrc, sal_Int32 _nCount)
+{
+    std::transform(_pSrc, _pSrc + _nCount, _pDest,
+                   [](char c)
+                   {
+                       assert(rtl::isAscii(static_cast<unsigned char>(c)));
+                       return static_cast<unsigned char>(c);
+                   });
+}
+
 /* ======================================================================= */
 /* C-String functions which could be used without the String-Class         */
 /* ======================================================================= */
@@ -1152,38 +1162,44 @@ template <typename IMPL_RTL_STRINGDATA> auto* getStr( 
IMPL_RTL_STRINGDATA* pThis
 
 /* ----------------------------------------------------------------------- */
 
-template <typename IMPL_RTL_STRINGDATA>
-void newConcat                                ( IMPL_RTL_STRINGDATA** ppThis,
-                                                IMPL_RTL_STRINGDATA* pLeft,
-                                                IMPL_RTL_STRINGDATA* pRight )
+enum ThrowPolicy { NoThrow, Throw };
+
+template <ThrowPolicy throwPolicy, typename IMPL_RTL_STRINGDATA, typename C1, 
typename C2>
+void newConcat(IMPL_RTL_STRINGDATA** ppThis, const C1* pLeft, sal_Int32 
nLeftLength,
+               const C2* pRight, sal_Int32 nRightLength)
 {
     assert(ppThis);
+    assert(nLeftLength >= 0);
+    assert(pLeft || nLeftLength == 0);
+    assert(nRightLength >= 0);
+    assert(pRight || nRightLength == 0);
     IMPL_RTL_STRINGDATA* pOrg = *ppThis;
 
-    /* Test for 0-Pointer - if not, change newReplaceStrAt! */
-    if ( !pRight || !pRight->length )
+    if (nLeftLength > std::numeric_limits<sal_Int32>::max() - nRightLength)
     {
-        *ppThis = pLeft;
-        acquire( pLeft );
-    }
-    else if ( !pLeft || !pLeft->length )
-    {
-        *ppThis = pRight;
-        acquire( pRight );
-    }
-    else if (pLeft->length
-             > std::numeric_limits<sal_Int32>::max() - pRight->length)
-    {
-        *ppThis = nullptr;
+        if constexpr (throwPolicy == NoThrow)
+            *ppThis = nullptr;
+        else
+        {
+#if !defined(__COVERITY__)
+            throw std::length_error("newConcat");
+#else
+            //coverity doesn't report std::bad_alloc as an unhandled exception 
when
+            //potentially thrown from destructors but does report 
std::length_error
+            throw std::bad_alloc();
+#endif
+        }
     }
     else
     {
-        auto* pTempStr = Alloc<IMPL_RTL_STRINGDATA>( pLeft->length + 
pRight->length );
+        auto* pTempStr = Alloc<IMPL_RTL_STRINGDATA>(nLeftLength + 
nRightLength);
         OSL_ASSERT(pTempStr != nullptr);
         *ppThis = pTempStr;
         if (*ppThis != nullptr) {
-            Copy( pTempStr->buffer, pLeft->buffer, pLeft->length );
-            Copy( pTempStr->buffer+pLeft->length, pRight->buffer, 
pRight->length );
+            if (nLeftLength)
+                Copy( pTempStr->buffer, pLeft, nLeftLength );
+            if (nRightLength)
+                Copy( pTempStr->buffer+nLeftLength, pRight, nRightLength );
 
             RTL_LOG_STRING_NEW( *ppThis );
         }
@@ -1194,6 +1210,34 @@ void newConcat                                ( 
IMPL_RTL_STRINGDATA** ppThis,
         release( pOrg );
 }
 
+template<typename IMPL_RTL_STRINGDATA, typename IMPL_RTL_STRCODE>
+void newConcat(IMPL_RTL_STRINGDATA** ppThis, IMPL_RTL_STRINGDATA* pLeft,
+               const IMPL_RTL_STRCODE* pRight, sal_Int32 nRightLength)
+{
+    assert(pLeft != nullptr);
+    if (nRightLength == 0)
+        assign(ppThis, pLeft);
+    else
+        newConcat<Throw>(ppThis, pLeft->buffer, pLeft->length, pRight, 
nRightLength);
+}
+
+template <typename IMPL_RTL_STRINGDATA>
+void newConcat                                ( IMPL_RTL_STRINGDATA** ppThis,
+                                                IMPL_RTL_STRINGDATA* pLeft,
+                                                IMPL_RTL_STRINGDATA* pRight )
+{
+    /* Test for 0-Pointer - if not, change newReplaceStrAt! */
+    if ( !pRight || !pRight->length )
+    {
+        assert(pLeft != nullptr);
+        assign(ppThis, pLeft);
+    }
+    else if ( !pLeft || !pLeft->length )
+        assign(ppThis, pRight);
+    else
+        newConcat<NoThrow>(ppThis, pLeft->buffer, pLeft->length, 
pRight->buffer, pRight->length);
+}
+
 /* ----------------------------------------------------------------------- */
 
 template <typename IMPL_RTL_STRINGDATA>
diff --git a/sal/rtl/ustring.cxx b/sal/rtl/ustring.cxx
index b5fc3685c48b..3aa772f491e6 100644
--- a/sal/rtl/ustring.cxx
+++ b/sal/rtl/ustring.cxx
@@ -562,57 +562,14 @@ void rtl_uString_newConcatAsciiL(
     rtl_uString ** newString, rtl_uString * left, char const * right,
     sal_Int32 rightLength)
 {
-    assert(newString != nullptr);
-    assert(left != nullptr);
-    assert(right != nullptr);
-    assert(rightLength >= 0);
-    if (left->length > std::numeric_limits<sal_Int32>::max() - rightLength) {
-#if !defined(__COVERITY__)
-        throw std::length_error("rtl_uString_newConcatAsciiL");
-#else
-        //coverity doesn't report std::bad_alloc as an unhandled exception when
-        //potentially thrown from destructors but does report std::length_error
-        throw std::bad_alloc();
-#endif
-    }
-    sal_Int32 n = left->length + rightLength;
-    rtl_uString_assign(newString, left);
-    rtl_uString_ensureCapacity(newString, n);
-    sal_Unicode * p = (*newString)->buffer + (*newString)->length;
-    for (sal_Int32 i = 0; i != rightLength; ++i) {
-        p[i] = static_cast<unsigned char>(right[i]);
-    }
-    (*newString)->buffer[n] = 0;
-    (*newString)->length = n;
+    rtl::str::newConcat(newString, left, right, rightLength);
 }
 
 void rtl_uString_newConcatUtf16L(
     rtl_uString ** newString, rtl_uString * left, sal_Unicode const * right,
     sal_Int32 rightLength)
 {
-    assert(newString != nullptr);
-    assert(left != nullptr);
-    assert(right != nullptr || rightLength == 0);
-    assert(rightLength >= 0);
-    if (left->length > std::numeric_limits<sal_Int32>::max() - rightLength) {
-#if !defined(__COVERITY__)
-        throw std::length_error("rtl_uString_newConcatUtf16L");
-#else
-        //coverity doesn't report std::bad_alloc as an unhandled exception when
-        //potentially thrown from destructors but does report std::length_error
-        throw std::bad_alloc();
-#endif
-    }
-    sal_Int32 n = left->length + rightLength;
-    rtl_uString_assign(newString, left);
-    rtl_uString_ensureCapacity(newString, n);
-    if (rightLength != 0) {
-        memcpy(
-            (*newString)->buffer + (*newString)->length, right,
-            rightLength * sizeof (sal_Unicode));
-    }
-    (*newString)->buffer[n] = 0;
-    (*newString)->length = n;
+    rtl::str::newConcat(newString, left, right, rightLength);
 }
 
 /* ======================================================================= */

Reply via email to