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>
This commit is contained in:
Mike Kaganski
2022-02-24 17:45:18 +03:00
parent 1127c63470
commit 089ce740f9
3 changed files with 68 additions and 89 deletions

View File

@@ -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()

View File

@@ -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>

View File

@@ -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);
}
/* ======================================================================= */