31#include <rtl/character.hxx>
32#include <rtl/ustring.hxx>
33#include <rtl/ustrbuf.hxx>
34#include <rtl/string.hxx>
35#include <rtl/strbuf.hxx>
43#include <com/sun/star/i18n/BreakIterator.hpp>
44#include <com/sun/star/i18n/CharType.hpp>
45#include <com/sun/star/i18n/Collator.hpp>
52 template <
typename T,
typename C> T tmpl_stripStart(
const T &rIn,
58 typename T::size_type
i = 0;
60 while (i < rIn.size())
62 if (rIn[i] != cRemove)
69 template <
typename T,
typename C> T tmpl_stripStartString(
const T &rIn,
77 while (i < rIn.getLength())
79 if (rIn[i] != cRemove)
90 return tmpl_stripStartString<OString, char>(rIn, c);
95 return tmpl_stripStart<std::string_view, char>(rIn, c);
100 return tmpl_stripStartString<OUString, sal_Unicode>(rIn, c);
105 return tmpl_stripStart<std::u16string_view, sal_Unicode>(rIn, c);
110 template <
typename T,
typename C> T tmpl_stripEnd(
const T &rIn,
116 typename T::size_type
i = rIn.size();
120 if (rIn[i-1] != cRemove)
125 return rIn.substr(0, i);
127 template <
typename T,
typename C> T tmpl_stripEndString(
const T &rIn,
133 sal_Int32
i = rIn.getLength();
137 if (rIn[i-1] != cRemove)
142 return rIn.copy(0, i);
148 return tmpl_stripEndString<OString, char>(rIn, c);
151std::string_view
stripEnd(std::string_view rIn,
char c)
153 return tmpl_stripEnd<std::string_view, char>(rIn, c);
158 return tmpl_stripEndString<OUString, sal_Unicode>(rIn, c);
163 return tmpl_stripEnd<std::u16string_view, sal_Unicode>(rIn, c);
168 template <
typename T,
typename C> T tmpl_strip(
const T &rIn,
174 typename T::size_type
end = rIn.size();
177 if (rIn[end-1] != cRemove)
182 typename T::size_type
start = 0;
185 if (rIn[start] != cRemove)
190 return rIn.substr(start, end - start);
192 template <
typename T,
typename C> T tmpl_stripString(
const T &rIn,
198 sal_Int32
end = rIn.getLength();
201 if (rIn[end-1] != cRemove)
208 if (rIn[start] != cRemove)
213 return rIn.copy(start, end - start);
217OString
strip(
const OString& rIn,
char c)
219 return tmpl_stripString<OString, char>(rIn, c);
222std::string_view
strip(std::string_view rIn,
char c)
224 return tmpl_strip<std::string_view, char>(rIn, c);
229 return tmpl_stripString<OUString, sal_Unicode>(rIn, c);
234 return tmpl_strip<std::u16string_view, sal_Unicode>(rIn, c);
239 template <
typename T,
typename C> sal_Int32 tmpl_getTokenCount( T rIn,
246 sal_Int32 nTokCount = 1;
247 for (
typename T::size_type i = 0;
i < rIn.size(); ++
i)
258 return tmpl_getTokenCount<std::string_view, char>(rIn, cTok);
263 return tmpl_getTokenCount<std::u16string_view, sal_Unicode>(rIn, cTok);
269 for( sal_Int32
i = 0; i < static_cast<sal_Int32>(str.size()); )
272 sal_uInt32
value = 0;
275 else if( c >= 0x1D7F6 )
277 else if( c >= 0x1D7EC )
279 else if( c >= 0x1D7E2 )
281 else if( c >= 0x1D7D8 )
283 else if( c >= 0x1D7CE )
285 else if( c >= 0x11066 )
287 else if( c >= 0x104A0 )
289 else if( c >= 0xFF10 )
291 else if( c >= 0xABF0 )
293 else if( c >= 0xAA50 )
295 else if( c >= 0xA9D0 )
297 else if( c >= 0xA900 )
299 else if( c >= 0xA8D0 )
301 else if( c >= 0xA620 )
303 else if( c >= 0x1C50 )
305 else if( c >= 0x1C40 )
307 else if( c >= 0x1BB0 )
309 else if( c >= 0x1B50 )
311 else if( c >= 0x1A90 )
313 else if( c >= 0x1A80 )
315 else if( c >= 0x19D0 )
317 else if( c >= 0x1946 )
319 else if( c >= 0x1810 )
321 else if( c >= 0x17E0 )
323 else if( c >= 0x1090 )
325 else if( c >= 0x1040 )
327 else if( c >= 0x0F20 )
329 else if( c >= 0x0ED0 )
331 else if( c >= 0x0E50 )
333 else if( c >= 0x0D66 )
335 else if( c >= 0x0CE6 )
337 else if( c >= 0x0C66 )
339 else if( c >= 0x0BE6 )
341 else if( c >= 0x0B66 )
343 else if( c >= 0x0AE6 )
345 else if( c >= 0x0A66 )
347 else if( c >= 0x09E6 )
349 else if( c >= 0x0966 )
351 else if( c >= 0x07C0 )
353 else if( c >= 0x06F0 )
355 else if( c >= 0x0660 )
367 uno::Sequence< OUString >
const& i_rSeq)
372 return buf.makeStringAndClear();
378 std::vector< OUString > vec;
386 vec.push_back(OUString(kw));
389 }
while (
idx != std::u16string_view::npos);
394uno::Sequence< OUString >
397 std::vector< OUString > vec =
split(i_rString,
',');
401OString
join(std::string_view rSeparator,
const std::vector<OString>& rSequence)
404 for (
size_t i = 0;
i < rSequence.size(); ++
i)
410 return aBuffer.makeStringAndClear();
414 const uno::Reference< i18n::XCollator > &rCollator,
415 const uno::Reference< i18n::XBreakIterator > &rBI,
416 const lang::Locale &rLocale )
420 sal_Int32 nLHSLastNonDigitPos = 0;
421 sal_Int32 nRHSLastNonDigitPos = 0;
422 sal_Int32 nLHSFirstDigitPos = 0;
423 sal_Int32 nRHSFirstDigitPos = 0;
426 sal_Int32 nStartsDigitLHS = rBI->endOfCharBlock(rLHS, nLHSFirstDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
427 sal_Int32 nStartsDigitRHS = rBI->endOfCharBlock(rRHS, nRHSFirstDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
429 if (nStartsDigitLHS > 0 && nStartsDigitRHS > 0)
435 return nLHS < nRHS ? -1 : 1;
436 nLHSLastNonDigitPos = nStartsDigitLHS;
437 nRHSLastNonDigitPos = nStartsDigitRHS;
439 else if (nStartsDigitLHS > 0)
441 else if (nStartsDigitRHS > 0)
444 while (nLHSFirstDigitPos < rLHS.getLength() || nRHSFirstDigitPos < rRHS.getLength())
446 sal_Int32 nLHSChunkLen;
447 sal_Int32 nRHSChunkLen;
450 nLHSFirstDigitPos = rBI->nextCharBlock(rLHS, nLHSLastNonDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
451 nRHSFirstDigitPos = rBI->nextCharBlock(rRHS, nRHSLastNonDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
453 if (nLHSFirstDigitPos == -1)
454 nLHSFirstDigitPos = rLHS.getLength();
456 if (nRHSFirstDigitPos == -1)
457 nRHSFirstDigitPos = rRHS.getLength();
459 nLHSChunkLen = nLHSFirstDigitPos - nLHSLastNonDigitPos;
460 nRHSChunkLen = nRHSFirstDigitPos - nRHSLastNonDigitPos;
462 nRet = rCollator->compareSubstring(rLHS, nLHSLastNonDigitPos, nLHSChunkLen, rRHS, nRHSLastNonDigitPos, nRHSChunkLen);
467 nLHSLastNonDigitPos = rBI->endOfCharBlock(rLHS, nLHSFirstDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
468 nRHSLastNonDigitPos = rBI->endOfCharBlock(rRHS, nRHSFirstDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
469 if (nLHSLastNonDigitPos == -1)
470 nLHSLastNonDigitPos = rLHS.getLength();
471 if (nRHSLastNonDigitPos == -1)
472 nRHSLastNonDigitPos = rRHS.getLength();
473 nLHSChunkLen = nLHSLastNonDigitPos - nLHSFirstDigitPos;
474 nRHSChunkLen = nRHSLastNonDigitPos - nRHSFirstDigitPos;
485 nRet = (nLHS < nRHS) ? -1 : 1;
494 const uno::Reference< uno::XComponentContext > &rContext,
499 m_xBI = i18n::BreakIterator::create( rContext );
505 rString.data(), rString.data() + rString.size(),
506 [](
unsigned char c){ return rtl::isAsciiDigit(c); });
512 rString.data(), rString.data() + rString.size(),
513 [](
sal_Unicode c){ return rtl::isAsciiDigit(c); });
521 std::size_t
i = rStr.size();
522 OUStringBuffer sBuf(
static_cast<sal_Int32
>(
i));
524 sBuf.append(rStr[--
i]);
525 return sBuf.makeStringAndClear();
529 auto const len = str.getLength();
530 OUStringBuffer buf(len);
531 for (
auto i = len;
i != 0;) {
532 buf.appendUtf32(str.iterateCodePoints(&
i, -1));
534 return buf.makeStringAndClear();
538 sal_Unicode const*
const pChars, sal_Int32
const nPos)
540 for (std::u16string_view::size_type
i =
nPos;
i < rIn.size(); ++
i)
559 for (std::u16string_view::size_type
i = 0;
i < rIn.size(); ++
i)
577 buf.append(rIn.substr(0,
i));
587 return isFound ? buf.makeStringAndClear() : OUString(rIn);
591 std::u16string_view rNewToken)
593 sal_Int32 nLen = rIn.getLength();
595 sal_Int32 nFirstChar = 0;
616 return rIn.replaceAt(nFirstChar,
i-nFirstChar,
rNewToken);
625void replaceAt(OUStringBuffer& rIn, sal_Int32 nIndex, sal_Int32 nCount, std::u16string_view newStr )
632 const sal_Int32 nOldLength = rIn.getLength();
633 if (
nIndex == nOldLength )
639 sal_Int32 nNewLength = nOldLength + newStr.size() -
nCount;
641 rIn.ensureCapacity(nOldLength + newStr.size() -
nCount);
645 memcpy(pStr +
nIndex, newStr.data(), newStr.size());
647 rIn.setLength(nNewLength);
653 while (
i < rString.getLength())
656 if (rtl::isHighSurrogate(c))
658 if (
i+1 == rString.getLength()
659 || !rtl::isLowSurrogate(rString[
i+1]))
661 SAL_WARN(
"comphelper",
"Surrogate error: high without low");
662 return rString.copy(0,
i);
666 if (rtl::isLowSurrogate(c))
668 SAL_WARN(
"comphelper",
"Surrogate error: low without high");
669 return rString.copy(0,
i);
output iterator that appends OUStrings into an OUStringBuffer.
css::lang::Locale const m_aLocale
NaturalStringSorter(const css::uno::Reference< css::uno::XComponentContext > &rContext, css::lang::Locale aLocale)
css::uno::Reference< css::i18n::XBreakIterator > m_xBI
css::uno::Reference< css::i18n::XCollator > m_xCollator
std::u16string_view rNewToken
#define SAL_WARN(area, stream)
bool isdigitAsciiString(std::string_view rString)
Determine if an OString contains solely ASCII numeric digits.
OUString setToken(const OUString &rIn, sal_Int32 nToken, sal_Unicode cTok, std::u16string_view rNewToken)
Replace a token in a string.
OString join(std::string_view rSeparator, const std::vector< OString > &rSequence)
Return a string which is the concatenation of the strings in the sequence.
OUString sanitizeStringSurrogates(const OUString &rString)
Sanitize an OUString to not have invalid surrogates.
OString strip(const OString &rIn, char c)
Strips occurrences of a character from the start and end of the source string.
OString stripEnd(const OString &rIn, char c)
Strips occurrences of a character from the end of the source string.
sal_uInt32 decimalStringToNumber(std::u16string_view str)
Convert a decimal string to a number.
void replaceAt(OUStringBuffer &rIn, sal_Int32 nIndex, sal_Int32 nCount, std::u16string_view newStr)
Similar to OUString::replaceAt, but for an OUStringBuffer.
OUString reverseString(std::u16string_view rStr)
Reverse an OUString's UTF-16 code units.
OUString removeAny(std::u16string_view rIn, sal_Unicode const *const pChars)
Remove any of a list of code units in the string.
sal_Int32 indexOfAny(std::u16string_view rIn, sal_Unicode const *const pChars, sal_Int32 const nPos)
Find any of a list of code units in the string.
OUString reverseCodePoints(OUString const &str)
Reverse an OUString's Unicode code points.
OUString convertCommaSeparated(uno::Sequence< OUString > const &i_rSeq)
OString stripStart(const OString &rIn, char c)
Strips occurrences of a character from the start of the source string.
std::vector< OUString > split(std::u16string_view rStr, sal_Unicode cSeparator)
sal_Int32 compareNatural(const OUString &rLHS, const OUString &rRHS, const uno::Reference< i18n::XCollator > &rCollator, const uno::Reference< i18n::XBreakIterator > &rBI, const lang::Locale &rLocale)
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
Returns number of tokens in an OUString.
OutputIter intersperse(ForwardIter start, ForwardIter end, OutputIter out, T const &separator)
algorithm similar to std::copy, but inserts a separator between elements.
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Copy from a container into a Sequence.
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
sal_uInt32 iterateCodePoints(std::u16string_view string, sal_Int32 *indexUtf16, sal_Int32 incrementCodePoints=1)
std::unique_ptr< char[]> aBuffer