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