diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2016-08-27 21:27:38 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-08-29 11:44:19 +0000 |
commit | 0c8fa58a2d73702770687ed15b98822d09f96ac3 (patch) | |
tree | f821dbc05e76a2430d902aec672cbb828d18d525 /include/rtl | |
parent | OUString construction from OUStringLiteral1 must not be overruled by... (diff) | |
download | core-0c8fa58a2d73702770687ed15b98822d09f96ac3.tar.gz core-0c8fa58a2d73702770687ed15b98822d09f96ac3.zip |
Support ConstCharArrayDetector also for UTF-16 arrays
The long-term benefit will be support of C++11 char16_t string literals (for
cases of string literals with non-ASCII content) once we drop any compilers that
don't support those yet. The short-term benefit is support for an improved
OUStringLiteral1 that accepts any sal_Unicode value, not just ASCII ones (see
next commit).
Change-Id: I3f8f6697d7eb62b5176b7e812b5a5113c53b83a4
Reviewed-on: https://gerrit.libreoffice.org/28445
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'include/rtl')
-rw-r--r-- | include/rtl/stringconcat.hxx | 9 | ||||
-rw-r--r-- | include/rtl/stringutils.hxx | 13 | ||||
-rw-r--r-- | include/rtl/ustrbuf.hxx | 74 | ||||
-rw-r--r-- | include/rtl/ustring.h | 223 | ||||
-rw-r--r-- | include/rtl/ustring.hxx | 520 |
5 files changed, 839 insertions, 0 deletions
diff --git a/include/rtl/stringconcat.hxx b/include/rtl/stringconcat.hxx index f381786eae4b..5a32bf930019 100644 --- a/include/rtl/stringconcat.hxx +++ b/include/rtl/stringconcat.hxx @@ -12,6 +12,7 @@ #include <rtl/stringutils.hxx> +#include <cstddef> #include <string.h> #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING" @@ -141,6 +142,14 @@ struct ToStringHelper< const char[ N ] > static const bool allowOUStringConcat = true; }; +template<std::size_t N> struct ToStringHelper<sal_Unicode const[N]> { + static int length(sal_Unicode const[N]) { return N - 1; } + static sal_Unicode * addData(sal_Unicode * buffer, sal_Unicode const str[N]) + { return addDataHelper(buffer, str, N - 1); } + static bool const allowOStringConcat = false; + static bool const allowOUStringConcat = true; +}; + template<char C> struct ToStringHelper<OUStringLiteral1_<C>> { static int length(OUStringLiteral1_<C>) { return 1; } static char * addData(char * buffer, OUStringLiteral1_<C> literal) diff --git a/include/rtl/stringutils.hxx b/include/rtl/stringutils.hxx index 23cad71a00b3..1e5761f0fab4 100644 --- a/include/rtl/stringutils.hxx +++ b/include/rtl/stringutils.hxx @@ -172,6 +172,15 @@ struct ConstCharArrayDetector< const char[ N ], T > static char const * toPointer(char const (& literal)[N]) { return literal; } }; #if defined LIBO_INTERNAL_ONLY +template<std::size_t N, typename T> +struct ConstCharArrayDetector<sal_Unicode const [N], T> { + using TypeUtf16 = T; + static SAL_CONSTEXPR bool const ok = true; + static SAL_CONSTEXPR std::size_t const length = N - 1; + static SAL_CONSTEXPR sal_Unicode const * toPointer( + sal_Unicode const (& literal)[N]) + { return literal; } +}; template<char C, typename T> struct ConstCharArrayDetector< #if defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ <= 8 \ && !defined __clang__ @@ -201,6 +210,8 @@ struct ExceptConstCharArrayDetector< const char[ N ] > { }; #if defined LIBO_INTERNAL_ONLY +template<std::size_t N> +struct ExceptConstCharArrayDetector<sal_Unicode const[N]> {}; template<char C> struct ExceptConstCharArrayDetector< #if defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ <= 8 \ && !defined __clang__ @@ -230,6 +241,8 @@ struct ExceptCharArrayDetector< const char[ N ] > { }; #if defined LIBO_INTERNAL_ONLY +template<std::size_t N> struct ExceptCharArrayDetector<sal_Unicode[N]> {}; +template<std::size_t N> struct ExceptCharArrayDetector<sal_Unicode const[N]> {}; template<char C> struct ExceptCharArrayDetector<OUStringLiteral1_<C>> {}; #endif diff --git a/include/rtl/ustrbuf.hxx b/include/rtl/ustrbuf.hxx index 1b1067977a38..8cfcabe043b4 100644 --- a/include/rtl/ustrbuf.hxx +++ b/include/rtl/ustrbuf.hxx @@ -146,6 +146,24 @@ public: #endif } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + OUStringBuffer( + T & literal, + typename libreoffice_internal::ConstCharArrayDetector< + T, libreoffice_internal::Dummy>::TypeUtf16 + = libreoffice_internal::Dummy()): + pData(nullptr), + nCapacity(libreoffice_internal::ConstCharArrayDetector<T>::length + 16) + { + rtl_uStringbuffer_newFromStr_WithLength( + &pData, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + } +#endif + #ifdef RTL_STRING_UNITTEST /** * Only used by unittests to detect incorrect conversions. @@ -484,6 +502,20 @@ public: return *this; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename libreoffice_internal::ConstCharArrayDetector< + T, OUStringBuffer &>::TypeUtf16 + append(T & literal) { + rtl_uStringbuffer_insert( + &pData, &nCapacity, getLength(), + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + return *this; + } +#endif + #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING" /** @overload @@ -836,6 +868,20 @@ public: return *this; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename libreoffice_internal::ConstCharArrayDetector< + T, OUStringBuffer &>::TypeUtf16 + insert(sal_Int32 offset, T & literal) { + rtl_uStringbuffer_insert( + &pData, &nCapacity, offset, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + return *this; + } +#endif + /** Inserts the string representation of the <code>sal_Bool</code> argument into this string buffer. @@ -1225,6 +1271,21 @@ public: return n < 0 ? n : n + fromIndex; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename + libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16 + indexOf(T & literal, sal_Int32 fromIndex = 0) const { + assert(fromIndex >= 0); + auto n = rtl_ustr_indexOfStr_WithLength( + pData->buffer + fromIndex, pData->length - fromIndex, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + return n < 0 ? n : n + fromIndex; + } +#endif + /** Returns the index within this string of the last occurrence of the specified substring, searching backward starting at the end. @@ -1290,6 +1351,19 @@ public: libreoffice_internal::ConstCharArrayDetector<T>::length); } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename + libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16 + lastIndexOf(T & literal) const { + return rtl_ustr_lastIndexOfStr_WithLength( + pData->buffer, pData->length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + } +#endif + /** Strip the given character from the start of the buffer. diff --git a/include/rtl/ustring.h b/include/rtl/ustring.h index aa58e5814911..831ecd66d9be 100644 --- a/include/rtl/ustring.h +++ b/include/rtl/ustring.h @@ -1458,6 +1458,28 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newConcatAsciiL( rtl_uString ** newString, rtl_uString * left, char const * right, sal_Int32 rightLength); +/** 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 UTF-16 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 UTF-16 code units + + @param rightLength the length of the \p right string; must be non-negative + + @since LibreOffice 5.3 + */ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newConcatUtf16L( + rtl_uString ** newString, rtl_uString * left, sal_Unicode 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), @@ -1632,6 +1654,114 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstAsciiLAsciiL( sal_Int32 fromLength, 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; upon return, points to the newly + allocated string or to null if there was either an out-of-memory condition + or the resulting number of UTF-16 code units would have been larger than + SAL_MAX_INT32 + + @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 + + @param fromLength the length of the \p from substring; must be non-negative + + @param to pointer to the substring to be replaced; must not be null and + must point to memory of at least \p toLength UTF-16 code units + + @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 would have taken place if \p newStr points to + null upon return) or -1 if no replacement took place + + @since LibreOffice 5.3 +*/ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstAsciiLUtf16L( + rtl_uString ** newStr, rtl_uString * str, char const * from, + sal_Int32 fromLength, sal_Unicode 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; upon return, points to the newly + allocated string or to null if there was either an out-of-memory condition + or the resulting number of UTF-16 code units would have been larger than + SAL_MAX_INT32 + + @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 UTF-16 code units + + @param fromLength the length of the \p from substring; must be non-negative + + @param to pointer to the substring to be replaced; 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 would have taken place if \p newStr points to + null upon return) or -1 if no replacement took place + + @since LibreOffice 5.3 +*/ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstUtf16LAsciiL( + rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from, + sal_Int32 fromLength, 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; upon return, points to the newly + allocated string or to null if there was either an out-of-memory condition + or the resulting number of UTF-16 code units would have been larger than + SAL_MAX_INT32 + + @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 UTF-16 code units + + @param fromLength the length of the \p from substring; must be non-negative + + @param to pointer to the substring to be replaced; must not be null and + must point to memory of at least \p toLength UTF-16 code units + + @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 would have taken place if \p newStr points to + null upon return) or -1 if no replacement took place + + @since LibreOffice 5.3 +*/ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstUtf16LUtf16L( + rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from, + sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength, + sal_Int32 * index) SAL_THROW_EXTERN_C(); + /** Create a new string by replacing all occurrences of a given substring with another substring. @@ -1752,6 +1882,99 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllAsciiLAsciiL( sal_Int32 fromLength, 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; upon return, points to the newly + allocated string or to null if there was either an out-of-memory condition + or the resulting number of UTF-16 code units would have been larger than + SAL_MAX_INT32 + + @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 + + @param fromLength the length of the \p from substring; must be non-negative + + @param to pointer to the substring to be replaced; must not be null and + must point to memory of at least \p toLength UTF-16 code units + + @param toLength the length of the \p to substring; must be non-negative + + @since LibreOffice 3.6 +*/ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllAsciiLUtf16L( + rtl_uString ** newStr, rtl_uString * str, char const * from, + sal_Int32 fromLength, sal_Unicode 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; upon return, points to the newly + allocated string or to null if there was either an out-of-memory condition + or the resulting number of UTF-16 code units would have been larger than + SAL_MAX_INT32 + + @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 UTF-16 code units + + @param fromLength the length of the \p from substring; must be non-negative + + @param to pointer to the substring to be replaced; 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 + + @since LibreOffice 3.6 +*/ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllUtf16LAsciiL( + rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from, + sal_Int32 fromLength, 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; upon return, points to the newly + allocated string or to null if there was either an out-of-memory condition + or the resulting number of UTF-16 code units would have been larger than + SAL_MAX_INT32 + + @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 UTF-16 code units + + @param fromLength the length of the \p from substring; must be non-negative + + @param to pointer to the substring to be replaced; must not be null and + must point to memory of at least \p toLength UTF-16 code units + + @param toLength the length of the \p to substring; must be non-negative + + @since LibreOffice 3.6 +*/ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllUtf16LUtf16L( + rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from, + sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength) + SAL_THROW_EXTERN_C(); + /** Create a new string by converting all ASCII uppercase letters to lowercase within another string. diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx index 8ac988232a13..5c097656c917 100644 --- a/include/rtl/ustring.hxx +++ b/include/rtl/ustring.hxx @@ -251,6 +251,27 @@ public: #endif } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> OUString( + T & literal, + typename libreoffice_internal::ConstCharArrayDetector< + T, libreoffice_internal::Dummy>::TypeUtf16 + = libreoffice_internal::Dummy()): + pData(nullptr) + { + if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) { + rtl_uString_new(&pData); + } else { + rtl_uString_newFromStr_WithLength( + &pData, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + } + } +#endif + #ifdef RTL_STRING_UNITTEST /** * Only used by unittests to detect incorrect conversions. @@ -451,6 +472,25 @@ public: return *this; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename + libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16 + operator =(T & literal) { + if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) { + rtl_uString_new(&pData); + } else { + rtl_uString_newFromStr_WithLength( + &pData, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + } + return *this; + } +#endif + /** Append a string to this string. @@ -495,6 +535,30 @@ public: operator +=(T &) && = delete; #endif +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename + libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16 + operator +=(T & literal) +#if HAVE_CXX11_REF_QUALIFIER + & +#endif + { + rtl_uString_newConcatUtf16L( + &pData, pData, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + return *this; + } +#if HAVE_CXX11_REF_QUALIFIER + template<typename T> + typename + libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16 + operator +=(T &) && = delete; +#endif +#endif + #ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING" /** @overload @@ -651,6 +715,19 @@ public: libreoffice_internal::ConstCharArrayDetector<T>::length); } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename + libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16 + reverseCompareTo(T & literal) const { + return rtl_ustr_reverseCompare_WithLength( + pData->buffer, pData->length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + } +#endif + /** Perform a comparison of two strings. @@ -738,6 +815,21 @@ public: == 0); } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + equalIgnoreAsciiCase(T & literal) const { + return + rtl_ustr_compareIgnoreAsciiCase_WithLength( + pData->buffer, pData->length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length) + == 0; + } +#endif + /** Match against a substring appearing in this string. @@ -778,6 +870,23 @@ public: == 0; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + match(T & literal, sal_Int32 fromIndex = 0) const { + assert(fromIndex >= 0); + return + rtl_ustr_shortenedCompare_WithLength( + pData->buffer + fromIndex, pData->length - fromIndex, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length, + libreoffice_internal::ConstCharArrayDetector<T>::length) + == 0; + } +#endif + /** Match against a substring appearing in this string, ignoring the case of ASCII letters. @@ -822,6 +931,23 @@ public: == 0; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + matchIgnoreAsciiCase(T & literal, sal_Int32 fromIndex = 0) const { + assert(fromIndex >= 0); + return + rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( + pData->buffer + fromIndex, pData->length - fromIndex, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length, + libreoffice_internal::ConstCharArrayDetector<T>::length) + == 0; + } +#endif + /** Compares two strings. @@ -1141,6 +1267,29 @@ public: return b; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + startsWith(T & literal, OUString * rest = nullptr) const { + bool b + = (libreoffice_internal::ConstCharArrayDetector<T>::length + <= sal_uInt32(pData->length)) + && (rtl_ustr_reverseCompare_WithLength( + pData->buffer, + libreoffice_internal::ConstCharArrayDetector<T>::length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length) + == 0); + if (b && rest != nullptr) { + *rest = copy( + libreoffice_internal::ConstCharArrayDetector<T>::length); + } + return b; + } +#endif + /** Check whether this string starts with a given string, ignoring the case of ASCII letters. @@ -1197,6 +1346,29 @@ public: return b; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + startsWithIgnoreAsciiCase(T & literal, OUString * rest = nullptr) const { + bool b + = (libreoffice_internal::ConstCharArrayDetector<T>::length + <= sal_uInt32(pData->length)) + && (rtl_ustr_compareIgnoreAsciiCase_WithLength( + pData->buffer, + libreoffice_internal::ConstCharArrayDetector<T>::length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length) + == 0); + if (b && rest != nullptr) { + *rest = copy( + libreoffice_internal::ConstCharArrayDetector<T>::length); + } + return b; + } +#endif + /** Check whether this string ends with a given substring. @@ -1249,6 +1421,32 @@ public: return b; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + endsWith(T & literal, OUString * rest = nullptr) const { + bool b + = (libreoffice_internal::ConstCharArrayDetector<T>::length + <= sal_uInt32(pData->length)) + && (rtl_ustr_reverseCompare_WithLength( + (pData->buffer + pData->length + - libreoffice_internal::ConstCharArrayDetector<T>::length), + libreoffice_internal::ConstCharArrayDetector<T>::length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length) + == 0); + if (b && rest != nullptr) { + *rest = copy( + 0, + (getLength() + - libreoffice_internal::ConstCharArrayDetector<T>::length)); + } + return b; + } +#endif + /** Check whether this string ends with a given ASCII string. @@ -1330,6 +1528,32 @@ public: return b; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + endsWithIgnoreAsciiCase(T & literal, OUString * rest = nullptr) const { + bool b + = (libreoffice_internal::ConstCharArrayDetector<T>::length + <= sal_uInt32(pData->length)) + && (rtl_ustr_compareIgnoreAsciiCase_WithLength( + (pData->buffer + pData->length + - libreoffice_internal::ConstCharArrayDetector<T>::length), + libreoffice_internal::ConstCharArrayDetector<T>::length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length) + == 0); + if (b && rest != nullptr) { + *rest = copy( + 0, + (getLength() + - libreoffice_internal::ConstCharArrayDetector<T>::length)); + } + return b; + } +#endif + /** Check whether this string ends with a given ASCII string, ignoring the case of ASCII letters. @@ -1439,6 +1663,57 @@ public: } #if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> friend inline + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + operator ==(OUString & string, T & literal) { + return + rtl_ustr_reverseCompare_WithLength( + string.pData->buffer, string.pData->length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length) + == 0; + } + /** @overload @since LibreOffice 5.3 */ + template<typename T> friend inline + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + operator ==(T & literal, OUString & string) { + return + rtl_ustr_reverseCompare_WithLength( + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length, + string.pData->buffer, string.pData->length) + == 0; + } + /** @overload @since LibreOffice 5.3 */ + template<typename T> friend inline + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + operator !=(OUString & string, T & literal) { + return + rtl_ustr_reverseCompare_WithLength( + string.pData->buffer, string.pData->length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length) + != 0; + } + /** @overload @since LibreOffice 5.3 */ + template<typename T> friend inline + typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 + operator !=(T & literal, OUString & string) { + return + rtl_ustr_reverseCompare_WithLength( + libreoffice_internal::ConstCharArrayDetector<T>::toPointer( + literal), + libreoffice_internal::ConstCharArrayDetector<T>::length, + string.pData->buffer, string.pData->length) + != 0; + } +#endif + +#if defined LIBO_INTERNAL_ONLY /// @cond INTERNAL /* Comparison between OUString and OUStringLiteral. @@ -1622,6 +1897,21 @@ public: return n < 0 ? n : n + fromIndex; } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename + libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16 + indexOf(T & literal, sal_Int32 fromIndex = 0) const { + assert(fromIndex >= 0); + auto n = rtl_ustr_indexOfStr_WithLength( + pData->buffer + fromIndex, pData->length - fromIndex, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + return n < 0 ? n : n + fromIndex; + } +#endif + /** Returns the index within this string of the first occurrence of the specified ASCII substring, starting at the specified index. @@ -1721,6 +2011,19 @@ public: libreoffice_internal::ConstCharArrayDetector<T>::length); } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> + typename + libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16 + lastIndexOf(T & literal) const { + return rtl_ustr_lastIndexOfStr_WithLength( + pData->buffer, pData->length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length); + } +#endif + /** Returns the index within this string of the last occurrence of the specified ASCII substring. @@ -1974,6 +2277,121 @@ public: return OUString(s, SAL_NO_ACQUIRE); } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> SAL_WARN_UNUSED_RESULT + typename + libreoffice_internal::ConstCharArrayDetector<T, OUString>::TypeUtf16 + replaceFirst(T & from, OUString const & to, sal_Int32 * index = nullptr) + const + { + rtl_uString * s = nullptr; + sal_Int32 i = 0; + rtl_uString_newReplaceFirstUtf16LUtf16L( + &s, pData, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from), + libreoffice_internal::ConstCharArrayDetector<T>::length, + to.pData->buffer, to.pData->length, index == nullptr ? &i : index); + if (s == nullptr) { + throw std::bad_alloc(); + // should be std::length_error if resulting would be too large + } + return OUString(s, SAL_NO_ACQUIRE); + } + /** @overload @since LibreOffice 5.3 */ + template<typename T> SAL_WARN_UNUSED_RESULT + typename + libreoffice_internal::ConstCharArrayDetector<T, OUString>::TypeUtf16 + replaceFirst(OUString const & from, T & to, sal_Int32 * index = nullptr) + const + { + rtl_uString * s = nullptr; + sal_Int32 i = 0; + rtl_uString_newReplaceFirstUtf16LUtf16L( + &s, pData, from.pData->buffer, from.pData->length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to), + libreoffice_internal::ConstCharArrayDetector<T>::length, + index == nullptr ? &i : index); + if (s == nullptr) { + throw std::bad_alloc(); + // should be std::length_error if resulting would be too large + } + return OUString(s, SAL_NO_ACQUIRE); + } + /** @overload @since LibreOffice 5.3 */ + template<typename T1, typename T2> SAL_WARN_UNUSED_RESULT + typename + libreoffice_internal::ConstCharArrayDetector< + T1, + typename libreoffice_internal::ConstCharArrayDetector< + T2, OUString>::TypeUtf16 + >::TypeUtf16 + replaceFirst(T1 & from, T2 & to, sal_Int32 * index = nullptr) const { + rtl_uString * s = nullptr; + sal_Int32 i = 0; + rtl_uString_newReplaceFirstUtf16LUtf16L( + &s, pData, + libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from), + libreoffice_internal::ConstCharArrayDetector<T1>::length, + libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to), + libreoffice_internal::ConstCharArrayDetector<T2>::length, + index == nullptr ? &i : index); + if (s == nullptr) { + throw std::bad_alloc(); + // should be std::length_error if resulting would be too large + } + return OUString(s, SAL_NO_ACQUIRE); + } + /** @overload @since LibreOffice 5.3 */ + template<typename T1, typename T2> SAL_WARN_UNUSED_RESULT + typename + libreoffice_internal::ConstCharArrayDetector< + T1, + typename libreoffice_internal::ConstCharArrayDetector< + T2, OUString>::Type + >::TypeUtf16 + replaceFirst(T1 & from, T2 & to, sal_Int32 * index = nullptr) const { + rtl_uString * s = nullptr; + sal_Int32 i = 0; + rtl_uString_newReplaceFirstUtf16LAsciiL( + &s, pData, + libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from), + libreoffice_internal::ConstCharArrayDetector<T1>::length, + libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to), + libreoffice_internal::ConstCharArrayDetector<T2>::length, + index == nullptr ? &i : index); + if (s == nullptr) { + throw std::bad_alloc(); + // should be std::length_error if resulting would be too large + } + return OUString(s, SAL_NO_ACQUIRE); + } + /** @overload @since LibreOffice 5.3 */ + template<typename T1, typename T2> SAL_WARN_UNUSED_RESULT + typename + libreoffice_internal::ConstCharArrayDetector< + T1, + typename libreoffice_internal::ConstCharArrayDetector< + T2, OUString>::TypeUtf16 + >::Type + replaceFirst(T1 & from, T2 & to, sal_Int32 * index = nullptr) const { + rtl_uString * s = nullptr; + sal_Int32 i = 0; + rtl_uString_newReplaceFirstAsciiLUtf16L( + &s, pData, + libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from), + libreoffice_internal::ConstCharArrayDetector<T1>::length, + libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to), + libreoffice_internal::ConstCharArrayDetector<T2>::length, + index == nullptr ? &i : index); + if (s == nullptr) { + throw std::bad_alloc(); + // should be std::length_error if resulting would be too large + } + return OUString(s, SAL_NO_ACQUIRE); + } +#endif + /** Returns a new string resulting from replacing all occurrences of a given substring with another substring. @@ -2076,6 +2494,108 @@ public: return OUString(s, SAL_NO_ACQUIRE); } +#if defined LIBO_INTERNAL_ONLY + /** @overload @since LibreOffice 5.3 */ + template<typename T> SAL_WARN_UNUSED_RESULT + typename + libreoffice_internal::ConstCharArrayDetector<T, OUString>::TypeUtf16 + replaceAll(T & from, OUString const & to) const { + rtl_uString * s = nullptr; + rtl_uString_newReplaceAllUtf16LUtf16L( + &s, pData, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from), + libreoffice_internal::ConstCharArrayDetector<T>::length, + to.pData->buffer, to.pData->length); + if (s == nullptr) { + throw std::bad_alloc(); + // should be std::length_error if resulting would be too large + } + return OUString(s, SAL_NO_ACQUIRE); + } + /** @overload @since LibreOffice 5.3 */ + template<typename T> SAL_WARN_UNUSED_RESULT + typename + libreoffice_internal::ConstCharArrayDetector<T, OUString>::TypeUtf16 + replaceAll(OUString const & from, T & to) const { + rtl_uString * s = nullptr; + rtl_uString_newReplaceAllUtf16LUtf16L( + &s, pData, from.pData->buffer, from.pData->length, + libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to), + libreoffice_internal::ConstCharArrayDetector<T>::length); + if (s == nullptr) { + throw std::bad_alloc(); + // should be std::length_error if resulting would be too large + } + return OUString(s, SAL_NO_ACQUIRE); + } + /** @overload @since LibreOffice 5.3 */ + template<typename T1, typename T2> SAL_WARN_UNUSED_RESULT + typename + libreoffice_internal::ConstCharArrayDetector< + T1, + typename libreoffice_internal::ConstCharArrayDetector< + T2, OUString>::TypeUtf16 + >::TypeUtf16 + replaceAll(T1 & from, T2 & to) const { + rtl_uString * s = nullptr; + rtl_uString_newReplaceAllUtf16LUtf16L( + &s, pData, + libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from), + libreoffice_internal::ConstCharArrayDetector<T1>::length, + libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to), + libreoffice_internal::ConstCharArrayDetector<T2>::length); + if (s == nullptr) { + throw std::bad_alloc(); + // should be std::length_error if resulting would be too large + } + return OUString(s, SAL_NO_ACQUIRE); + } + /** @overload @since LibreOffice 5.3 */ + template<typename T1, typename T2> SAL_WARN_UNUSED_RESULT + typename + libreoffice_internal::ConstCharArrayDetector< + T1, + typename libreoffice_internal::ConstCharArrayDetector< + T2, OUString>::Type + >::TypeUtf16 + replaceAll(T1 & from, T2 & to) const { + rtl_uString * s = nullptr; + rtl_uString_newReplaceAllUtf16LAsciiL( + &s, pData, + libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from), + libreoffice_internal::ConstCharArrayDetector<T1>::length, + libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to), + libreoffice_internal::ConstCharArrayDetector<T2>::length); + if (s == nullptr) { + throw std::bad_alloc(); + // should be std::length_error if resulting would be too large + } + return OUString(s, SAL_NO_ACQUIRE); + } + /** @overload @since LibreOffice 5.3 */ + template<typename T1, typename T2> SAL_WARN_UNUSED_RESULT + typename + libreoffice_internal::ConstCharArrayDetector< + T1, + typename libreoffice_internal::ConstCharArrayDetector< + T2, OUString>::TypeUtf16 + >::Type + replaceAll(T1 & from, T2 & to) const { + rtl_uString * s = nullptr; + rtl_uString_newReplaceAllAsciiLUtf16L( + &s, pData, + libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from), + libreoffice_internal::ConstCharArrayDetector<T1>::length, + libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to), + libreoffice_internal::ConstCharArrayDetector<T2>::length); + if (s == nullptr) { + throw std::bad_alloc(); + // should be std::length_error if resulting would be too large + } + return OUString(s, SAL_NO_ACQUIRE); + } +#endif + /** Converts from this string all ASCII uppercase characters (65-90) to ASCII lowercase characters (97-122). |