LibreOffice Module comphelper (master) 1
string.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <cstddef>
23#include <string_view>
24#include <utility>
25#include <vector>
26#include <algorithm>
27
28#include <o3tl/safeint.hxx>
29#include <o3tl/string_view.hxx>
30#include <rtl/character.hxx>
31#include <rtl/ustring.hxx>
32#include <rtl/ustrbuf.hxx>
33#include <rtl/string.hxx>
34#include <rtl/strbuf.hxx>
35#include <sal/types.h>
36
37#include <comphelper/string.hxx>
40
41#include <com/sun/star/i18n/BreakIterator.hpp>
42#include <com/sun/star/i18n/CharType.hpp>
43#include <com/sun/star/i18n/Collator.hpp>
44
45
46namespace comphelper::string {
47
48namespace
49{
50 template <typename T, typename C> T tmpl_stripStart(const T &rIn,
51 const C cRemove)
52 {
53 if (rIn.empty())
54 return rIn;
55
56 typename T::size_type i = 0;
57
58 while (i < rIn.size())
59 {
60 if (rIn[i] != cRemove)
61 break;
62 ++i;
63 }
64
65 return rIn.substr(i);
66 }
67 template <typename T, typename C> T tmpl_stripStartString(const T &rIn,
68 const C cRemove)
69 {
70 if (rIn.isEmpty())
71 return rIn;
72
73 sal_Int32 i = 0;
74
75 while (i < rIn.getLength())
76 {
77 if (rIn[i] != cRemove)
78 break;
79 ++i;
80 }
81
82 return rIn.copy(i);
83 }
84}
85
86OString stripStart(const OString& rIn, char c)
87{
88 return tmpl_stripStartString<OString, char>(rIn, c);
89}
90
91std::string_view stripStart(std::string_view rIn, char c)
92{
93 return tmpl_stripStart<std::string_view, char>(rIn, c);
94}
95
96OUString stripStart(const OUString& rIn, sal_Unicode c)
97{
98 return tmpl_stripStartString<OUString, sal_Unicode>(rIn, c);
99}
100
101std::u16string_view stripStart(std::u16string_view rIn, sal_Unicode c)
102{
103 return tmpl_stripStart<std::u16string_view, sal_Unicode>(rIn, c);
104}
105
106namespace
107{
108 template <typename T, typename C> T tmpl_stripEnd(const T &rIn,
109 const C cRemove)
110 {
111 if (rIn.empty())
112 return rIn;
113
114 typename T::size_type i = rIn.size();
115
116 while (i > 0)
117 {
118 if (rIn[i-1] != cRemove)
119 break;
120 --i;
121 }
122
123 return rIn.substr(0, i);
124 }
125 template <typename T, typename C> T tmpl_stripEndString(const T &rIn,
126 const C cRemove)
127 {
128 if (rIn.isEmpty())
129 return rIn;
130
131 sal_Int32 i = rIn.getLength();
132
133 while (i > 0)
134 {
135 if (rIn[i-1] != cRemove)
136 break;
137 --i;
138 }
139
140 return rIn.copy(0, i);
141 }
142}
143
144OString stripEnd(const OString& rIn, char c)
145{
146 return tmpl_stripEndString<OString, char>(rIn, c);
147}
148
149std::string_view stripEnd(std::string_view rIn, char c)
150{
151 return tmpl_stripEnd<std::string_view, char>(rIn, c);
152}
153
154OUString stripEnd(const OUString& rIn, sal_Unicode c)
155{
156 return tmpl_stripEndString<OUString, sal_Unicode>(rIn, c);
157}
158
159std::u16string_view stripEnd(std::u16string_view rIn, sal_Unicode c)
160{
161 return tmpl_stripEnd<std::u16string_view, sal_Unicode>(rIn, c);
162}
163
164namespace
165{
166 template <typename T, typename C> T tmpl_strip(const T &rIn,
167 const C cRemove)
168 {
169 if (rIn.empty())
170 return rIn;
171
172 typename T::size_type end = rIn.size();
173 while (end > 0)
174 {
175 if (rIn[end-1] != cRemove)
176 break;
177 --end;
178 }
179
180 typename T::size_type start = 0;
181 while (start < end)
182 {
183 if (rIn[start] != cRemove)
184 break;
185 ++start;
186 }
187
188 return rIn.substr(start, end - start);
189 }
190 template <typename T, typename C> T tmpl_stripString(const T &rIn,
191 const C cRemove)
192 {
193 if (rIn.isEmpty())
194 return rIn;
195
196 sal_Int32 end = rIn.getLength();
197 while (end > 0)
198 {
199 if (rIn[end-1] != cRemove)
200 break;
201 --end;
202 }
203 sal_Int32 start = 0;
204 while (start < end)
205 {
206 if (rIn[start] != cRemove)
207 break;
208 ++start;
209 }
210
211 return rIn.copy(start, end - start);
212 }
213}
214
215OString strip(const OString& rIn, char c)
216{
217 return tmpl_stripString<OString, char>(rIn, c);
218}
219
220std::string_view strip(std::string_view rIn, char c)
221{
222 return tmpl_strip<std::string_view, char>(rIn, c);
223}
224
225OUString strip(const OUString& rIn, sal_Unicode c)
226{
227 return tmpl_stripString<OUString, sal_Unicode>(rIn, c);
228}
229
230std::u16string_view strip(std::u16string_view rIn, sal_Unicode c)
231{
232 return tmpl_strip<std::u16string_view, sal_Unicode>(rIn, c);
233}
234
235namespace
236{
237 template <typename T, typename C> sal_Int32 tmpl_getTokenCount( T rIn,
238 C cTok)
239 {
240 // Empty String: TokenCount by Definition is 0
241 if (rIn.empty())
242 return 0;
243
244 sal_Int32 nTokCount = 1;
245 for (typename T::size_type i = 0; i < rIn.size(); ++i)
246 {
247 if (rIn[i] == cTok)
248 ++nTokCount;
249 }
250 return nTokCount;
251 }
252}
253
254sal_Int32 getTokenCount(std::string_view rIn, char cTok)
255{
256 return tmpl_getTokenCount<std::string_view, char>(rIn, cTok);
257}
258
259sal_Int32 getTokenCount(std::u16string_view rIn, sal_Unicode cTok)
260{
261 return tmpl_getTokenCount<std::u16string_view, sal_Unicode>(rIn, cTok);
262}
263
264static sal_uInt32 decimalStringToNumber(
265 OUString const & str, sal_Int32 nStart, sal_Int32 nLength )
266{
267 sal_uInt32 result = 0;
268 for( sal_Int32 i = nStart; i < nStart + nLength; )
269 {
270 sal_uInt32 c = str.iterateCodePoints(&i);
271 sal_uInt32 value = 0;
272 if( c <= 0x0039) // ASCII decimal digits, most common
273 value = c - 0x0030;
274 else if( c >= 0x1D7F6 ) // mathematical monospace digits
275 value = c - 0x1D7F6;
276 else if( c >= 0x1D7EC ) // mathematical sans-serif bold digits
277 value = c - 0x1D7EC;
278 else if( c >= 0x1D7E2 ) // mathematical sans-serif digits
279 value = c - 0x1D7E2;
280 else if( c >= 0x1D7D8 ) // mathematical double-struck digits
281 value = c - 0x1D7D8;
282 else if( c >= 0x1D7CE ) // mathematical bold digits
283 value = c - 0x1D7CE;
284 else if( c >= 0x11066 ) // brahmi digits
285 value = c - 0x11066;
286 else if( c >= 0x104A0 ) // osmanya digits
287 value = c - 0x104A0;
288 else if( c >= 0xFF10 ) // fullwidth digits
289 value = c - 0xFF10;
290 else if( c >= 0xABF0 ) // meetei mayek digits
291 value = c - 0xABF0;
292 else if( c >= 0xAA50 ) // cham digits
293 value = c - 0xAA50;
294 else if( c >= 0xA9D0 ) // javanese digits
295 value = c - 0xA9D0;
296 else if( c >= 0xA900 ) // kayah li digits
297 value = c - 0xA900;
298 else if( c >= 0xA8D0 ) // saurashtra digits
299 value = c - 0xA8D0;
300 else if( c >= 0xA620 ) // vai digits
301 value = c - 0xA620;
302 else if( c >= 0x1C50 ) // ol chiki digits
303 value = c - 0x1C50;
304 else if( c >= 0x1C40 ) // lepcha digits
305 value = c - 0x1C40;
306 else if( c >= 0x1BB0 ) // sundanese digits
307 value = c - 0x1BB0;
308 else if( c >= 0x1B50 ) // balinese digits
309 value = c - 0x1B50;
310 else if( c >= 0x1A90 ) // tai tham tham digits
311 value = c - 0x1A90;
312 else if( c >= 0x1A80 ) // tai tham hora digits
313 value = c - 0x1A80;
314 else if( c >= 0x19D0 ) // new tai lue digits
315 value = c - 0x19D0;
316 else if( c >= 0x1946 ) // limbu digits
317 value = c - 0x1946;
318 else if( c >= 0x1810 ) // mongolian digits
319 value = c - 0x1810;
320 else if( c >= 0x17E0 ) // khmer digits
321 value = c - 0x17E0;
322 else if( c >= 0x1090 ) // myanmar shan digits
323 value = c - 0x1090;
324 else if( c >= 0x1040 ) // myanmar digits
325 value = c - 0x1040;
326 else if( c >= 0x0F20 ) // tibetan digits
327 value = c - 0x0F20;
328 else if( c >= 0x0ED0 ) // lao digits
329 value = c - 0x0ED0;
330 else if( c >= 0x0E50 ) // thai digits
331 value = c - 0x0E50;
332 else if( c >= 0x0D66 ) // malayalam digits
333 value = c - 0x0D66;
334 else if( c >= 0x0CE6 ) // kannada digits
335 value = c - 0x0CE6;
336 else if( c >= 0x0C66 ) // telugu digits
337 value = c - 0x0C66;
338 else if( c >= 0x0BE6 ) // tamil digits
339 value = c - 0x0BE6;
340 else if( c >= 0x0B66 ) // odia digits
341 value = c - 0x0B66;
342 else if( c >= 0x0AE6 ) // gujarati digits
343 value = c - 0x0AE6;
344 else if( c >= 0x0A66 ) // gurmukhi digits
345 value = c - 0x0A66;
346 else if( c >= 0x09E6 ) // bengali digits
347 value = c - 0x09E6;
348 else if( c >= 0x0966 ) // devanagari digit
349 value = c - 0x0966;
350 else if( c >= 0x07C0 ) // nko digits
351 value = c - 0x07C0;
352 else if( c >= 0x06F0 ) // extended arabic-indic digits
353 value = c - 0x06F0;
354 else if( c >= 0x0660 ) // arabic-indic digits
355 value = c - 0x0660;
356 result = result * 10 + value;
357 }
358 return result;
359}
360
362 OUString const & str )
363{
364 return decimalStringToNumber(str, 0, str.getLength());
365}
366
367using namespace ::com::sun::star;
368
369// convert between sequence of string and comma separated string
370
372 uno::Sequence< OUString > const& i_rSeq)
373{
374 OUStringBuffer buf;
376 i_rSeq.begin(), i_rSeq.end(), ::comphelper::OUStringBufferAppender(buf), OUString( ", " ));
377 return buf.makeStringAndClear();
378}
379
380std::vector<OUString>
381 split(std::u16string_view rStr, sal_Unicode cSeparator)
382{
383 std::vector< OUString > vec;
384 std::size_t idx = 0;
385 do
386 {
387 std::u16string_view kw = o3tl::getToken(rStr, cSeparator, idx);
388 kw = o3tl::trim(kw);
389 if (!kw.empty())
390 {
391 vec.push_back(OUString(kw));
392 }
393
394 } while (idx != std::u16string_view::npos);
395
396 return vec;
397}
398
399uno::Sequence< OUString >
400 convertCommaSeparated( std::u16string_view i_rString )
401{
402 std::vector< OUString > vec = split(i_rString, ',');
404}
405
406OString join(std::string_view rSeparator, const std::vector<OString>& rSequence)
407{
408 OStringBuffer aBuffer;
409 for (size_t i = 0; i < rSequence.size(); ++i)
410 {
411 if (i != 0)
412 aBuffer.append(rSeparator);
413 aBuffer.append(rSequence[i]);
414 }
415 return aBuffer.makeStringAndClear();
416}
417
418sal_Int32 compareNatural( const OUString & rLHS, const OUString & rRHS,
419 const uno::Reference< i18n::XCollator > &rCollator,
420 const uno::Reference< i18n::XBreakIterator > &rBI,
421 const lang::Locale &rLocale )
422{
423 sal_Int32 nRet = 0;
424
425 sal_Int32 nLHSLastNonDigitPos = 0;
426 sal_Int32 nRHSLastNonDigitPos = 0;
427 sal_Int32 nLHSFirstDigitPos = 0;
428 sal_Int32 nRHSFirstDigitPos = 0;
429
430 // Check if the string starts with a digit
431 sal_Int32 nStartsDigitLHS = rBI->endOfCharBlock(rLHS, nLHSFirstDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
432 sal_Int32 nStartsDigitRHS = rBI->endOfCharBlock(rRHS, nRHSFirstDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
433
434 if (nStartsDigitLHS > 0 && nStartsDigitRHS > 0)
435 {
436 sal_uInt32 nLHS = comphelper::string::decimalStringToNumber(rLHS, 0, nStartsDigitLHS);
437 sal_uInt32 nRHS = comphelper::string::decimalStringToNumber(rRHS, 0, nStartsDigitRHS);
438
439 if (nLHS != nRHS)
440 return nLHS < nRHS ? -1 : 1;
441 nLHSLastNonDigitPos = nStartsDigitLHS;
442 nRHSLastNonDigitPos = nStartsDigitRHS;
443 }
444 else if (nStartsDigitLHS > 0)
445 return -1;
446 else if (nStartsDigitRHS > 0)
447 return 1;
448
449 while (nLHSFirstDigitPos < rLHS.getLength() || nRHSFirstDigitPos < rRHS.getLength())
450 {
451 sal_Int32 nLHSChunkLen;
452 sal_Int32 nRHSChunkLen;
453
454 //Compare non digit block as normal strings
455 nLHSFirstDigitPos = rBI->nextCharBlock(rLHS, nLHSLastNonDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
456 nRHSFirstDigitPos = rBI->nextCharBlock(rRHS, nRHSLastNonDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
457
458 if (nLHSFirstDigitPos == -1)
459 nLHSFirstDigitPos = rLHS.getLength();
460
461 if (nRHSFirstDigitPos == -1)
462 nRHSFirstDigitPos = rRHS.getLength();
463
464 nLHSChunkLen = nLHSFirstDigitPos - nLHSLastNonDigitPos;
465 nRHSChunkLen = nRHSFirstDigitPos - nRHSLastNonDigitPos;
466
467 nRet = rCollator->compareSubstring(rLHS, nLHSLastNonDigitPos, nLHSChunkLen, rRHS, nRHSLastNonDigitPos, nRHSChunkLen);
468 if (nRet != 0)
469 break;
470
471 //Compare digit block as one number vs another
472 nLHSLastNonDigitPos = rBI->endOfCharBlock(rLHS, nLHSFirstDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
473 nRHSLastNonDigitPos = rBI->endOfCharBlock(rRHS, nRHSFirstDigitPos, rLocale, i18n::CharType::DECIMAL_DIGIT_NUMBER);
474 if (nLHSLastNonDigitPos == -1)
475 nLHSLastNonDigitPos = rLHS.getLength();
476 if (nRHSLastNonDigitPos == -1)
477 nRHSLastNonDigitPos = rRHS.getLength();
478 nLHSChunkLen = nLHSLastNonDigitPos - nLHSFirstDigitPos;
479 nRHSChunkLen = nRHSLastNonDigitPos - nRHSFirstDigitPos;
480
481 //To-Do: Possibly scale down those unicode codepoints that relate to
482 //numbers outside of the normal 0-9 range, e.g. see GetLocalizedChar in
483 //vcl
484
485 sal_uInt32 nLHS = comphelper::string::decimalStringToNumber(rLHS, nLHSFirstDigitPos, nLHSChunkLen);
486 sal_uInt32 nRHS = comphelper::string::decimalStringToNumber(rRHS, nRHSFirstDigitPos, nRHSChunkLen);
487
488 if (nLHS != nRHS)
489 {
490 nRet = (nLHS < nRHS) ? -1 : 1;
491 break;
492 }
493 }
494
495 return nRet;
496}
497
499 const uno::Reference< uno::XComponentContext > &rContext,
500 lang::Locale aLocale) : m_aLocale(std::move(aLocale))
501{
502 m_xCollator = i18n::Collator::create( rContext );
503 m_xCollator->loadDefaultCollator(m_aLocale, 0);
504 m_xBI = i18n::BreakIterator::create( rContext );
505}
506
507bool isdigitAsciiString(std::string_view rString)
508{
509 return std::all_of(
510 rString.data(), rString.data() + rString.size(),
511 [](unsigned char c){ return rtl::isAsciiDigit(c); });
512}
513
514bool isdigitAsciiString(std::u16string_view rString)
515{
516 return std::all_of(
517 rString.data(), rString.data() + rString.size(),
518 [](sal_Unicode c){ return rtl::isAsciiDigit(c); });
519}
520
521namespace
522{
523 template <typename T, typename I, typename O> T tmpl_reverseString(I rIn)
524 {
525 if (rIn.empty())
526 return T();
527
528 typename I::size_type i = rIn.size();
529 O sBuf(static_cast<sal_Int32>(i));
530 while (i)
531 sBuf.append(rIn[--i]);
532 return sBuf.makeStringAndClear();
533 }
534}
535
536OUString reverseString(std::u16string_view rStr)
537{
538 return tmpl_reverseString<OUString, std::u16string_view, OUStringBuffer>(rStr);
539}
540
541OString reverseString(std::string_view rStr)
542{
543 return tmpl_reverseString<OString, std::string_view, OStringBuffer>(rStr);
544}
545
546sal_Int32 indexOfAny(std::u16string_view rIn,
547 sal_Unicode const*const pChars, sal_Int32 const nPos)
548{
549 for (std::u16string_view::size_type i = nPos; i < rIn.size(); ++i)
550 {
551 sal_Unicode const c = rIn[i];
552 for (sal_Unicode const* pChar = pChars; *pChar; ++pChar)
553 {
554 if (c == *pChar)
555 {
556 return i;
557 }
558 }
559 }
560 return -1;
561}
562
563OUString removeAny(std::u16string_view rIn,
564 sal_Unicode const*const pChars)
565{
566 OUStringBuffer buf;
567 bool isFound(false);
568 for (std::u16string_view::size_type i = 0; i < rIn.size(); ++i)
569 {
570 sal_Unicode const c = rIn[i];
571 bool removeC(false);
572 for (sal_Unicode const* pChar = pChars; *pChar; ++pChar)
573 {
574 if (c == *pChar)
575 {
576 removeC = true;
577 break;
578 }
579 }
580 if (removeC)
581 {
582 if (!isFound)
583 {
584 if (i > 0)
585 {
586 buf.append(rIn.substr(0, i));
587 }
588 isFound = true;
589 }
590 }
591 else if (isFound)
592 {
593 buf.append(c);
594 }
595 }
596 return isFound ? buf.makeStringAndClear() : OUString(rIn);
597}
598
599OUString setToken(const OUString& rIn, sal_Int32 nToken, sal_Unicode cTok,
600 std::u16string_view rNewToken)
601{
602 sal_Int32 nLen = rIn.getLength();
603 sal_Int32 nTok = 0;
604 sal_Int32 nFirstChar = 0;
605 sal_Int32 i = 0;
606
607 // Determine token position and length
608 while ( i < nLen )
609 {
610 // Increase token count if match
611 if (rIn[i] == cTok)
612 {
613 ++nTok;
614
615 if (nTok == nToken)
616 nFirstChar = i+1;
617 else if (nTok > nToken)
618 break;
619 }
620
621 ++i;
622 }
623
624 if (nTok >= nToken)
625 return rIn.replaceAt(nFirstChar, i-nFirstChar, rNewToken);
626 return rIn;
627}
628
634void replaceAt(OUStringBuffer& rIn, sal_Int32 nIndex, sal_Int32 nCount, std::u16string_view newStr )
635{
636 assert(nIndex >= 0 && nIndex <= rIn.getLength());
637 assert(nCount >= 0);
638 assert(nCount <= rIn.getLength() - nIndex);
639
640 /* Append? */
641 const sal_Int32 nOldLength = rIn.getLength();
642 if ( nIndex == nOldLength )
643 {
644 rIn.append(newStr);
645 return;
646 }
647
648 sal_Int32 nNewLength = nOldLength + newStr.size() - nCount;
649 if (newStr.size() > o3tl::make_unsigned(nCount))
650 rIn.ensureCapacity(nOldLength + newStr.size() - nCount);
651
652 sal_Unicode* pStr = const_cast<sal_Unicode*>(rIn.getStr());
653 memmove(pStr + nIndex + newStr.size(), pStr + nIndex + nCount, nOldLength - nIndex + nCount);
654 memcpy(pStr + nIndex, newStr.data(), newStr.size());
655
656 rIn.setLength(nNewLength);
657}
658
659}
660
661/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
output iterator that appends OUStrings into an OUStringBuffer.
Definition: stl_types.hxx:126
css::lang::Locale const m_aLocale
Definition: string.hxx:347
NaturalStringSorter(const css::uno::Reference< css::uno::XComponentContext > &rContext, css::lang::Locale aLocale)
Definition: string.cxx:498
css::uno::Reference< css::i18n::XBreakIterator > m_xBI
Definition: string.hxx:349
css::uno::Reference< css::i18n::XCollator > m_xCollator
Definition: string.hxx:348
Any value
int nCount
std::u16string_view rNewToken
const sal_uInt16 idx[]
sal_Int32 nIndex
sal_uInt16 nPos
bool isdigitAsciiString(std::string_view rString)
Determine if an OString contains solely ASCII numeric digits.
Definition: string.cxx:507
OUString setToken(const OUString &rIn, sal_Int32 nToken, sal_Unicode cTok, std::u16string_view rNewToken)
Replace a token in a string.
Definition: string.cxx:599
OString join(std::string_view rSeparator, const std::vector< OString > &rSequence)
Return a string which is the concatenation of the strings in the sequence.
Definition: string.cxx:406
static sal_uInt32 decimalStringToNumber(OUString const &str, sal_Int32 nStart, sal_Int32 nLength)
Definition: string.cxx:264
OString strip(const OString &rIn, char c)
Strips occurrences of a character from the start and end of the source string.
Definition: string.cxx:215
OString stripEnd(const OString &rIn, char c)
Strips occurrences of a character from the end of the source string.
Definition: string.cxx:144
void replaceAt(OUStringBuffer &rIn, sal_Int32 nIndex, sal_Int32 nCount, std::u16string_view newStr)
Similar to OUString::replaceAt, but for an OUStringBuffer.
Definition: string.cxx:634
OUString reverseString(std::u16string_view rStr)
Reverse an OUString.
Definition: string.cxx:536
OUString removeAny(std::u16string_view rIn, sal_Unicode const *const pChars)
Remove any of a list of code units in the string.
Definition: string.cxx:563
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.
Definition: string.cxx:546
OUString convertCommaSeparated(uno::Sequence< OUString > const &i_rSeq)
Definition: string.cxx:371
OString stripStart(const OString &rIn, char c)
Strips occurrences of a character from the start of the source string.
Definition: string.cxx:86
std::vector< OUString > split(std::u16string_view rStr, sal_Unicode cSeparator)
Definition: string.cxx:381
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)
Definition: string.cxx:418
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
Returns number of tokens in an OUString.
Definition: string.cxx:254
OutputIter intersperse(ForwardIter start, ForwardIter end, OutputIter out, T const &separator)
algorithm similar to std::copy, but inserts a separator between elements.
Definition: stl_types.hxx:152
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Copy from a container into a Sequence.
Definition: sequence.hxx:190
int i
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 > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
std::u16string_view trim(std::u16string_view str)
end
DefTokenId nToken
std::locale m_aLocale
sal_uInt16 sal_Unicode
Any result
std::unique_ptr< char[]> aBuffer
const char * pChar
sal_Int32 nLength