summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2022-02-24 17:45:18 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2022-02-24 17:57:14 +0100
commit089ce740f9f97f9c7b13e37a31acfc94984e9a3e (patch)
tree6f9984a8cad44cf0c1ba98a331d0f577aa26fb29 /sal
parent1127c63470096f62394f133c61cee2e6fb7fd0c7 (diff)
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.kaganski@collabora.com>
Diffstat (limited to 'sal')
-rw-r--r--sal/rtl/string.cxx24
-rw-r--r--sal/rtl/strtmpl.hxx86
-rw-r--r--sal/rtl/ustring.cxx47
3 files changed, 68 insertions, 89 deletions
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);
}
/* ======================================================================= */