summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/rtl/ustring.h53
-rw-r--r--include/rtl/ustring.hxx52
-rw-r--r--sal/qa/rtl/strings/test_strings_replace.cxx54
-rw-r--r--sal/rtl/ustring.cxx58
-rw-r--r--sal/util/sal.map6
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;