diff options
-rw-r--r-- | include/rtl/ustring.h | 53 | ||||
-rw-r--r-- | include/rtl/ustring.hxx | 52 | ||||
-rw-r--r-- | sal/qa/rtl/strings/test_strings_replace.cxx | 54 | ||||
-rw-r--r-- | sal/rtl/ustring.cxx | 58 | ||||
-rw-r--r-- | sal/util/sal.map | 6 |
5 files changed, 223 insertions, 0 deletions
diff --git a/include/rtl/ustring.h b/include/rtl/ustring.h index 8dd70cb4911f..700393694b60 100644 --- a/include/rtl/ustring.h +++ b/include/rtl/ustring.h @@ -1555,6 +1555,35 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstAsciiL( @param str pointer to the original string; must not be null + @param from pointer to the substring to be replaced; must not be null + + @param to pointer to the replacing substring; must not be null and must + point to memory of at least \p toLength ASCII bytes + + @param toLength the length of the \p to substring; must be non-negative + + @param[in,out] index pointer to a start index, must not be null; upon entry + to the function its value is the index into the original string at which to + start searching for the \p from substring, the value must be non-negative + and not greater than the original string's length; upon exit from the + function its value is the index into the original string at which the + replacement took place or -1 if no replacement took place + + @since LibreOffice 5.1 +*/ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstToAsciiL( + rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from, + char const * to, sal_Int32 toLength, sal_Int32 * index) + SAL_THROW_EXTERN_C(); + +/** Create a new string by replacing the first occurrence of a given substring + with another substring. + + @param[in, out] newStr pointer to the new string; must not be null; must + point to null or a valid rtl_uString + + @param str pointer to the original string; must not be null + @param from pointer to the substring to be replaced; must not be null and must point to memory of at least \p fromLength ASCII bytes @@ -1658,6 +1687,30 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllAsciiL( @param str pointer to the original string; must not be null + @param from pointer to the substring to be replaced; must not be null + + @param to pointer to the replacing substring; must not be null and must + point to memory of at least \p toLength ASCII bytes + + @param fromLength the length of the \p to substring; must be non-negative + + @since LibreOffice 5.1 +*/ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllToAsciiL( + rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from, + char const * to, sal_Int32 toLength) SAL_THROW_EXTERN_C(); + +/** Create a new string by replacing all occurrences of a given substring with + another substring. + + Replacing subsequent occurrences picks up only after a given replacement. + That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". + + @param[in, out] newStr pointer to the new string; must not be null; must + point to null or a valid rtl_uString + + @param str pointer to the original string; must not be null + @param from pointer to the substring to be replaced; must not be null and must point to memory of at least \p fromLength ASCII bytes diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx index 662e215c0370..1e9bfa8fbd5e 100644 --- a/include/rtl/ustring.hxx +++ b/include/rtl/ustring.hxx @@ -1780,6 +1780,36 @@ public: Returns a new string resulting from replacing the first occurrence of a given substring with another substring. + @param from the substring to be replaced + + @param to ASCII string literal, the replacing substring + + @param[in,out] index pointer to a start index; if the pointer is + non-null: upon entry to the function, its value is the index into the this + string at which to start searching for the \p from substring, the value + must be non-negative and not greater than this string's length; upon exiting + the function its value is the index into this string at which the + replacement took place or -1 if no replacement took place; if the pointer + is null, searching always starts at index 0 + + @since LibreOffice 5.1 + */ + template< typename T > + SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( OUString const & from, T& to, + sal_Int32 * index = 0) const + { + rtl_uString * s = 0; + sal_Int32 i = 0; + assert( strlen( to ) == libreoffice_internal::ConstCharArrayDetector< T >::size - 1 ); + rtl_uString_newReplaceFirstToAsciiL( + &s, pData, from.pData, to, libreoffice_internal::ConstCharArrayDetector< T, void >::size - 1, index == 0 ? &i : index); + return OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns a new string resulting from replacing the first occurrence of a + given substring with another substring. + @param from ASCII string literal, the substring to be replaced @param to ASCII string literal, the substring to be replaced @@ -1860,6 +1890,28 @@ public: Replacing subsequent occurrences picks up only after a given replacement. That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". + @param from the substring to be replaced + + @param to ASCII string literal, the replacing substring + + @since LibreOffice 5.1 + */ + template< typename T > + SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( OUString const & from, T& to) const + { + rtl_uString * s = 0; + assert( strlen( to ) == libreoffice_internal::ConstCharArrayDetector< T >::size - 1 ); + rtl_uString_newReplaceAllToAsciiL(&s, pData, from.pData, to, libreoffice_internal::ConstCharArrayDetector< T, void >::size - 1); + return OUString(s, SAL_NO_ACQUIRE); + } + + /** + Returns a new string resulting from replacing all occurrences of a given + substring with another substring. + + Replacing subsequent occurrences picks up only after a given replacement. + That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". + @param from ASCII string literal, the substring to be replaced @param to ASCII string literal, the substring to be replaced diff --git a/sal/qa/rtl/strings/test_strings_replace.cxx b/sal/qa/rtl/strings/test_strings_replace.cxx index 999df825a53a..0d47c3e6f4c5 100644 --- a/sal/qa/rtl/strings/test_strings_replace.cxx +++ b/sal/qa/rtl/strings/test_strings_replace.cxx @@ -37,12 +37,16 @@ private: void ustringReplaceFirstAsciiL(); + void ustringReplaceFirstToAsciiL(); + void ustringReplaceFirstAsciiLAsciiL(); void ustringReplaceAll(); void ustringReplaceAllAsciiL(); + void ustringReplaceAllToAsciiL(); + void ustringReplaceAllAsciiLAsciiL(); CPPUNIT_TEST_SUITE(Test); @@ -50,9 +54,11 @@ private: CPPUNIT_TEST(stringReplaceAll); CPPUNIT_TEST(ustringReplaceFirst); CPPUNIT_TEST(ustringReplaceFirstAsciiL); + CPPUNIT_TEST(ustringReplaceFirstToAsciiL); CPPUNIT_TEST(ustringReplaceFirstAsciiLAsciiL); CPPUNIT_TEST(ustringReplaceAll); CPPUNIT_TEST(ustringReplaceAllAsciiL); + CPPUNIT_TEST(ustringReplaceAllToAsciiL); CPPUNIT_TEST(ustringReplaceAllAsciiLAsciiL); CPPUNIT_TEST_SUITE_END(); }; @@ -172,6 +178,40 @@ void Test::ustringReplaceFirstAsciiL() { } } +void Test::ustringReplaceFirstToAsciiL() { + CPPUNIT_ASSERT_EQUAL( + rtl::OUString("otherbarfoo"), + rtl::OUString("foobarfoo").replaceFirst(s_foo, "other")); + + CPPUNIT_ASSERT_EQUAL( + rtl::OUString("foobarfoo"), + rtl::OUString("foobarfoo").replaceFirst(s_bars, "other")); + + { + sal_Int32 n = 0; + CPPUNIT_ASSERT_EQUAL( + rtl::OUString("otherbarfoo"), + rtl::OUString("foobarfoo").replaceFirst(s_foo, "other", &n)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), n); + } + + { + sal_Int32 n = 1; + CPPUNIT_ASSERT_EQUAL( + rtl::OUString("foobarother"), + rtl::OUString("foobarfoo").replaceFirst(s_foo, "other", &n)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(6), n); + } + + { + sal_Int32 n = 4; + CPPUNIT_ASSERT_EQUAL( + rtl::OUString("foobarfoo"), + rtl::OUString("foobarfoo").replaceFirst(s_bar, "other", &n)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), n); + } +} + void Test::ustringReplaceFirstAsciiLAsciiL() { CPPUNIT_ASSERT_EQUAL( rtl::OUString("otherbarfoo"), @@ -239,6 +279,20 @@ void Test::ustringReplaceAllAsciiL() { rtl::OUString("xaa").replaceAll("xa", s_xx)); } +void Test::ustringReplaceAllToAsciiL() { + CPPUNIT_ASSERT_EQUAL( + rtl::OUString("otherbarother"), + rtl::OUString("foobarfoo").replaceAll(s_foo, "other")); + + CPPUNIT_ASSERT_EQUAL( + rtl::OUString("foobarfoo"), + rtl::OUString("foobarfoo").replaceAll(s_bars, "other")); + + CPPUNIT_ASSERT_EQUAL( + rtl::OUString("xxa"), + rtl::OUString("xaa").replaceAll(s_xa, "xx")); +} + void Test::ustringReplaceAllAsciiLAsciiL() { CPPUNIT_ASSERT_EQUAL( rtl::OUString("otherbarother"), diff --git a/sal/rtl/ustring.cxx b/sal/rtl/ustring.cxx index 3c9c8b750a1f..827077468fd5 100644 --- a/sal/rtl/ustring.cxx +++ b/sal/rtl/ustring.cxx @@ -1173,6 +1173,49 @@ void rtl_uString_newReplaceFirstAsciiL( *index = i; } +void rtl_uString_newReplaceFirstToAsciiL( + rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from, + char const * to, sal_Int32 toLength, sal_Int32 * index) + SAL_THROW_EXTERN_C() +{ + assert(str != 0); + assert(index != 0); + assert(*index >= 0 && *index <= str->length); + assert(from != 0); + assert(toLength >= 0); + sal_Int32 i = rtl_ustr_indexOfStr_WithLength( + str->buffer + *index, str->length - *index, from->buffer, from->length); + if (i == -1) { + rtl_uString_assign(newStr, str); + } else { + assert(i <= str->length - *index); + i += *index; + assert(from->length <= str->length); + if (str->length - from->length > SAL_MAX_INT32 - toLength) { + std::abort(); + } + sal_Int32 n = str->length - from->length + toLength; + rtl_uString_acquire(str); // in case *newStr == str + if (n != 0) { + rtl_uString_new_WithLength(newStr, n); + (*newStr)->length = n; + assert(i >= 0 && i < str->length); + memcpy( + (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode)); + for (sal_Int32 j = 0; j != toLength; ++j) { + assert(static_cast< unsigned char >(to[j]) <= 0x7F); + (*newStr)->buffer[i + j] = to[j]; + } + memcpy( + (*newStr)->buffer + i + toLength, + str->buffer + i + from->length, + (str->length - i - from->length) * sizeof (sal_Unicode)); + } + rtl_uString_release(str); + } + *index = i; +} + void rtl_uString_newReplaceFirstAsciiLAsciiL( rtl_uString ** newStr, rtl_uString * str, char const * from, sal_Int32 fromLength, char const * to, sal_Int32 toLength, @@ -1254,6 +1297,21 @@ void rtl_uString_newReplaceAllAsciiL( } } +void rtl_uString_newReplaceAllToAsciiL( + rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from, + char const * to, sal_Int32 toLength) SAL_THROW_EXTERN_C() +{ + assert(from != 0); + rtl_uString_assign(newStr, str); + for (sal_Int32 i = 0;; i += toLength) { + rtl_uString_newReplaceFirstToAsciiL( + newStr, *newStr, from, to, toLength, &i); + if (i == -1) { + break; + } + } +} + void rtl_uString_newReplaceAllAsciiLAsciiL( rtl_uString ** newStr, rtl_uString * str, char const * from, sal_Int32 fromLength, char const * to, sal_Int32 toLength) diff --git a/sal/util/sal.map b/sal/util/sal.map index baafa66a255f..c41ee41ebc7e 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -683,6 +683,12 @@ LIBO_UDK_5.0 { # symbols available in >= LibO 5.0 rtl_secureZeroMemory; } LIBO_UDK_4.3; +LIBO_UDK_5.1 { # symbols available in >= LibO 5.1 + global: + rtl_uString_newReplaceAllToAsciiL; + rtl_uString_newReplaceFirstToAsciiL; +} LIBO_UDK_5.0; + PRIVATE_1.0 { global: osl_detail_ObjectRegistry_storeAddresses; |