1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
26 #include <config_options.h>
27 #include <o3tl/intcmp.hxx>
28 #include <o3tl/string_view.hxx>
29 #include <osl/diagnose.h>
30 #include <osl/interlck.h>
31 #include <osl/mutex.h>
32 #include <rtl/tencinfo.h>
34 #include <sal/log.hxx>
38 #include <rtl/character.hxx>
39 #include <rtl/ustring.h>
44 // Temporary check to verify that the #pragma pack around rtl_uString is indeed cargo cult and can
46 static_assert(alignof (rtl_uString
) == 4);
47 static_assert(sizeof (rtl_uString
) == 12);
50 /* ======================================================================= */
53 #define RTL_LOG_STRING_BITS 16
56 #include "strtmpl.hxx"
58 /* ======================================================================= */
60 sal_Int32
rtl_ustr_indexOfAscii_WithLength(
61 sal_Unicode
const * str
, sal_Int32 len
,
62 char const * subStr
, sal_Int32 subLen
) SAL_THROW_EXTERN_C()
64 return rtl::str::indexOfStr_WithLength(str
, len
, subStr
, subLen
);
67 sal_Int32
rtl_ustr_lastIndexOfAscii_WithLength(
68 sal_Unicode
const * str
, sal_Int32 len
,
69 char const * subStr
, sal_Int32 subLen
) SAL_THROW_EXTERN_C()
73 if (subLen
> 0 && subLen
<= len
) {
75 for (i
= len
- subLen
; i
>= 0; --i
) {
76 if (rtl_ustr_asciil_reverseEquals_WithLength(
77 str
+ i
, subStr
, subLen
))
86 sal_Int32 SAL_CALL
rtl_ustr_valueOfFloat(sal_Unicode
* pStr
, float f
)
89 return rtl::str::valueOfFP
<RTL_USTR_MAX_VALUEOFFLOAT
>(pStr
, f
);
92 sal_Int32 SAL_CALL
rtl_ustr_valueOfDouble(sal_Unicode
* pStr
, double d
)
95 return rtl::str::valueOfFP
<RTL_USTR_MAX_VALUEOFDOUBLE
>(pStr
, d
);
100 float doubleToFloat(double x
) {
101 return static_cast<float>(x
);
106 float SAL_CALL
rtl_ustr_toFloat(sal_Unicode
const * pStr
) SAL_THROW_EXTERN_C()
109 return doubleToFloat(rtl_math_uStringToDouble(pStr
,
110 pStr
+ rtl_ustr_getLength(pStr
),
111 '.', 0, nullptr, nullptr));
114 double SAL_CALL
rtl_ustr_toDouble(sal_Unicode
const * pStr
) SAL_THROW_EXTERN_C()
117 return rtl_math_uStringToDouble(pStr
, pStr
+ rtl_ustr_getLength(pStr
), '.',
118 0, nullptr, nullptr);
121 /* ======================================================================= */
123 sal_Int32 SAL_CALL
rtl_ustr_ascii_compare( const sal_Unicode
* pStr1
,
127 return rtl::str::compare(rtl::str::null_terminated(pStr1
), rtl::str::null_terminated(pStr2
),
128 rtl::str::CompareNormal(), rtl::str::noShortening
);
131 /* ----------------------------------------------------------------------- */
133 sal_Int32 SAL_CALL
rtl_ustr_ascii_compare_WithLength( const sal_Unicode
* pStr1
,
138 return rtl::str::compare(rtl::str::with_length(pStr1
, nStr1Len
),
139 rtl::str::null_terminated(pStr2
),
140 rtl::str::CompareNormal(), rtl::str::noShortening
);
143 /* ----------------------------------------------------------------------- */
145 sal_Int32 SAL_CALL
rtl_ustr_ascii_shortenedCompare_WithLength( const sal_Unicode
* pStr1
,
148 sal_Int32 nShortenedLength
)
151 return rtl::str::compare(rtl::str::with_length(pStr1
, nStr1Len
),
152 rtl::str::null_terminated(pStr2
),
153 rtl::str::CompareNormal(), nShortenedLength
);
156 /* ----------------------------------------------------------------------- */
158 sal_Int32 SAL_CALL
rtl_ustr_asciil_reverseCompare_WithLength( const sal_Unicode
* pStr1
,
164 return rtl::str::reverseCompare_WithLengths(pStr1
, nStr1Len
, pStr2
, nStr2Len
,
165 rtl::str::CompareNormal());
168 /* ----------------------------------------------------------------------- */
170 sal_Bool SAL_CALL
rtl_ustr_asciil_reverseEquals_WithLength( const sal_Unicode
* pStr1
,
175 assert(nStrLen
>= 0);
176 const sal_Unicode
* pStr1Run
= pStr1
+nStrLen
;
177 const char* pStr2Run
= pStr2
+nStrLen
;
178 while ( pStr1
< pStr1Run
)
182 SAL_WARN_IF( !rtl::isAscii(static_cast<unsigned char>(*pStr2Run
)), "rtl.string",
183 "rtl_ustr_asciil_reverseEquals_WithLength - Found char > 127" );
184 if( *pStr1Run
!= static_cast<sal_Unicode
>(*pStr2Run
) )
191 /* ----------------------------------------------------------------------- */
193 sal_Int32 SAL_CALL
rtl_ustr_ascii_compareIgnoreAsciiCase( const sal_Unicode
* pStr1
,
197 return rtl::str::compare(rtl::str::null_terminated(pStr1
), rtl::str::null_terminated(pStr2
),
198 rtl::str::CompareIgnoreAsciiCase(), rtl::str::noShortening
);
201 /* ----------------------------------------------------------------------- */
203 sal_Int32 SAL_CALL
rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( const sal_Unicode
* pStr1
,
208 return rtl::str::compare(rtl::str::with_length(pStr1
, nStr1Len
),
209 rtl::str::null_terminated(pStr2
),
210 rtl::str::CompareIgnoreAsciiCase(), rtl::str::noShortening
);
213 sal_Int32
rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
214 sal_Unicode
const * first
, sal_Int32 firstLen
,
215 char const * second
, sal_Int32 secondLen
) SAL_THROW_EXTERN_C()
217 return rtl::str::compare(rtl::str::with_length(first
, firstLen
),
218 rtl::str::with_length(second
, secondLen
),
219 rtl::str::CompareIgnoreAsciiCase(), rtl::str::noShortening
);
222 /* ----------------------------------------------------------------------- */
224 sal_Int32 SAL_CALL
rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( const sal_Unicode
* pStr1
,
227 sal_Int32 nShortenedLength
)
230 return rtl::str::compare(rtl::str::with_length(pStr1
, nStr1Len
),
231 rtl::str::null_terminated(pStr2
),
232 rtl::str::CompareIgnoreAsciiCase(), nShortenedLength
);
235 /* ----------------------------------------------------------------------- */
237 void SAL_CALL
rtl_uString_newFromAscii( rtl_uString
** ppThis
,
238 const char* pCharStr
)
242 sal_Int32 nLen
= pCharStr
? rtl::str::getLength(pCharStr
) : 0;
246 rtl_uString_new( ppThis
);
251 rtl_uString_release( *ppThis
);
253 *ppThis
= rtl_uString_ImplAlloc( nLen
);
254 OSL_ASSERT(*ppThis
!= nullptr);
258 sal_Unicode
* pBuffer
= (*ppThis
)->buffer
;
261 assert(static_cast<unsigned char>(*pCharStr
) < 0x80); // ASCII range
262 *pBuffer
= *pCharStr
;
268 RTL_LOG_STRING_NEW( *ppThis
);
271 void SAL_CALL
rtl_uString_newFromCodePoints(
272 rtl_uString
** newString
, sal_uInt32
const * codePoints
,
273 sal_Int32 codePointCount
) SAL_THROW_EXTERN_C()
278 assert(newString
!= nullptr);
279 assert((codePoints
!= nullptr || codePointCount
== 0) && codePointCount
>= 0);
280 if (codePointCount
== 0) {
281 rtl_uString_new(newString
);
284 if (*newString
!= nullptr) {
285 rtl_uString_release(*newString
);
288 for (i
= 0; i
< codePointCount
; ++i
) {
289 OSL_ASSERT(rtl::isUnicodeCodePoint(codePoints
[i
]));
290 if (codePoints
[i
] >= 0x10000) {
294 /* Builds on the assumption that sal_Int32 uses 32 bit two's complement
295 representation with wrap around (the necessary number of UTF-16 code
296 units will be no larger than 2 * SAL_MAX_INT32, represented as
299 // coverity[dead_error_begin] - assumes wrap around
300 *newString
= nullptr;
303 *newString
= rtl_uString_ImplAlloc(n
);
304 if (*newString
== nullptr) {
307 p
= (*newString
)->buffer
;
308 for (i
= 0; i
< codePointCount
; ++i
) {
309 p
+= rtl::splitSurrogates(codePoints
[i
], p
);
311 RTL_LOG_STRING_NEW( *newString
);
314 void rtl_uString_newConcatAsciiL(
315 rtl_uString
** newString
, rtl_uString
* left
, char const * right
,
316 sal_Int32 rightLength
)
318 rtl::str::newConcat(newString
, left
, right
, rightLength
);
321 void rtl_uString_newConcatUtf16L(
322 rtl_uString
** newString
, rtl_uString
* left
, sal_Unicode
const * right
,
323 sal_Int32 rightLength
)
325 rtl::str::newConcat(newString
, left
, right
, rightLength
);
328 /* ======================================================================= */
330 static int rtl_ImplGetFastUTF8UnicodeLen( const char* pStr
, sal_Int32 nLen
, bool * ascii
)
338 while ( pStr
< pEndStr
)
340 unsigned char c
= static_cast<unsigned char>(*pStr
);
346 if ( (c
& 0xE0) == 0xC0 )
348 else if ( (c
& 0xF0) == 0xE0 )
350 else if ( (c
& 0xF8) == 0xF0 )
352 else if ( (c
& 0xFC) == 0xF8 )
354 else if ( (c
& 0xFE) == 0xFC )
367 /* ----------------------------------------------------------------------- */
369 static void rtl_string2UString_status( rtl_uString
** ppThis
,
372 rtl_TextEncoding eTextEncoding
,
373 sal_uInt32 nCvtFlags
,
376 OSL_ENSURE(nLen
== 0 || rtl_isOctetTextEncoding(eTextEncoding
),
377 "rtl_string2UString_status() - Wrong TextEncoding" );
381 rtl_uString_new( ppThis
);
382 if (pInfo
!= nullptr) {
389 rtl_uString_release( *ppThis
);
391 /* Optimization for US-ASCII */
392 if ( eTextEncoding
== RTL_TEXTENCODING_ASCII_US
)
394 sal_Unicode
* pBuffer
;
395 *ppThis
= rtl_uString_ImplAlloc( nLen
);
396 if (*ppThis
== nullptr) {
397 if (pInfo
!= nullptr) {
398 *pInfo
= RTL_TEXTTOUNICODE_INFO_ERROR
|
399 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
;
403 pBuffer
= (*ppThis
)->buffer
;
404 sal_Int32
nLenCopy(nLen
);
405 const char *pStrCopy(pStr
);
408 /* Check ASCII range */
409 if (static_cast<unsigned char>(*pStrCopy
) > 127)
411 rtl_uString_release(*ppThis
);
412 goto retry
; // cancel loop - try again with the converter
415 *pBuffer
= *pStrCopy
;
421 if (pInfo
!= nullptr) {
424 RTL_LOG_STRING_NEW( *ppThis
);
430 rtl_uString
* pTemp2
= nullptr;
431 rtl_TextToUnicodeConverter hConverter
;
437 /* Optimization for UTF-8 - we try to calculate the exact length */
438 /* For all other encoding we try the maximum - and reallocate
439 the buffer if needed */
440 if ( eTextEncoding
== RTL_TEXTENCODING_UTF8
)
443 nNewLen
= rtl_ImplGetFastUTF8UnicodeLen( pStr
, nLen
, &ascii
);
444 /* Includes the string only ASCII, then we could copy
448 sal_Unicode
* pBuffer
;
449 *ppThis
= rtl_uString_ImplAlloc( nLen
);
450 if (*ppThis
== nullptr)
452 if (pInfo
!= nullptr) {
453 *pInfo
= RTL_TEXTTOUNICODE_INFO_ERROR
|
454 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
;
458 pBuffer
= (*ppThis
)->buffer
;
461 assert((static_cast<unsigned char>(*pStr
)) <= 127);
468 if (pInfo
!= nullptr) {
471 RTL_LOG_STRING_NEW( *ppThis
);
478 nCvtFlags
|= RTL_TEXTTOUNICODE_FLAGS_FLUSH
;
479 hConverter
= rtl_createTextToUnicodeConverter( eTextEncoding
);
481 pTemp
= rtl_uString_ImplAlloc( nNewLen
);
482 if (pTemp
== nullptr) {
483 if (pInfo
!= nullptr) {
484 *pInfo
= RTL_TEXTTOUNICODE_INFO_ERROR
|
485 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
;
489 nDestChars
= rtl_convertTextToUnicode( hConverter
, nullptr,
491 pTemp
->buffer
, nNewLen
,
493 &nInfo
, &nSrcBytes
);
495 /* Buffer not big enough, try again with enough space */
496 /* Shouldn't be the case, but if we get textencoding which
497 could results in more unicode characters we have this
498 code here. Could be the case for apple encodings */
499 while ( nInfo
& RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
)
501 rtl_freeString( pTemp
);
503 pTemp
= rtl_uString_ImplAlloc( nNewLen
);
504 if (pTemp
== nullptr) {
505 if (pInfo
!= nullptr) {
506 *pInfo
= RTL_TEXTTOUNICODE_INFO_ERROR
|
507 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
;
511 nDestChars
= rtl_convertTextToUnicode( hConverter
, nullptr,
513 pTemp
->buffer
, nNewLen
,
515 &nInfo
, &nSrcBytes
);
521 /* Set the buffer to the correct size or if there is too
522 much overhead, reallocate to the correct size */
523 if ( nNewLen
> nDestChars
+8 )
525 pTemp2
= rtl_uString_ImplAlloc( nDestChars
);
527 if (pTemp2
!= nullptr)
529 rtl::str::Copy(pTemp2
->buffer
, pTemp
->buffer
, nDestChars
);
530 rtl_freeString(pTemp
);
535 pTemp
->length
= nDestChars
;
536 pTemp
->buffer
[nDestChars
] = 0;
539 rtl_destroyTextToUnicodeConverter( hConverter
);
542 /* Results the conversion in an empty buffer -
543 create an empty string */
544 if ( pTemp
&& !nDestChars
)
545 rtl_uString_new( ppThis
);
548 RTL_LOG_STRING_NEW( *ppThis
);
551 void SAL_CALL
rtl_string2UString( rtl_uString
** ppThis
,
554 rtl_TextEncoding eTextEncoding
,
555 sal_uInt32 nCvtFlags
) SAL_THROW_EXTERN_C()
559 rtl_string2UString_status( ppThis
, pStr
, nLen
, eTextEncoding
,
560 nCvtFlags
, nullptr );
563 /* ----------------------------------------------------------------------- */
577 static oslMutex pPoolGuard
= osl_createMutex();
582 /* returns true if we found a dup in the pool */
583 static void rtl_ustring_intern_internal( rtl_uString
** newStr
,
585 StrLifecycle can_return
)
589 pPoolMutex
= getInternMutex();
591 osl_acquireMutex( pPoolMutex
);
593 *newStr
= rtl_str_hash_intern (str
, can_return
);
595 osl_releaseMutex( pPoolMutex
);
597 RTL_LOG_STRING_INTERN_NEW(*newStr
, str
);
599 if( can_return
&& *newStr
!= str
)
600 { /* we dupped, then found a match */
601 rtl_freeString( str
);
605 void SAL_CALL
rtl_uString_intern( rtl_uString
** newStr
,
606 rtl_uString
* str
) SAL_THROW_EXTERN_C()
610 if (SAL_STRING_IS_INTERN(str
))
612 rtl::str::acquire(str
);
617 rtl_uString
*pOrg
= *newStr
;
619 rtl_ustring_intern_internal( newStr
, str
, CANNOT_RETURN
);
621 rtl_uString_release (pOrg
);
625 static int rtl_canGuessUOutputLength( int len
, rtl_TextEncoding eTextEncoding
)
627 // FIXME: Maybe we should use a bit flag in the higher bits of the
628 // eTextEncoding value itself to determine the encoding type. But if we
629 // do, be sure to mask the value in certain places that expect the values
630 // to be numbered serially from 0 and up. One such place is
631 // Impl_getTextEncodingData().
633 switch ( eTextEncoding
)
635 // 1 to 1 (with no zero elements)
636 case RTL_TEXTENCODING_IBM_437
:
637 case RTL_TEXTENCODING_IBM_850
:
638 case RTL_TEXTENCODING_IBM_860
:
639 case RTL_TEXTENCODING_IBM_861
:
640 case RTL_TEXTENCODING_IBM_863
:
641 case RTL_TEXTENCODING_IBM_865
:
647 void SAL_CALL
rtl_uString_internConvert( rtl_uString
** newStr
,
650 rtl_TextEncoding eTextEncoding
,
651 sal_uInt32 convertFlags
,
657 rtl_uString
*scratch
;
661 rtl_uString_release (*newStr
);
666 { // try various optimisations
668 if ( eTextEncoding
== RTL_TEXTENCODING_ASCII_US
)
671 rtl_uString
*pScratch
;
672 pScratch
= static_cast< rtl_uString
* >(
673 alloca(sizeof (rtl_uString
) + len
* sizeof (sal_Unicode
)));
674 for (i
= 0; i
< len
; i
++)
676 /* Check ASCII range */
677 SAL_WARN_IF( !rtl::isAscii(static_cast<unsigned char>(str
[i
])), "rtl.string",
678 "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
679 pScratch
->buffer
[i
] = str
[i
];
681 pScratch
->length
= len
;
682 rtl_ustring_intern_internal( newStr
, pScratch
, CANNOT_RETURN
);
685 if ( (ulen
= rtl_canGuessUOutputLength(len
, eTextEncoding
)) != 0 )
687 rtl_uString
*pScratch
;
688 rtl_TextToUnicodeConverter hConverter
;
692 pScratch
= static_cast< rtl_uString
* >(
694 sizeof (rtl_uString
) + ulen
* sizeof (sal_Unicode
)));
696 hConverter
= rtl_createTextToUnicodeConverter( eTextEncoding
);
697 rtl_convertTextToUnicode(
698 hConverter
, nullptr, str
, len
, pScratch
->buffer
, ulen
, convertFlags
, &nInfo
, &nSrcBytes
);
699 rtl_destroyTextToUnicodeConverter( hConverter
);
704 pScratch
->length
= ulen
;
705 rtl_ustring_intern_internal( newStr
, pScratch
, CANNOT_RETURN
);
709 /* FIXME: we want a nice UTF-8 / alloca shortcut here */
713 rtl_string2UString_status( &scratch
, str
, len
, eTextEncoding
, convertFlags
,
718 rtl_ustring_intern_internal( newStr
, scratch
, CAN_RETURN
);
721 void internRelease (rtl_uString
*pThis
)
723 rtl_uString
*pFree
= nullptr;
724 if ( SAL_STRING_REFCOUNT(
725 osl_atomic_decrement( &(pThis
->refCount
) ) ) == 0)
727 RTL_LOG_STRING_INTERN_DELETE(pThis
);
728 oslMutex pPoolMutex
= getInternMutex();
729 osl_acquireMutex( pPoolMutex
);
731 rtl_str_hash_remove (pThis
);
733 /* May have been separately acquired */
734 if ( SAL_STRING_REFCOUNT(
735 osl_atomic_increment( &(pThis
->refCount
) ) ) == 1 )
737 /* we got the last ref */
740 else /* very unusual */
742 internRelease (pThis
);
745 osl_releaseMutex( pPoolMutex
);
748 rtl_freeString (pFree
);
751 sal_uInt32 SAL_CALL
rtl_uString_iterateCodePoints(
752 rtl_uString
const * string
, sal_Int32
* indexUtf16
,
753 sal_Int32 incrementCodePoints
)
755 assert(string
!= nullptr && indexUtf16
!= nullptr);
758 && o3tl::cmp_less_equal(*indexUtf16
, std::numeric_limits
<std::size_t>::max()));
759 // using o3tl::cmp_less_equal nicely avoids potential
760 // -Wtautological-constant-out-of-range-compare
761 auto const cp
= o3tl::iterateCodePoints(
762 std::u16string_view(string
->buffer
, string
->length
), indexUtf16
, incrementCodePoints
);
766 sal_Bool
rtl_convertStringToUString(
767 rtl_uString
** target
, char const * source
, sal_Int32 length
,
768 rtl_TextEncoding encoding
, sal_uInt32 flags
) SAL_THROW_EXTERN_C()
773 rtl_string2UString_status(target
, source
, length
, encoding
, flags
, &info
);
774 return (info
& RTL_TEXTTOUNICODE_INFO_ERROR
) == 0;
777 void rtl_uString_newReplaceFirst(
778 rtl_uString
** newStr
, rtl_uString
* str
, rtl_uString
const * from
,
779 rtl_uString
const * to
, sal_Int32
* index
) SAL_THROW_EXTERN_C()
781 assert(from
!= nullptr);
782 assert(to
!= nullptr);
783 rtl_uString_newReplaceFirstUtf16LUtf16L(newStr
, str
, from
->buffer
, from
->length
, to
->buffer
,
787 void rtl_uString_newReplaceFirstAsciiL(
788 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
789 sal_Int32 fromLength
, rtl_uString
const * to
, sal_Int32
* index
)
792 assert(to
!= nullptr);
793 rtl_uString_newReplaceFirstAsciiLUtf16L(newStr
, str
, from
, fromLength
, to
->buffer
, to
->length
,
797 void rtl_uString_newReplaceFirstToAsciiL(
798 rtl_uString
** newStr
, rtl_uString
* str
, rtl_uString
const * from
,
799 char const * to
, sal_Int32 toLength
, sal_Int32
* index
)
802 assert(from
!= nullptr);
803 rtl_uString_newReplaceFirstUtf16LAsciiL(newStr
, str
, from
->buffer
, from
->length
, to
, toLength
,
807 void rtl_uString_newReplaceFirstAsciiLAsciiL(
808 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
809 sal_Int32 fromLength
, char const * to
, sal_Int32 toLength
,
810 sal_Int32
* index
) SAL_THROW_EXTERN_C()
812 assert(index
!= nullptr);
813 rtl::str::newReplaceFirst(newStr
, str
, from
, fromLength
, to
, toLength
, *index
);
816 void rtl_uString_newReplaceFirstAsciiLUtf16L(
817 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
818 sal_Int32 fromLength
, sal_Unicode
const * to
, sal_Int32 toLength
,
819 sal_Int32
* index
) SAL_THROW_EXTERN_C()
821 assert(index
!= nullptr);
822 rtl::str::newReplaceFirst(newStr
, str
, from
, fromLength
, to
, toLength
, *index
);
825 void rtl_uString_newReplaceFirstUtf16LAsciiL(
826 rtl_uString
** newStr
, rtl_uString
* str
, sal_Unicode
const * from
,
827 sal_Int32 fromLength
, char const * to
, sal_Int32 toLength
,
828 sal_Int32
* index
) SAL_THROW_EXTERN_C()
830 assert(index
!= nullptr);
831 rtl::str::newReplaceFirst(newStr
, str
, from
, fromLength
, to
, toLength
, *index
);
834 void rtl_uString_newReplaceFirstUtf16LUtf16L(
835 rtl_uString
** newStr
, rtl_uString
* str
, sal_Unicode
const * from
,
836 sal_Int32 fromLength
, sal_Unicode
const * to
, sal_Int32 toLength
,
837 sal_Int32
* index
) SAL_THROW_EXTERN_C()
839 assert(index
!= nullptr);
840 rtl::str::newReplaceFirst(newStr
, str
, from
, fromLength
, to
, toLength
, *index
);
843 void rtl_uString_newReplaceAll(
844 rtl_uString
** newStr
, rtl_uString
* str
, rtl_uString
const * from
,
845 rtl_uString
const * to
) SAL_THROW_EXTERN_C()
847 rtl_uString_newReplaceAllFromIndex( newStr
, str
, from
, to
, 0 );
850 void rtl_uString_newReplaceAllFromIndex(
851 rtl_uString
** newStr
, rtl_uString
* str
, rtl_uString
const * from
,
852 rtl_uString
const * to
, sal_Int32 fromIndex
) SAL_THROW_EXTERN_C()
854 assert(to
!= nullptr);
855 assert(fromIndex
>= 0 && fromIndex
<= str
->length
);
856 rtl_uString_newReplaceAllFromIndexUtf16LUtf16L(newStr
, str
, from
->buffer
, from
->length
,
857 to
->buffer
, to
->length
, fromIndex
);
860 void rtl_uString_newReplaceAllAsciiL(
861 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
862 sal_Int32 fromLength
, rtl_uString
const * to
) SAL_THROW_EXTERN_C()
864 assert(to
!= nullptr);
865 rtl_uString_newReplaceAllAsciiLUtf16L(newStr
, str
, from
, fromLength
, to
->buffer
, to
->length
);
868 void rtl_uString_newReplaceAllToAsciiL(
869 rtl_uString
** newStr
, rtl_uString
* str
, rtl_uString
const * from
,
870 char const * to
, sal_Int32 toLength
) SAL_THROW_EXTERN_C()
872 assert(from
!= nullptr);
873 rtl_uString_newReplaceAllUtf16LAsciiL(newStr
, str
, from
->buffer
, from
->length
, to
, toLength
);
876 void rtl_uString_newReplaceAllAsciiLAsciiL(
877 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
878 sal_Int32 fromLength
, char const * to
, sal_Int32 toLength
)
881 rtl::str::newReplaceAllFromIndex(newStr
, str
, from
, fromLength
, to
, toLength
, 0);
884 void rtl_uString_newReplaceAllAsciiLUtf16L(
885 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
886 sal_Int32 fromLength
, sal_Unicode
const * to
, sal_Int32 toLength
)
889 rtl::str::newReplaceAllFromIndex(newStr
, str
, from
, fromLength
, to
, toLength
, 0);
892 void rtl_uString_newReplaceAllUtf16LAsciiL(
893 rtl_uString
** newStr
, rtl_uString
* str
, sal_Unicode
const * from
,
894 sal_Int32 fromLength
, char const * to
, sal_Int32 toLength
)
897 rtl::str::newReplaceAllFromIndex(newStr
, str
, from
, fromLength
, to
, toLength
, 0);
900 void rtl_uString_newReplaceAllUtf16LUtf16L(
901 rtl_uString
** newStr
, rtl_uString
* str
, sal_Unicode
const * from
,
902 sal_Int32 fromLength
, sal_Unicode
const * to
, sal_Int32 toLength
)
905 rtl_uString_newReplaceAllFromIndexUtf16LUtf16L(newStr
, str
, from
, fromLength
, to
, toLength
, 0);
908 void rtl_uString_newReplaceAllFromIndexUtf16LUtf16L(
909 rtl_uString
** newStr
, rtl_uString
* str
, sal_Unicode
const * from
,
910 sal_Int32 fromLength
, sal_Unicode
const * to
, sal_Int32 toLength
, sal_Int32 fromIndex
)
913 rtl::str::newReplaceAllFromIndex(newStr
, str
, from
, fromLength
, to
, toLength
, fromIndex
);
916 sal_Int32 SAL_CALL
rtl_ustr_getLength(const sal_Unicode
* pStr
) SAL_THROW_EXTERN_C()
918 return rtl::str::getLength(pStr
);
921 sal_Int32 SAL_CALL
rtl_ustr_compare(const sal_Unicode
* pStr1
, const sal_Unicode
* pStr2
)
924 return rtl::str::compare(rtl::str::null_terminated(pStr1
), rtl::str::null_terminated(pStr2
),
925 rtl::str::CompareNormal(), rtl::str::noShortening
);
928 sal_Int32 SAL_CALL
rtl_ustr_compare_WithLength(const sal_Unicode
* pStr1
, sal_Int32 nStr1Len
,
929 const sal_Unicode
* pStr2
, sal_Int32 nStr2Len
)
932 return rtl::str::compare(rtl::str::with_length(pStr1
, nStr1Len
),
933 rtl::str::with_length(pStr2
, nStr2Len
), rtl::str::CompareNormal(),
934 rtl::str::noShortening
);
937 sal_Int32 SAL_CALL
rtl_ustr_shortenedCompare_WithLength(
938 const sal_Unicode
* pStr1
, sal_Int32 nStr1Len
, const sal_Unicode
* pStr2
, sal_Int32 nStr2Len
,
939 sal_Int32 nShortenedLength
) SAL_THROW_EXTERN_C()
941 return rtl::str::compare(rtl::str::with_length(pStr1
, nStr1Len
),
942 rtl::str::with_length(pStr2
, nStr2Len
), rtl::str::CompareNormal(),
946 sal_Int32 SAL_CALL
rtl_ustr_reverseCompare_WithLength(const sal_Unicode
* pStr1
, sal_Int32 nStr1Len
,
947 const sal_Unicode
* pStr2
, sal_Int32 nStr2Len
)
950 return rtl::str::reverseCompare_WithLengths(pStr1
, nStr1Len
, pStr2
, nStr2Len
,
951 rtl::str::CompareNormal());
954 sal_Int32 SAL_CALL
rtl_ustr_compareIgnoreAsciiCase(const sal_Unicode
* pStr1
,
955 const sal_Unicode
* pStr2
) SAL_THROW_EXTERN_C()
957 return rtl::str::compare(rtl::str::null_terminated(pStr1
), rtl::str::null_terminated(pStr2
),
958 rtl::str::CompareIgnoreAsciiCase(), rtl::str::noShortening
);
961 sal_Int32 SAL_CALL
rtl_ustr_compareIgnoreAsciiCase_WithLength(const sal_Unicode
* pStr1
,
963 const sal_Unicode
* pStr2
,
967 return rtl::str::compare(rtl::str::with_length(pStr1
, nStr1Len
),
968 rtl::str::with_length(pStr2
, nStr2Len
),
969 rtl::str::CompareIgnoreAsciiCase(), rtl::str::noShortening
);
972 sal_Int32 SAL_CALL
rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength(
973 const sal_Unicode
* pStr1
, sal_Int32 nStr1Len
, const sal_Unicode
* pStr2
, sal_Int32 nStr2Len
,
974 sal_Int32 nShortenedLength
) SAL_THROW_EXTERN_C()
976 return rtl::str::compare(rtl::str::with_length(pStr1
, nStr1Len
),
977 rtl::str::with_length(pStr2
, nStr2Len
),
978 rtl::str::CompareIgnoreAsciiCase(), nShortenedLength
);
981 sal_Int32 SAL_CALL
rtl_ustr_hashCode(const sal_Unicode
* pStr
) SAL_THROW_EXTERN_C()
983 return rtl::str::hashCode(pStr
);
986 sal_Int32 SAL_CALL
rtl_ustr_hashCode_WithLength(const sal_Unicode
* pStr
, sal_Int32 nLen
)
989 return rtl::str::hashCode_WithLength(pStr
, nLen
);
992 sal_Int32 SAL_CALL
rtl_ustr_indexOfChar(const sal_Unicode
* pStr
, sal_Unicode c
) SAL_THROW_EXTERN_C()
994 return rtl::str::indexOfChar(pStr
, c
);
997 sal_Int32 SAL_CALL
rtl_ustr_indexOfChar_WithLength(const sal_Unicode
* pStr
, sal_Int32 nLen
,
998 sal_Unicode c
) SAL_THROW_EXTERN_C()
1000 return rtl::str::indexOfChar_WithLength(pStr
, nLen
, c
);
1003 sal_Int32 SAL_CALL
rtl_ustr_lastIndexOfChar(const sal_Unicode
* pStr
, sal_Unicode c
)
1004 SAL_THROW_EXTERN_C()
1006 return rtl::str::lastIndexOfChar(pStr
, c
);
1009 sal_Int32 SAL_CALL
rtl_ustr_lastIndexOfChar_WithLength(const sal_Unicode
* pStr
, sal_Int32 nLen
,
1010 sal_Unicode c
) SAL_THROW_EXTERN_C()
1012 return rtl::str::lastIndexOfChar_WithLength(pStr
, nLen
, c
);
1015 sal_Int32 SAL_CALL
rtl_ustr_indexOfStr(const sal_Unicode
* pStr
, const sal_Unicode
* pSubStr
)
1016 SAL_THROW_EXTERN_C()
1018 return rtl::str::indexOfStr(pStr
, pSubStr
);
1021 sal_Int32 SAL_CALL
rtl_ustr_indexOfStr_WithLength(const sal_Unicode
* pStr
, sal_Int32 nStrLen
,
1022 const sal_Unicode
* pSubStr
, sal_Int32 nSubLen
)
1023 SAL_THROW_EXTERN_C()
1025 return rtl::str::indexOfStr_WithLength(pStr
, nStrLen
, pSubStr
, nSubLen
);
1028 sal_Int32 SAL_CALL
rtl_ustr_lastIndexOfStr(const sal_Unicode
* pStr
, const sal_Unicode
* pSubStr
)
1029 SAL_THROW_EXTERN_C()
1031 return rtl::str::lastIndexOfStr(pStr
, pSubStr
);
1034 sal_Int32 SAL_CALL
rtl_ustr_lastIndexOfStr_WithLength(const sal_Unicode
* pStr
, sal_Int32 nStrLen
,
1035 const sal_Unicode
* pSubStr
, sal_Int32 nSubLen
)
1036 SAL_THROW_EXTERN_C()
1038 return rtl::str::lastIndexOfStr_WithLength(pStr
, nStrLen
, pSubStr
, nSubLen
);
1041 void SAL_CALL
rtl_ustr_replaceChar(sal_Unicode
* pStr
, sal_Unicode cOld
, sal_Unicode cNew
)
1042 SAL_THROW_EXTERN_C()
1044 return rtl::str::replaceChars(rtl::str::null_terminated(pStr
), rtl::str::FromTo(cOld
, cNew
));
1047 void SAL_CALL
rtl_ustr_replaceChar_WithLength(sal_Unicode
* pStr
, sal_Int32 nLen
, sal_Unicode cOld
,
1048 sal_Unicode cNew
) SAL_THROW_EXTERN_C()
1050 return rtl::str::replaceChars(rtl::str::with_length(pStr
, nLen
), rtl::str::FromTo(cOld
, cNew
));
1053 void SAL_CALL
rtl_ustr_toAsciiLowerCase(sal_Unicode
* pStr
) SAL_THROW_EXTERN_C()
1055 return rtl::str::replaceChars(rtl::str::null_terminated(pStr
), rtl::str::toAsciiLower
);
1058 void SAL_CALL
rtl_ustr_toAsciiLowerCase_WithLength(sal_Unicode
* pStr
, sal_Int32 nLen
)
1059 SAL_THROW_EXTERN_C()
1061 return rtl::str::replaceChars(rtl::str::with_length(pStr
, nLen
), rtl::str::toAsciiLower
);
1064 void SAL_CALL
rtl_ustr_toAsciiUpperCase(sal_Unicode
* pStr
) SAL_THROW_EXTERN_C()
1066 return rtl::str::replaceChars(rtl::str::null_terminated(pStr
), rtl::str::toAsciiUpper
);
1069 void SAL_CALL
rtl_ustr_toAsciiUpperCase_WithLength(sal_Unicode
* pStr
, sal_Int32 nLen
)
1070 SAL_THROW_EXTERN_C()
1072 return rtl::str::replaceChars(rtl::str::with_length(pStr
, nLen
), rtl::str::toAsciiUpper
);
1075 sal_Int32 SAL_CALL
rtl_ustr_trim(sal_Unicode
* pStr
) SAL_THROW_EXTERN_C()
1077 return rtl::str::trim(pStr
);
1080 sal_Int32 SAL_CALL
rtl_ustr_trim_WithLength(sal_Unicode
* pStr
, sal_Int32 nLen
) SAL_THROW_EXTERN_C()
1082 return rtl::str::trim_WithLength(pStr
, nLen
);
1085 sal_Int32 SAL_CALL
rtl_ustr_valueOfBoolean(sal_Unicode
* pStr
, sal_Bool b
) SAL_THROW_EXTERN_C()
1087 return rtl::str::valueOfBoolean(pStr
, b
);
1090 sal_Int32 SAL_CALL
rtl_ustr_valueOfChar(sal_Unicode
* pStr
, sal_Unicode c
) SAL_THROW_EXTERN_C()
1092 return rtl::str::valueOfChar(pStr
, c
);
1095 sal_Int32 SAL_CALL
rtl_ustr_valueOfInt32(sal_Unicode
* pStr
, sal_Int32 n
, sal_Int16 nRadix
)
1096 SAL_THROW_EXTERN_C()
1098 return rtl::str::valueOfInt
<RTL_USTR_MAX_VALUEOFINT32
>(pStr
, n
, nRadix
);
1101 sal_Int32 SAL_CALL
rtl_ustr_valueOfInt64(sal_Unicode
* pStr
, sal_Int64 n
, sal_Int16 nRadix
)
1102 SAL_THROW_EXTERN_C()
1104 return rtl::str::valueOfInt
<RTL_USTR_MAX_VALUEOFINT64
>(pStr
, n
, nRadix
);
1107 sal_Int32 SAL_CALL
rtl_ustr_valueOfUInt64(sal_Unicode
* pStr
, sal_uInt64 n
, sal_Int16 nRadix
)
1108 SAL_THROW_EXTERN_C()
1110 return rtl::str::valueOfInt
<RTL_USTR_MAX_VALUEOFUINT64
>(pStr
, n
, nRadix
);
1113 sal_Bool SAL_CALL
rtl_ustr_toBoolean(const sal_Unicode
* pStr
) SAL_THROW_EXTERN_C()
1115 return rtl::str::toBoolean(pStr
);
1118 sal_Int32 SAL_CALL
rtl_ustr_toInt32(const sal_Unicode
* pStr
, sal_Int16 nRadix
) SAL_THROW_EXTERN_C()
1120 return rtl::str::toInt
<sal_Int32
>(rtl::str::null_terminated(pStr
), nRadix
);
1123 sal_Int64 SAL_CALL
rtl_ustr_toInt64(const sal_Unicode
* pStr
, sal_Int16 nRadix
) SAL_THROW_EXTERN_C()
1125 return rtl::str::toInt
<sal_Int64
>(rtl::str::null_terminated(pStr
), nRadix
);
1128 sal_Int64 SAL_CALL
rtl_ustr_toInt64_WithLength(const sal_Unicode
* pStr
, sal_Int16 nRadix
,
1129 sal_Int32 nStrLength
) SAL_THROW_EXTERN_C()
1131 return rtl::str::toInt
<sal_Int64
>(rtl::str::with_length(pStr
, nStrLength
), nRadix
);
1134 sal_uInt32 SAL_CALL
rtl_ustr_toUInt32(const sal_Unicode
* pStr
, sal_Int16 nRadix
)
1135 SAL_THROW_EXTERN_C()
1137 return rtl::str::toInt
<sal_uInt32
>(rtl::str::null_terminated(pStr
), nRadix
);
1140 sal_uInt64 SAL_CALL
rtl_ustr_toUInt64(const sal_Unicode
* pStr
, sal_Int16 nRadix
)
1141 SAL_THROW_EXTERN_C()
1143 return rtl::str::toInt
<sal_uInt64
>(rtl::str::null_terminated(pStr
), nRadix
);
1146 rtl_uString
* rtl_uString_ImplAlloc(sal_Int32 nLen
)
1148 return rtl::str::Alloc
<rtl_uString
>(nLen
);
1151 void SAL_CALL
rtl_uString_acquire(rtl_uString
* pThis
) SAL_THROW_EXTERN_C()
1153 return rtl::str::acquire(pThis
);
1156 void SAL_CALL
rtl_uString_release(rtl_uString
* pThis
) SAL_THROW_EXTERN_C()
1158 return rtl::str::release(pThis
);
1161 void SAL_CALL
rtl_uString_new(rtl_uString
** ppThis
) SAL_THROW_EXTERN_C()
1163 return rtl::str::new_(ppThis
);
1166 rtl_uString
* SAL_CALL
rtl_uString_alloc(sal_Int32 nLen
) SAL_THROW_EXTERN_C()
1169 return rtl::str::Alloc
<rtl_uString
>(nLen
);
1172 void SAL_CALL
rtl_uString_new_WithLength(rtl_uString
** ppThis
, sal_Int32 nLen
) SAL_THROW_EXTERN_C()
1174 rtl::str::new_WithLength(ppThis
, nLen
);
1177 void SAL_CALL
rtl_uString_newFromString(rtl_uString
** ppThis
, const rtl_uString
* pStr
)
1178 SAL_THROW_EXTERN_C()
1180 rtl::str::newFromString(ppThis
, pStr
);
1183 void SAL_CALL
rtl_uString_newFromStr(rtl_uString
** ppThis
, const sal_Unicode
* pCharStr
)
1184 SAL_THROW_EXTERN_C()
1186 rtl::str::newFromStr(ppThis
, pCharStr
);
1189 void SAL_CALL
rtl_uString_newFromStr_WithLength(rtl_uString
** ppThis
, const sal_Unicode
* pCharStr
,
1190 sal_Int32 nLen
) SAL_THROW_EXTERN_C()
1192 rtl::str::newFromStr_WithLength(ppThis
, pCharStr
, nLen
);
1195 void SAL_CALL
rtl_uString_newFromSubString(rtl_uString
** ppThis
, const rtl_uString
* pFrom
,
1196 sal_Int32 beginIndex
, sal_Int32 count
)
1197 SAL_THROW_EXTERN_C()
1199 rtl::str::newFromSubString(ppThis
, pFrom
, beginIndex
, count
);
1202 // Used when creating from string literals.
1203 void SAL_CALL
rtl_uString_newFromLiteral(rtl_uString
** ppThis
, const char* pCharStr
, sal_Int32 nLen
,
1204 sal_Int32 allocExtra
) SAL_THROW_EXTERN_C()
1206 rtl::str::newFromStr_WithLength(ppThis
, pCharStr
, nLen
, allocExtra
);
1209 void SAL_CALL
rtl_uString_assign(rtl_uString
** ppThis
, rtl_uString
* pStr
) SAL_THROW_EXTERN_C()
1211 rtl::str::assign(ppThis
, pStr
);
1214 sal_Int32 SAL_CALL
rtl_uString_getLength(const rtl_uString
* pThis
) SAL_THROW_EXTERN_C()
1216 return rtl::str::getLength(pThis
);
1219 sal_Unicode
* SAL_CALL
rtl_uString_getStr(rtl_uString
* pThis
) SAL_THROW_EXTERN_C()
1221 return rtl::str::getStr(pThis
);
1224 void SAL_CALL
rtl_uString_newConcat(rtl_uString
** ppThis
, rtl_uString
* pLeft
, rtl_uString
* pRight
)
1225 SAL_THROW_EXTERN_C()
1227 rtl::str::newConcat(ppThis
, pLeft
, pRight
);
1230 void SAL_CALL
rtl_uString_ensureCapacity(rtl_uString
** ppThis
, sal_Int32 size
) SAL_THROW_EXTERN_C()
1232 rtl::str::ensureCapacity(ppThis
, size
);
1235 void SAL_CALL
rtl_uString_newReplaceStrAt(rtl_uString
** ppThis
, rtl_uString
* pStr
, sal_Int32 nIndex
,
1236 sal_Int32 nCount
, rtl_uString
* pNewSubStr
)
1237 SAL_THROW_EXTERN_C()
1239 rtl::str::newReplaceStrAt(ppThis
, pStr
, nIndex
, nCount
, pNewSubStr
);
1242 void SAL_CALL
rtl_uString_newReplaceStrAtUtf16L(rtl_uString
** ppThis
, rtl_uString
* pStr
, sal_Int32 nIndex
,
1243 sal_Int32 nCount
, sal_Unicode
const * subStr
, sal_Int32 substrLen
)
1244 SAL_THROW_EXTERN_C()
1246 rtl::str::newReplaceStrAt(ppThis
, pStr
, nIndex
, nCount
, subStr
, substrLen
);
1249 void SAL_CALL
rtl_uString_newReplace(rtl_uString
** ppThis
, rtl_uString
* pStr
, sal_Unicode cOld
,
1250 sal_Unicode cNew
) SAL_THROW_EXTERN_C()
1252 rtl::str::newReplaceChars(ppThis
, pStr
, rtl::str::FromTo(cOld
, cNew
));
1255 void SAL_CALL
rtl_uString_newToAsciiLowerCase(rtl_uString
** ppThis
, rtl_uString
* pStr
)
1256 SAL_THROW_EXTERN_C()
1258 rtl::str::newReplaceChars(ppThis
, pStr
, rtl::str::toAsciiLower
);
1261 void SAL_CALL
rtl_uString_newToAsciiUpperCase(rtl_uString
** ppThis
, rtl_uString
* pStr
)
1262 SAL_THROW_EXTERN_C()
1264 rtl::str::newReplaceChars(ppThis
, pStr
, rtl::str::toAsciiUpper
);
1267 void SAL_CALL
rtl_uString_newTrim(rtl_uString
** ppThis
, rtl_uString
* pStr
) SAL_THROW_EXTERN_C()
1269 rtl::str::newTrim(ppThis
, pStr
);
1272 sal_Int32 SAL_CALL
rtl_uString_getToken(rtl_uString
** ppThis
, rtl_uString
* pStr
, sal_Int32 nToken
,
1273 sal_Unicode cTok
, sal_Int32 nIndex
) SAL_THROW_EXTERN_C()
1275 return rtl::str::getToken(ppThis
, pStr
, nToken
, cTok
, nIndex
);
1278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */