Add optimized OUString += literal overload

Change-Id: Ib34196185f90204a71598f2c659c3fddce7a0e4d
This commit is contained in:
Stephan Bergmann
2015-06-26 13:49:25 +02:00
parent 1de776a492
commit edc96a157e
5 changed files with 75 additions and 0 deletions

View File

@@ -1434,6 +1434,30 @@ SAL_DLLPUBLIC sal_Unicode * SAL_CALL rtl_uString_getStr(
SAL_DLLPUBLIC void SAL_CALL rtl_uString_newConcat(
rtl_uString ** newStr, rtl_uString * left, rtl_uString * right ) SAL_THROW_EXTERN_C();
/** Create a new string that is the concatenation of two other strings.
The new string does not necessarily have a reference count of 1 (in cases
where the ASCII string is empty), so it must not be modified without
checking the reference count.
@param newString
pointer to the new string. The pointed-to data must be null or a valid
string.
@param left
a valid string.
@param right must not be null and must point to memory of at least
\p rightLength ASCII bytes
@param rightLength the length of the \p right string; must be non-negative
@since LibreOffice 5.1
*/
SAL_DLLPUBLIC void SAL_CALL rtl_uString_newConcatAsciiL(
rtl_uString ** newString, rtl_uString * left, char const * right,
sal_Int32 rightLength);
/** Create a new string by replacing a substring of another string.
The new string results from replacing a number of characters (count),

View File

@@ -424,6 +424,24 @@ public:
return *this;
}
/** Append an ASCII string literal to this string.
@param literal an 8-bit ASCII-only string literal
@since LibreOffice 5.1
*/
template<typename T>
typename libreoffice_internal::ConstCharArrayDetector<T, OUString &>::Type
operator +=(T & literal) {
assert(
libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
rtl_uString_newConcatAsciiL(
&pData, pData,
libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
libreoffice_internal::ConstCharArrayDetector<T>::length);
return *this;
}
#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
/**
@overload

View File

@@ -40,12 +40,14 @@ class StringConcat : public CppUnit::TestFixture
{
private:
void checkConcat();
void checkConcatAsciiL();
void checkEnsureCapacity();
void checkAppend();
void checkInvalid();
CPPUNIT_TEST_SUITE(StringConcat);
CPPUNIT_TEST(checkConcat);
CPPUNIT_TEST(checkConcatAsciiL);
CPPUNIT_TEST(checkEnsureCapacity);
CPPUNIT_TEST(checkAppend);
CPPUNIT_TEST(checkInvalid);
@@ -71,6 +73,12 @@ void test::oustring::StringConcat::checkConcat()
CPPUNIT_ASSERT_EQUAL(( typeid( OUStringConcat< OUStringBuffer, OUString > )), typeid( OUStringBuffer( "foo" ) + OUString( "bar" )));
}
void test::oustring::StringConcat::checkConcatAsciiL()
{
CPPUNIT_ASSERT_EQUAL(OUString("foo"), OUString("foo") += "");
CPPUNIT_ASSERT_EQUAL(OUString("foobar"), OUString("foo") += "bar");
}
void test::oustring::StringConcat::checkEnsureCapacity()
{
rtl_uString* str = NULL;

View File

@@ -25,6 +25,8 @@
#include <cassert>
#include <cstdlib>
#include <limits>
#include <stdexcept>
#include <osl/diagnose.h>
#include <osl/interlck.h>
@@ -595,6 +597,28 @@ void SAL_CALL rtl_uString_newFromCodePoints(
RTL_LOG_STRING_NEW( *newString );
}
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) {
throw std::length_error("rtl_uString_newConcatAsciiL");
}
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;
}
/* ======================================================================= */
static int rtl_ImplGetFastUTF8UnicodeLen( const sal_Char* pStr, sal_Int32 nLen, bool * ascii )

View File

@@ -685,6 +685,7 @@ LIBO_UDK_5.0 { # symbols available in >= LibO 5.0
LIBO_UDK_5.1 { # symbols available in >= LibO 5.1
global:
rtl_uString_newConcatAsciiL;
rtl_uString_newReplaceAllToAsciiL;
rtl_uString_newReplaceFirstToAsciiL;
} LIBO_UDK_5.0;