diff options
Diffstat (limited to 'sal')
-rw-r--r-- | sal/rtl/string.cxx | 24 | ||||
-rw-r--r-- | sal/rtl/strtmpl.hxx | 86 | ||||
-rw-r--r-- | sal/rtl/ustring.cxx | 47 |
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); } /* ======================================================================= */ |