diff options
-rw-r--r-- | include/rtl/ustring.h | 24 | ||||
-rw-r--r-- | include/rtl/ustring.hxx | 18 | ||||
-rw-r--r-- | sal/qa/rtl/strings/test_oustring_concat.cxx | 8 | ||||
-rw-r--r-- | sal/rtl/ustring.cxx | 24 | ||||
-rw-r--r-- | sal/util/sal.map | 1 |
5 files changed, 75 insertions, 0 deletions
diff --git a/include/rtl/ustring.h b/include/rtl/ustring.h index 700393694b60..2a8cd933e3e0 100644 --- a/include/rtl/ustring.h +++ b/include/rtl/ustring.h @@ -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), diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx index 387a6e8099eb..d5142afc4139 100644 --- a/include/rtl/ustring.hxx +++ b/include/rtl/ustring.hxx @@ -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 diff --git a/sal/qa/rtl/strings/test_oustring_concat.cxx b/sal/qa/rtl/strings/test_oustring_concat.cxx index f02bde560451..977229691702 100644 --- a/sal/qa/rtl/strings/test_oustring_concat.cxx +++ b/sal/qa/rtl/strings/test_oustring_concat.cxx @@ -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; diff --git a/sal/rtl/ustring.cxx b/sal/rtl/ustring.cxx index de733e86be0d..b31bc2fcddeb 100644 --- a/sal/rtl/ustring.cxx +++ b/sal/rtl/ustring.cxx @@ -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 ) diff --git a/sal/util/sal.map b/sal/util/sal.map index c41ee41ebc7e..e3f920c7e33c 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -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; |