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>
28 #include <osl/diagnose.h>
29 #include <osl/interlck.h>
30 #include <rtl/alloc.h>
31 #include <osl/mutex.h>
32 #include <rtl/tencinfo.h>
35 #include <sal/alloca.h>
36 #include <sal/log.hxx>
40 #include <rtl/character.hxx>
41 #include <rtl/ustring.h>
45 /* ======================================================================= */
47 /* static data to be referenced by all empty strings
48 * the refCount is predefined to 1 and must never become 0 !
50 static rtl_uString
const aImplEmpty_rtl_uString
=
52 sal_Int32(SAL_STRING_INTERN_FLAG
|SAL_STRING_STATIC_FLAG
|1), /*sal_Int32 refCount; */
53 0, /*sal_Int32 length; */
54 { 0 } /*sal_Unicode buffer[1];*/
57 /* ======================================================================= */
58 /* These macros are for the "poor-man templates" included from
59 * the strtmpl.cxx just below, used to share code between here and
63 #define IMPL_RTL_IS_USTRING 1
65 #define IMPL_RTL_STRCODE sal_Unicode
66 #define IMPL_RTL_USTRCODE( c ) (c)
67 #define IMPL_RTL_STRNAME( n ) rtl_ustr_ ## n
69 #define IMPL_RTL_STRINGNAME( n ) rtl_uString_ ## n
70 #define IMPL_RTL_STRINGDATA rtl_uString
71 #define IMPL_RTL_EMPTYSTRING aImplEmpty_rtl_uString
73 static void internRelease (rtl_uString
*pThis
);
76 #define RTL_LOG_STRING_BITS 16
79 /* ======================================================================= */
81 /* Include String/UString template code */
83 #include "strtmpl.cxx"
85 #undef IMPL_RTL_EMPTYSTRING
86 #undef IMPL_RTL_IS_USTRING
87 #undef IMPL_RTL_STRCODE
88 #undef IMPL_RTL_STRINGDATA
89 #undef IMPL_RTL_STRINGNAME
90 #undef IMPL_RTL_STRNAME
91 #undef IMPL_RTL_USTRCODE
92 #undef RTL_LOG_STRING_BITS
94 sal_Int32
rtl_ustr_indexOfAscii_WithLength(
95 sal_Unicode
const * str
, sal_Int32 len
,
96 char const * subStr
, sal_Int32 subLen
) SAL_THROW_EXTERN_C()
100 if (subLen
> 0 && subLen
<= len
)
102 sal_Unicode
const* end
= str
+ len
;
103 sal_Unicode
const* cursor
= str
;
107 cursor
= std::char_traits
<sal_Unicode
>::find(cursor
, end
- cursor
, *subStr
);
108 if(!cursor
|| (end
- cursor
< subLen
))
110 /* no enough left to actually have a match */
113 /* now it is worth trying a full match */
114 if (rtl_ustr_asciil_reverseEquals_WithLength(cursor
, subStr
, subLen
))
124 sal_Int32
rtl_ustr_lastIndexOfAscii_WithLength(
125 sal_Unicode
const * str
, sal_Int32 len
,
126 char const * subStr
, sal_Int32 subLen
) SAL_THROW_EXTERN_C()
130 if (subLen
> 0 && subLen
<= len
) {
132 for (i
= len
- subLen
; i
>= 0; --i
) {
133 if (rtl_ustr_asciil_reverseEquals_WithLength(
134 str
+ i
, subStr
, subLen
))
143 sal_Int32 SAL_CALL
rtl_ustr_valueOfFloat(sal_Unicode
* pStr
, float f
)
147 rtl_uString
* pResult
= nullptr;
149 rtl_math_doubleToUString(
150 &pResult
, nullptr, 0, f
, rtl_math_StringFormat_G
,
151 RTL_USTR_MAX_VALUEOFFLOAT
- RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', nullptr,
153 nLen
= pResult
->length
;
154 OSL_ASSERT(nLen
< RTL_USTR_MAX_VALUEOFFLOAT
);
155 memcpy(pStr
, pResult
->buffer
, (nLen
+ 1) * sizeof(sal_Unicode
));
156 rtl_uString_release(pResult
);
160 sal_Int32 SAL_CALL
rtl_ustr_valueOfDouble(sal_Unicode
* pStr
, double d
)
164 rtl_uString
* pResult
= nullptr;
166 rtl_math_doubleToUString(
167 &pResult
, nullptr, 0, d
, rtl_math_StringFormat_G
,
168 RTL_USTR_MAX_VALUEOFDOUBLE
- RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', nullptr,
170 nLen
= pResult
->length
;
171 OSL_ASSERT(nLen
< RTL_USTR_MAX_VALUEOFDOUBLE
);
172 memcpy(pStr
, pResult
->buffer
, (nLen
+ 1) * sizeof(sal_Unicode
));
173 rtl_uString_release(pResult
);
179 // Avoid -fsanitize=undefined warning e.g. "runtime error: value 1e+99 is
180 // outside the range of representable values of type 'float'":
181 float doubleToFloat(double x
) {
183 x
< -std::numeric_limits
<float>::max()
184 ? -std::numeric_limits
<float>::infinity()
185 : x
> std::numeric_limits
<float>::max()
186 ? std::numeric_limits
<float>::infinity()
187 : static_cast<float>(x
);
192 float SAL_CALL
rtl_ustr_toFloat(sal_Unicode
const * pStr
) SAL_THROW_EXTERN_C()
195 return doubleToFloat(rtl_math_uStringToDouble(pStr
,
196 pStr
+ rtl_ustr_getLength(pStr
),
197 '.', 0, nullptr, nullptr));
200 double SAL_CALL
rtl_ustr_toDouble(sal_Unicode
const * pStr
) SAL_THROW_EXTERN_C()
203 return rtl_math_uStringToDouble(pStr
, pStr
+ rtl_ustr_getLength(pStr
), '.',
204 0, nullptr, nullptr);
207 /* ======================================================================= */
209 sal_Int32 SAL_CALL
rtl_ustr_ascii_compare( const sal_Unicode
* pStr1
,
210 const sal_Char
* pStr2
)
216 while ( ((nRet
= static_cast<sal_Int32
>(*pStr1
)-
217 static_cast<sal_Int32
>(static_cast<unsigned char>(*pStr2
))) == 0) &&
220 /* Check ASCII range */
221 SAL_WARN_IF( (static_cast<unsigned char>(*pStr2
)) > 127, "rtl.string",
222 "rtl_ustr_ascii_compare - Found char > 127" );
230 /* ----------------------------------------------------------------------- */
232 sal_Int32 SAL_CALL
rtl_ustr_ascii_compare_WithLength( const sal_Unicode
* pStr1
,
234 const sal_Char
* pStr2
)
238 assert(nStr1Len
>= 0);
241 while( ((nRet
= (nStr1Len
? static_cast<sal_Int32
>(*pStr1
) : 0)-
242 static_cast<sal_Int32
>(static_cast<unsigned char>(*pStr2
))) == 0) &&
245 /* Check ASCII range */
246 SAL_WARN_IF( (static_cast<unsigned char>(*pStr2
)) > 127, "rtl.string",
247 "rtl_ustr_ascii_compare_WithLength - Found char > 127" );
256 /* ----------------------------------------------------------------------- */
258 sal_Int32 SAL_CALL
rtl_ustr_ascii_shortenedCompare_WithLength( const sal_Unicode
* pStr1
,
260 const sal_Char
* pStr2
,
261 sal_Int32 nShortenedLength
)
264 assert(nStr1Len
>= 0);
265 assert(nShortenedLength
>= 0);
266 const sal_Unicode
* pStr1End
= pStr1
+ nStr1Len
;
268 while ( (nShortenedLength
> 0) &&
269 (pStr1
< pStr1End
) && *pStr2
)
271 /* Check ASCII range */
272 SAL_WARN_IF( (static_cast<unsigned char>(*pStr2
)) > 127, "rtl.string",
273 "rtl_ustr_ascii_shortenedCompare_WithLength - Found char > 127" );
275 nRet
= static_cast<sal_Int32
>(*pStr1
)-
276 static_cast<sal_Int32
>(static_cast<unsigned char>(*pStr2
));
285 if ( nShortenedLength
<= 0 )
290 OSL_ENSURE( pStr1
== pStr1End
, "pStr1 == pStr1End failed" );
291 // first is a substring of the second string => less (negative value)
297 nRet
= pStr1End
- pStr1
;
303 /* ----------------------------------------------------------------------- */
305 sal_Int32 SAL_CALL
rtl_ustr_asciil_reverseCompare_WithLength( const sal_Unicode
* pStr1
,
307 const sal_Char
* pStr2
,
311 assert(nStr1Len
>= 0 && nStr2Len
>= 0);
312 const sal_Unicode
* pStr1Run
= pStr1
+nStr1Len
;
313 const sal_Char
* pStr2Run
= pStr2
+nStr2Len
;
315 while ( (pStr1
< pStr1Run
) && (pStr2
< pStr2Run
) )
317 /* Check ASCII range */
318 SAL_WARN_IF( (static_cast<unsigned char>(*pStr2
)) > 127, "rtl.string",
319 "rtl_ustr_asciil_reverseCompare_WithLength - Found char > 127" );
322 nRet
= static_cast<sal_Int32
>(*pStr1Run
)- static_cast<sal_Int32
>(*pStr2Run
);
327 return nStr1Len
- nStr2Len
;
330 /* ----------------------------------------------------------------------- */
332 sal_Bool SAL_CALL
rtl_ustr_asciil_reverseEquals_WithLength( const sal_Unicode
* pStr1
,
333 const sal_Char
* pStr2
,
337 assert(nStrLen
>= 0);
338 const sal_Unicode
* pStr1Run
= pStr1
+nStrLen
;
339 const sal_Char
* pStr2Run
= pStr2
+nStrLen
;
340 while ( pStr1
< pStr1Run
)
342 /* Check ASCII range */
343 SAL_WARN_IF( (static_cast<unsigned char>(*pStr2
)) > 127, "rtl.string",
344 "rtl_ustr_asciil_reverseEquals_WithLength - Found char > 127" );
347 if( *pStr1Run
!= static_cast<sal_Unicode
>(*pStr2Run
) )
354 /* ----------------------------------------------------------------------- */
356 sal_Int32 SAL_CALL
rtl_ustr_ascii_compareIgnoreAsciiCase( const sal_Unicode
* pStr1
,
357 const sal_Char
* pStr2
)
367 /* Check ASCII range */
368 SAL_WARN_IF( (static_cast<unsigned char>(*pStr2
)) > 127, "rtl.string",
369 "rtl_ustr_ascii_compareIgnoreAsciiCase - Found char > 127" );
370 /* If character between 'A' and 'Z', then convert it to lowercase */
371 c1
= static_cast<sal_Int32
>(*pStr1
);
372 c2
= static_cast<sal_Int32
>(static_cast<unsigned char>(*pStr2
));
373 if ( (c1
>= 65) && (c1
<= 90) )
375 if ( (c2
>= 65) && (c2
<= 90) )
389 /* ----------------------------------------------------------------------- */
391 sal_Int32 SAL_CALL
rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( const sal_Unicode
* pStr1
,
393 const sal_Char
* pStr2
)
396 assert(nStr1Len
>= 0);
403 /* Check ASCII range */
404 SAL_WARN_IF( (static_cast<unsigned char>(*pStr2
)) > 127, "rtl.string",
405 "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength - Found char > 127" );
407 return *pStr2
== '\0' ? 0 : -1;
409 /* If character between 'A' and 'Z', then convert it to lowercase */
410 c1
= static_cast<sal_Int32
>(*pStr1
);
411 c2
= static_cast<sal_Int32
>(static_cast<unsigned char>(*pStr2
));
412 if ( (c1
>= 65) && (c1
<= 90) )
414 if ( (c2
>= 65) && (c2
<= 90) )
429 sal_Int32
rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
430 sal_Unicode
const * first
, sal_Int32 firstLen
,
431 char const * second
, sal_Int32 secondLen
) SAL_THROW_EXTERN_C()
433 assert(firstLen
>= 0 && secondLen
>= 0);
435 sal_Int32 len
= std::min(firstLen
, secondLen
);
436 for (i
= 0; i
< len
; ++i
) {
437 /* Check ASCII range */
438 SAL_WARN_IF( (static_cast<unsigned char>(*second
)) > 127, "rtl.string",
439 "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths - Found char > 127" );
440 sal_Int32 c1
= *first
++;
441 sal_Int32 c2
= static_cast<unsigned char>(*second
++);
443 if (c1
>= 65 && c1
<= 90) {
446 if (c2
>= 65 && c2
<= 90) {
454 return firstLen
- secondLen
;
457 /* ----------------------------------------------------------------------- */
459 sal_Int32 SAL_CALL
rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( const sal_Unicode
* pStr1
,
461 const sal_Char
* pStr2
,
462 sal_Int32 nShortenedLength
)
465 assert(nStr1Len
>= 0);
466 assert(nShortenedLength
>= 0);
467 const sal_Unicode
* pStr1End
= pStr1
+ nStr1Len
;
471 while ( (nShortenedLength
> 0) &&
472 (pStr1
< pStr1End
) && *pStr2
)
474 /* Check ASCII range */
475 SAL_WARN_IF( (static_cast<unsigned char>(*pStr2
)) > 127, "rtl.string",
476 "rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength - Found char > 127" );
478 /* If character between 'A' and 'Z', then convert it to lowercase */
479 c1
= static_cast<sal_Int32
>(*pStr1
);
480 c2
= static_cast<sal_Int32
>(static_cast<unsigned char>(*pStr2
));
481 if ( (c1
>= 65) && (c1
<= 90) )
483 if ( (c2
>= 65) && (c2
<= 90) )
494 if ( nShortenedLength
<= 0 )
499 OSL_ENSURE( pStr1
== pStr1End
, "pStr1 == pStr1End failed" );
500 // first is a substring of the second string => less (negative value)
506 nRet
= pStr1End
- pStr1
;
512 /* ----------------------------------------------------------------------- */
514 void SAL_CALL
rtl_uString_newFromAscii( rtl_uString
** ppThis
,
515 const sal_Char
* pCharStr
)
523 const sal_Char
* pTempStr
= pCharStr
;
526 nLen
= pTempStr
-pCharStr
;
533 rtl_uString_new( ppThis
);
538 rtl_uString_release( *ppThis
);
540 *ppThis
= rtl_uString_ImplAlloc( nLen
);
541 OSL_ASSERT(*ppThis
!= nullptr);
544 sal_Unicode
* pBuffer
= (*ppThis
)->buffer
;
547 assert(static_cast<unsigned char>(*pCharStr
) < 0x80); // ASCII range
548 *pBuffer
= *pCharStr
;
554 RTL_LOG_STRING_NEW( *ppThis
);
558 void SAL_CALL
rtl_uString_newFromCodePoints(
559 rtl_uString
** newString
, sal_uInt32
const * codePoints
,
560 sal_Int32 codePointCount
) SAL_THROW_EXTERN_C()
565 assert(newString
!= nullptr);
566 assert((codePoints
!= nullptr || codePointCount
== 0) && codePointCount
>= 0);
567 if (codePointCount
== 0) {
568 rtl_uString_new(newString
);
571 if (*newString
!= nullptr) {
572 rtl_uString_release(*newString
);
575 for (i
= 0; i
< codePointCount
; ++i
) {
576 OSL_ASSERT(rtl::isUnicodeCodePoint(codePoints
[i
]));
577 if (codePoints
[i
] >= 0x10000) {
581 /* Builds on the assumption that sal_Int32 uses 32 bit two's complement
582 representation with wrap around (the necessary number of UTF-16 code
583 units will be no larger than 2 * SAL_MAX_INT32, represented as
586 // coverity[dead_error_begin] - assumes wrap around
587 *newString
= nullptr;
590 *newString
= rtl_uString_ImplAlloc(n
);
591 if (*newString
== nullptr) {
594 p
= (*newString
)->buffer
;
595 for (i
= 0; i
< codePointCount
; ++i
) {
596 p
+= rtl::splitSurrogates(codePoints
[i
], p
);
598 RTL_LOG_STRING_NEW( *newString
);
601 void rtl_uString_newConcatAsciiL(
602 rtl_uString
** newString
, rtl_uString
* left
, char const * right
,
603 sal_Int32 rightLength
)
605 assert(newString
!= nullptr);
606 assert(left
!= nullptr);
607 assert(right
!= nullptr);
608 assert(rightLength
>= 0);
609 if (left
->length
> std::numeric_limits
<sal_Int32
>::max() - rightLength
) {
610 #if !defined(__COVERITY__)
611 throw std::length_error("rtl_uString_newConcatAsciiL");
613 //coverity doesn't report std::bad_alloc as an unhandled exception when
614 //potentially thrown from destructors but does report std::length_error
615 throw std::bad_alloc();
618 sal_Int32 n
= left
->length
+ rightLength
;
619 rtl_uString_assign(newString
, left
);
620 rtl_uString_ensureCapacity(newString
, n
);
621 sal_Unicode
* p
= (*newString
)->buffer
+ (*newString
)->length
;
622 for (sal_Int32 i
= 0; i
!= rightLength
; ++i
) {
623 p
[i
] = static_cast<unsigned char>(right
[i
]);
625 (*newString
)->buffer
[n
] = 0;
626 (*newString
)->length
= n
;
629 void rtl_uString_newConcatUtf16L(
630 rtl_uString
** newString
, rtl_uString
* left
, sal_Unicode
const * right
,
631 sal_Int32 rightLength
)
633 assert(newString
!= nullptr);
634 assert(left
!= nullptr);
635 assert(right
!= nullptr);
636 assert(rightLength
>= 0);
637 if (left
->length
> std::numeric_limits
<sal_Int32
>::max() - rightLength
) {
638 #if !defined(__COVERITY__)
639 throw std::length_error("rtl_uString_newConcatUtf16L");
641 //coverity doesn't report std::bad_alloc as an unhandled exception when
642 //potentially thrown from destructors but does report std::length_error
643 throw std::bad_alloc();
646 sal_Int32 n
= left
->length
+ rightLength
;
647 rtl_uString_assign(newString
, left
);
648 rtl_uString_ensureCapacity(newString
, n
);
650 (*newString
)->buffer
+ (*newString
)->length
, right
,
651 rightLength
* sizeof (sal_Unicode
));
652 (*newString
)->buffer
[n
] = 0;
653 (*newString
)->length
= n
;
656 /* ======================================================================= */
658 static int rtl_ImplGetFastUTF8UnicodeLen( const sal_Char
* pStr
, sal_Int32 nLen
, bool * ascii
)
661 const sal_Char
* pEndStr
;
666 while ( pStr
< pEndStr
)
668 unsigned char c
= static_cast<unsigned char>(*pStr
);
674 if ( (c
& 0xE0) == 0xC0 )
676 else if ( (c
& 0xF0) == 0xE0 )
678 else if ( (c
& 0xF8) == 0xF0 )
680 else if ( (c
& 0xFC) == 0xF8 )
682 else if ( (c
& 0xFE) == 0xFC )
695 /* ----------------------------------------------------------------------- */
697 static void rtl_string2UString_status( rtl_uString
** ppThis
,
698 const sal_Char
* pStr
,
700 rtl_TextEncoding eTextEncoding
,
701 sal_uInt32 nCvtFlags
,
704 OSL_ENSURE(nLen
== 0 || rtl_isOctetTextEncoding(eTextEncoding
),
705 "rtl_string2UString_status() - Wrong TextEncoding" );
709 rtl_uString_new( ppThis
);
710 if (pInfo
!= nullptr) {
717 rtl_uString_release( *ppThis
);
719 /* Optimization for US-ASCII */
720 if ( eTextEncoding
== RTL_TEXTENCODING_ASCII_US
)
722 sal_Unicode
* pBuffer
;
723 *ppThis
= rtl_uString_ImplAlloc( nLen
);
724 if (*ppThis
== nullptr) {
725 if (pInfo
!= nullptr) {
726 *pInfo
= RTL_TEXTTOUNICODE_INFO_ERROR
|
727 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
;
731 pBuffer
= (*ppThis
)->buffer
;
732 sal_Int32
nLenCopy(nLen
);
733 const sal_Char
*pStrCopy(pStr
);
736 /* Check ASCII range */
737 if (static_cast<unsigned char>(*pStrCopy
) > 127)
739 rtl_uString_release(*ppThis
);
740 goto retry
; // cancel loop - try again with the converter
743 *pBuffer
= *pStrCopy
;
749 if (pInfo
!= nullptr) {
752 RTL_LOG_STRING_NEW( *ppThis
);
758 rtl_uString
* pTemp2
= nullptr;
759 rtl_TextToUnicodeConverter hConverter
;
765 /* Optimization for UTF-8 - we try to calculate the exact length */
766 /* For all other encoding we try the maximum - and reallocate
767 the buffer if needed */
768 if ( eTextEncoding
== RTL_TEXTENCODING_UTF8
)
771 nNewLen
= rtl_ImplGetFastUTF8UnicodeLen( pStr
, nLen
, &ascii
);
772 /* Includes the string only ASCII, then we could copy
776 sal_Unicode
* pBuffer
;
777 *ppThis
= rtl_uString_ImplAlloc( nLen
);
778 if (*ppThis
== nullptr)
780 if (pInfo
!= nullptr) {
781 *pInfo
= RTL_TEXTTOUNICODE_INFO_ERROR
|
782 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
;
786 pBuffer
= (*ppThis
)->buffer
;
789 assert((static_cast<unsigned char>(*pStr
)) <= 127);
796 if (pInfo
!= nullptr) {
799 RTL_LOG_STRING_NEW( *ppThis
);
806 nCvtFlags
|= RTL_TEXTTOUNICODE_FLAGS_FLUSH
;
807 hConverter
= rtl_createTextToUnicodeConverter( eTextEncoding
);
809 pTemp
= rtl_uString_ImplAlloc( nNewLen
);
810 if (pTemp
== nullptr) {
811 if (pInfo
!= nullptr) {
812 *pInfo
= RTL_TEXTTOUNICODE_INFO_ERROR
|
813 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
;
817 nDestChars
= rtl_convertTextToUnicode( hConverter
, nullptr,
819 pTemp
->buffer
, nNewLen
,
821 &nInfo
, &nSrcBytes
);
823 /* Buffer not big enough, try again with enough space */
824 /* Shouldn't be the case, but if we get textencoding which
825 could results in more unicode characters we have this
826 code here. Could be the case for apple encodings */
827 while ( nInfo
& RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
)
829 rtl_freeString( pTemp
);
831 pTemp
= rtl_uString_ImplAlloc( nNewLen
);
832 if (pTemp
== nullptr) {
833 if (pInfo
!= nullptr) {
834 *pInfo
= RTL_TEXTTOUNICODE_INFO_ERROR
|
835 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
;
839 nDestChars
= rtl_convertTextToUnicode( hConverter
, nullptr,
841 pTemp
->buffer
, nNewLen
,
843 &nInfo
, &nSrcBytes
);
849 /* Set the buffer to the correct size or if there is too
850 much overhead, reallocate to the correct size */
851 if ( nNewLen
> nDestChars
+8 )
853 pTemp2
= rtl_uString_ImplAlloc( nDestChars
);
855 if (pTemp2
!= nullptr)
857 rtl_str_ImplCopy(pTemp2
->buffer
, pTemp
->buffer
, nDestChars
);
858 rtl_freeString(pTemp
);
863 pTemp
->length
= nDestChars
;
864 pTemp
->buffer
[nDestChars
] = 0;
867 rtl_destroyTextToUnicodeConverter( hConverter
);
870 /* Results the conversion in an empty buffer -
871 create an empty string */
872 if ( pTemp
&& !nDestChars
)
873 rtl_uString_new( ppThis
);
876 RTL_LOG_STRING_NEW( *ppThis
);
879 void SAL_CALL
rtl_string2UString( rtl_uString
** ppThis
,
880 const sal_Char
* pStr
,
882 rtl_TextEncoding eTextEncoding
,
883 sal_uInt32 nCvtFlags
) SAL_THROW_EXTERN_C()
887 rtl_string2UString_status( ppThis
, pStr
, nLen
, eTextEncoding
,
888 nCvtFlags
, nullptr );
891 /* ----------------------------------------------------------------------- */
901 static oslMutex pPoolGuard
= osl_createMutex();
906 /* returns true if we found a dup in the pool */
907 static void rtl_ustring_intern_internal( rtl_uString
** newStr
,
909 StrLifecycle can_return
)
913 pPoolMutex
= getInternMutex();
915 osl_acquireMutex( pPoolMutex
);
917 *newStr
= rtl_str_hash_intern (str
, can_return
);
919 osl_releaseMutex( pPoolMutex
);
921 RTL_LOG_STRING_INTERN_NEW(*newStr
, str
);
923 if( can_return
&& *newStr
!= str
)
924 { /* we dupped, then found a match */
925 rtl_freeString( str
);
929 void SAL_CALL
rtl_uString_intern( rtl_uString
** newStr
,
930 rtl_uString
* str
) SAL_THROW_EXTERN_C()
934 if (SAL_STRING_IS_INTERN(str
))
936 IMPL_RTL_ACQUIRE( str
);
941 rtl_uString
*pOrg
= *newStr
;
943 rtl_ustring_intern_internal( newStr
, str
, CANNOT_RETURN
);
945 rtl_uString_release (pOrg
);
949 static int rtl_canGuessUOutputLength( int len
, rtl_TextEncoding eTextEncoding
)
951 // FIXME: Maybe we should use a bit flag in the higher bits of the
952 // eTextEncoding value itself to determine the encoding type. But if we
953 // do, be sure to mask the value in certain places that expect the values
954 // to be numbered serially from 0 and up. One such place is
955 // Impl_getTextEncodingData().
957 switch ( eTextEncoding
)
959 // 1 to 1 (with no zero elements)
960 case RTL_TEXTENCODING_IBM_437
:
961 case RTL_TEXTENCODING_IBM_850
:
962 case RTL_TEXTENCODING_IBM_860
:
963 case RTL_TEXTENCODING_IBM_861
:
964 case RTL_TEXTENCODING_IBM_863
:
965 case RTL_TEXTENCODING_IBM_865
:
972 void SAL_CALL
rtl_uString_internConvert( rtl_uString
** newStr
,
973 const sal_Char
* str
,
975 rtl_TextEncoding eTextEncoding
,
976 sal_uInt32 convertFlags
,
982 rtl_uString
*scratch
;
986 rtl_uString_release (*newStr
);
991 { // try various optimisations
993 if ( eTextEncoding
== RTL_TEXTENCODING_ASCII_US
)
996 rtl_uString
*pScratch
;
997 pScratch
= static_cast< rtl_uString
* >(
998 alloca(sizeof (rtl_uString
) + len
* sizeof (sal_Unicode
)));
999 for (i
= 0; i
< len
; i
++)
1001 /* Check ASCII range */
1002 SAL_WARN_IF( (static_cast<unsigned char>(str
[i
])) > 127, "rtl.string",
1003 "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
1004 pScratch
->buffer
[i
] = str
[i
];
1006 pScratch
->length
= len
;
1007 rtl_ustring_intern_internal( newStr
, pScratch
, CANNOT_RETURN
);
1010 if ( (ulen
= rtl_canGuessUOutputLength(len
, eTextEncoding
)) != 0 )
1012 rtl_uString
*pScratch
;
1013 rtl_TextToUnicodeConverter hConverter
;
1017 pScratch
= static_cast< rtl_uString
* >(
1019 sizeof (rtl_uString
) + ulen
* sizeof (sal_Unicode
)));
1021 hConverter
= rtl_createTextToUnicodeConverter( eTextEncoding
);
1022 rtl_convertTextToUnicode(
1023 hConverter
, nullptr, str
, len
, pScratch
->buffer
, ulen
, convertFlags
, &nInfo
, &nSrcBytes
);
1024 rtl_destroyTextToUnicodeConverter( hConverter
);
1029 pScratch
->length
= ulen
;
1030 rtl_ustring_intern_internal( newStr
, pScratch
, CANNOT_RETURN
);
1034 /* FIXME: we want a nice UTF-8 / alloca shortcut here */
1038 rtl_string2UString_status( &scratch
, str
, len
, eTextEncoding
, convertFlags
,
1043 rtl_ustring_intern_internal( newStr
, scratch
, CAN_RETURN
);
1047 internRelease (rtl_uString
*pThis
)
1049 oslMutex pPoolMutex
;
1051 rtl_uString
*pFree
= nullptr;
1052 if ( SAL_STRING_REFCOUNT(
1053 osl_atomic_decrement( &(pThis
->refCount
) ) ) == 0)
1055 RTL_LOG_STRING_INTERN_DELETE(pThis
);
1056 pPoolMutex
= getInternMutex();
1057 osl_acquireMutex( pPoolMutex
);
1059 rtl_str_hash_remove (pThis
);
1061 /* May have been separately acquired */
1062 if ( SAL_STRING_REFCOUNT(
1063 osl_atomic_increment( &(pThis
->refCount
) ) ) == 1 )
1065 /* we got the last ref */
1068 else /* very unusual */
1070 internRelease (pThis
);
1073 osl_releaseMutex( pPoolMutex
);
1076 rtl_freeString (pFree
);
1079 sal_uInt32 SAL_CALL
rtl_uString_iterateCodePoints(
1080 rtl_uString
const * string
, sal_Int32
* indexUtf16
,
1081 sal_Int32 incrementCodePoints
)
1086 assert(string
!= nullptr && indexUtf16
!= nullptr);
1088 assert(n
>= 0 && n
<= string
->length
);
1089 while (incrementCodePoints
< 0) {
1091 cu
= string
->buffer
[--n
];
1092 if (rtl::isLowSurrogate(cu
) && n
!= 0 &&
1093 rtl::isHighSurrogate(string
->buffer
[n
- 1]))
1097 ++incrementCodePoints
;
1099 assert(n
>= 0 && n
< string
->length
);
1100 cu
= string
->buffer
[n
];
1101 if (rtl::isHighSurrogate(cu
) && string
->length
- n
>= 2 &&
1102 rtl::isLowSurrogate(string
->buffer
[n
+ 1]))
1104 cp
= rtl::combineSurrogates(cu
, string
->buffer
[n
+ 1]);
1108 while (incrementCodePoints
> 0) {
1109 assert(n
< string
->length
);
1110 cu
= string
->buffer
[n
++];
1111 if (rtl::isHighSurrogate(cu
) && n
!= string
->length
&&
1112 rtl::isLowSurrogate(string
->buffer
[n
]))
1116 --incrementCodePoints
;
1118 assert(n
>= 0 && n
<= string
->length
);
1123 sal_Bool
rtl_convertStringToUString(
1124 rtl_uString
** target
, char const * source
, sal_Int32 length
,
1125 rtl_TextEncoding encoding
, sal_uInt32 flags
) SAL_THROW_EXTERN_C()
1128 assert(length
>= 0);
1130 rtl_string2UString_status(target
, source
, length
, encoding
, flags
, &info
);
1131 return (info
& RTL_TEXTTOUNICODE_INFO_ERROR
) == 0;
1134 void rtl_uString_newReplaceFirst(
1135 rtl_uString
** newStr
, rtl_uString
* str
, rtl_uString
const * from
,
1136 rtl_uString
const * to
, sal_Int32
* index
) SAL_THROW_EXTERN_C()
1138 assert(str
!= nullptr);
1139 assert(index
!= nullptr);
1140 assert(*index
>= 0 && *index
<= str
->length
);
1141 assert(from
!= nullptr);
1142 assert(to
!= nullptr);
1143 sal_Int32 i
= rtl_ustr_indexOfStr_WithLength(
1144 str
->buffer
+ *index
, str
->length
- *index
, from
->buffer
, from
->length
);
1146 rtl_uString_assign(newStr
, str
);
1148 assert(i
<= str
->length
- *index
);
1150 assert(from
->length
<= str
->length
);
1151 if (str
->length
- from
->length
> SAL_MAX_INT32
- to
->length
) {
1154 sal_Int32 n
= str
->length
- from
->length
+ to
->length
;
1155 rtl_uString_acquire(str
); // in case *newStr == str
1156 rtl_uString_new_WithLength(newStr
, n
);
1158 (*newStr
)->length
= n
;
1159 assert(i
>= 0 && i
< str
->length
);
1161 (*newStr
)->buffer
, str
->buffer
, i
* sizeof (sal_Unicode
));
1163 (*newStr
)->buffer
+ i
, to
->buffer
,
1164 to
->length
* sizeof (sal_Unicode
));
1166 (*newStr
)->buffer
+ i
+ to
->length
,
1167 str
->buffer
+ i
+ from
->length
,
1168 (str
->length
- i
- from
->length
) * sizeof (sal_Unicode
));
1170 rtl_uString_release(str
);
1175 void rtl_uString_newReplaceFirstAsciiL(
1176 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
1177 sal_Int32 fromLength
, rtl_uString
const * to
, sal_Int32
* index
)
1178 SAL_THROW_EXTERN_C()
1180 assert(str
!= nullptr);
1181 assert(index
!= nullptr);
1182 assert(*index
>= 0 && *index
<= str
->length
);
1183 assert(fromLength
>= 0);
1184 assert(to
!= nullptr);
1185 sal_Int32 i
= rtl_ustr_indexOfAscii_WithLength(
1186 str
->buffer
+ *index
, str
->length
- *index
, from
, fromLength
);
1188 rtl_uString_assign(newStr
, str
);
1190 assert(i
<= str
->length
- *index
);
1192 assert(fromLength
<= str
->length
);
1193 if (str
->length
- fromLength
> SAL_MAX_INT32
- to
->length
) {
1196 sal_Int32 n
= str
->length
- fromLength
+ to
->length
;
1197 rtl_uString_acquire(str
); // in case *newStr == str
1198 rtl_uString_new_WithLength(newStr
, n
);
1200 (*newStr
)->length
= n
;
1201 assert(i
>= 0 && i
< str
->length
);
1203 (*newStr
)->buffer
, str
->buffer
, i
* sizeof (sal_Unicode
));
1205 (*newStr
)->buffer
+ i
, to
->buffer
,
1206 to
->length
* sizeof (sal_Unicode
));
1208 (*newStr
)->buffer
+ i
+ to
->length
,
1209 str
->buffer
+ i
+ fromLength
,
1210 (str
->length
- i
- fromLength
) * sizeof (sal_Unicode
));
1212 rtl_uString_release(str
);
1217 void rtl_uString_newReplaceFirstToAsciiL(
1218 rtl_uString
** newStr
, rtl_uString
* str
, rtl_uString
const * from
,
1219 char const * to
, sal_Int32 toLength
, sal_Int32
* index
)
1220 SAL_THROW_EXTERN_C()
1222 assert(str
!= nullptr);
1223 assert(index
!= nullptr);
1224 assert(*index
>= 0 && *index
<= str
->length
);
1225 assert(from
!= nullptr);
1226 assert(toLength
>= 0);
1227 sal_Int32 i
= rtl_ustr_indexOfStr_WithLength(
1228 str
->buffer
+ *index
, str
->length
- *index
, from
->buffer
, from
->length
);
1230 rtl_uString_assign(newStr
, str
);
1232 assert(i
<= str
->length
- *index
);
1234 assert(from
->length
<= str
->length
);
1235 if (str
->length
- from
->length
> SAL_MAX_INT32
- toLength
) {
1238 sal_Int32 n
= str
->length
- from
->length
+ toLength
;
1239 rtl_uString_acquire(str
); // in case *newStr == str
1240 rtl_uString_new_WithLength(newStr
, n
);
1242 (*newStr
)->length
= n
;
1243 assert(i
>= 0 && i
< str
->length
);
1245 (*newStr
)->buffer
, str
->buffer
, i
* sizeof (sal_Unicode
));
1246 for (sal_Int32 j
= 0; j
!= toLength
; ++j
) {
1247 assert(static_cast< unsigned char >(to
[j
]) <= 0x7F);
1248 (*newStr
)->buffer
[i
+ j
] = to
[j
];
1251 (*newStr
)->buffer
+ i
+ toLength
,
1252 str
->buffer
+ i
+ from
->length
,
1253 (str
->length
- i
- from
->length
) * sizeof (sal_Unicode
));
1255 rtl_uString_release(str
);
1260 void rtl_uString_newReplaceFirstAsciiLAsciiL(
1261 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
1262 sal_Int32 fromLength
, char const * to
, sal_Int32 toLength
,
1263 sal_Int32
* index
) SAL_THROW_EXTERN_C()
1265 assert(str
!= nullptr);
1266 assert(index
!= nullptr);
1267 assert(*index
>= 0 && *index
<= str
->length
);
1268 assert(fromLength
>= 0);
1269 assert(to
!= nullptr);
1270 assert(toLength
>= 0);
1271 sal_Int32 i
= rtl_ustr_indexOfAscii_WithLength(
1272 str
->buffer
+ *index
, str
->length
- *index
, from
, fromLength
);
1274 rtl_uString_assign(newStr
, str
);
1276 assert(i
<= str
->length
- *index
);
1278 assert(fromLength
<= str
->length
);
1279 if (str
->length
- fromLength
> SAL_MAX_INT32
- toLength
) {
1282 sal_Int32 n
= str
->length
- fromLength
+ toLength
;
1283 rtl_uString_acquire(str
); // in case *newStr == str
1284 rtl_uString_new_WithLength(newStr
, n
);
1286 (*newStr
)->length
= n
;
1287 assert(i
>= 0 && i
< str
->length
);
1289 (*newStr
)->buffer
, str
->buffer
, i
* sizeof (sal_Unicode
));
1290 for (sal_Int32 j
= 0; j
!= toLength
; ++j
) {
1291 assert(static_cast< unsigned char >(to
[j
]) <= 0x7F);
1292 (*newStr
)->buffer
[i
+ j
] = to
[j
];
1295 (*newStr
)->buffer
+ i
+ toLength
,
1296 str
->buffer
+ i
+ fromLength
,
1297 (str
->length
- i
- fromLength
) * sizeof (sal_Unicode
));
1299 rtl_uString_release(str
);
1304 void rtl_uString_newReplaceFirstAsciiLUtf16L(
1305 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
1306 sal_Int32 fromLength
, sal_Unicode
const * to
, sal_Int32 toLength
,
1307 sal_Int32
* index
) SAL_THROW_EXTERN_C()
1309 assert(str
!= nullptr);
1310 assert(index
!= nullptr);
1311 assert(*index
>= 0 && *index
<= str
->length
);
1312 assert(fromLength
>= 0);
1313 assert(to
!= nullptr);
1314 assert(toLength
>= 0);
1315 sal_Int32 i
= rtl_ustr_indexOfAscii_WithLength(
1316 str
->buffer
+ *index
, str
->length
- *index
, from
, fromLength
);
1318 rtl_uString_assign(newStr
, str
);
1320 assert(i
<= str
->length
- *index
);
1322 assert(fromLength
<= str
->length
);
1323 if (str
->length
- fromLength
> SAL_MAX_INT32
- toLength
) {
1324 rtl_uString_release(*newStr
);
1327 sal_Int32 n
= str
->length
- fromLength
+ toLength
;
1328 rtl_uString_acquire(str
); // in case *newStr == str
1329 rtl_uString_new_WithLength(newStr
, n
);
1330 if (n
!= 0 && /*TODO:*/ *newStr
!= nullptr) {
1331 (*newStr
)->length
= n
;
1332 assert(i
>= 0 && i
< str
->length
);
1334 (*newStr
)->buffer
, str
->buffer
, i
* sizeof (sal_Unicode
));
1336 (*newStr
)->buffer
+ i
, to
, toLength
* sizeof (sal_Unicode
));
1338 (*newStr
)->buffer
+ i
+ toLength
,
1339 str
->buffer
+ i
+ fromLength
,
1340 (str
->length
- i
- fromLength
) * sizeof (sal_Unicode
));
1342 rtl_uString_release(str
);
1348 void rtl_uString_newReplaceFirstUtf16LAsciiL(
1349 rtl_uString
** newStr
, rtl_uString
* str
, sal_Unicode
const * from
,
1350 sal_Int32 fromLength
, char const * to
, sal_Int32 toLength
,
1351 sal_Int32
* index
) SAL_THROW_EXTERN_C()
1353 assert(str
!= nullptr);
1354 assert(index
!= nullptr);
1355 assert(*index
>= 0 && *index
<= str
->length
);
1356 assert(fromLength
>= 0);
1357 assert(to
!= nullptr);
1358 assert(toLength
>= 0);
1359 sal_Int32 i
= rtl_ustr_indexOfStr_WithLength(
1360 str
->buffer
+ *index
, str
->length
- *index
, from
, fromLength
);
1362 rtl_uString_assign(newStr
, str
);
1364 assert(i
<= str
->length
- *index
);
1366 assert(fromLength
<= str
->length
);
1367 if (str
->length
- fromLength
> SAL_MAX_INT32
- toLength
) {
1368 rtl_uString_release(*newStr
);
1371 sal_Int32 n
= str
->length
- fromLength
+ toLength
;
1372 rtl_uString_acquire(str
); // in case *newStr == str
1373 rtl_uString_new_WithLength(newStr
, n
);
1374 if (n
!= 0 && /*TODO:*/ *newStr
!= nullptr) {
1375 (*newStr
)->length
= n
;
1376 assert(i
>= 0 && i
< str
->length
);
1378 (*newStr
)->buffer
, str
->buffer
, i
* sizeof (sal_Unicode
));
1379 for (sal_Int32 j
= 0; j
!= toLength
; ++j
) {
1380 assert(static_cast< unsigned char >(to
[j
]) <= 0x7F);
1381 (*newStr
)->buffer
[i
+ j
] = to
[j
];
1384 (*newStr
)->buffer
+ i
+ toLength
,
1385 str
->buffer
+ i
+ fromLength
,
1386 (str
->length
- i
- fromLength
) * sizeof (sal_Unicode
));
1388 rtl_uString_release(str
);
1394 void rtl_uString_newReplaceFirstUtf16LUtf16L(
1395 rtl_uString
** newStr
, rtl_uString
* str
, sal_Unicode
const * from
,
1396 sal_Int32 fromLength
, sal_Unicode
const * to
, sal_Int32 toLength
,
1397 sal_Int32
* index
) SAL_THROW_EXTERN_C()
1399 assert(str
!= nullptr);
1400 assert(index
!= nullptr);
1401 assert(*index
>= 0 && *index
<= str
->length
);
1402 assert(fromLength
>= 0);
1403 assert(to
!= nullptr);
1404 assert(toLength
>= 0);
1405 sal_Int32 i
= rtl_ustr_indexOfStr_WithLength(
1406 str
->buffer
+ *index
, str
->length
- *index
, from
, fromLength
);
1408 rtl_uString_assign(newStr
, str
);
1410 assert(i
<= str
->length
- *index
);
1412 assert(fromLength
<= str
->length
);
1413 if (str
->length
- fromLength
> SAL_MAX_INT32
- toLength
) {
1414 rtl_uString_release(*newStr
);
1417 sal_Int32 n
= str
->length
- fromLength
+ toLength
;
1418 rtl_uString_acquire(str
); // in case *newStr == str
1419 rtl_uString_new_WithLength(newStr
, n
);
1420 if (n
!= 0 && /*TODO:*/ *newStr
!= nullptr) {
1421 (*newStr
)->length
= n
;
1422 assert(i
>= 0 && i
< str
->length
);
1424 (*newStr
)->buffer
, str
->buffer
, i
* sizeof (sal_Unicode
));
1426 (*newStr
)->buffer
+ i
, to
, toLength
* sizeof (sal_Unicode
));
1428 (*newStr
)->buffer
+ i
+ toLength
,
1429 str
->buffer
+ i
+ fromLength
,
1430 (str
->length
- i
- fromLength
) * sizeof (sal_Unicode
));
1432 rtl_uString_release(str
);
1438 void rtl_uString_newReplaceAll(
1439 rtl_uString
** newStr
, rtl_uString
* str
, rtl_uString
const * from
,
1440 rtl_uString
const * to
) SAL_THROW_EXTERN_C()
1442 rtl_uString_newReplaceAllFromIndex( newStr
, str
, from
, to
, 0 );
1445 void rtl_uString_newReplaceAllFromIndex(
1446 rtl_uString
** newStr
, rtl_uString
* str
, rtl_uString
const * from
,
1447 rtl_uString
const * to
, sal_Int32 fromIndex
) SAL_THROW_EXTERN_C()
1449 assert(to
!= nullptr);
1450 assert(fromIndex
>= 0 && fromIndex
<= str
->length
);
1451 rtl_uString_assign(newStr
, str
);
1452 for (sal_Int32 i
= fromIndex
;; i
+= to
->length
) {
1453 rtl_uString_newReplaceFirst(newStr
, *newStr
, from
, to
, &i
);
1460 void rtl_uString_newReplaceAllAsciiL(
1461 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
1462 sal_Int32 fromLength
, rtl_uString
const * to
) SAL_THROW_EXTERN_C()
1464 assert(to
!= nullptr);
1465 rtl_uString_assign(newStr
, str
);
1466 for (sal_Int32 i
= 0;; i
+= to
->length
) {
1467 rtl_uString_newReplaceFirstAsciiL(
1468 newStr
, *newStr
, from
, fromLength
, to
, &i
);
1475 void rtl_uString_newReplaceAllToAsciiL(
1476 rtl_uString
** newStr
, rtl_uString
* str
, rtl_uString
const * from
,
1477 char const * to
, sal_Int32 toLength
) SAL_THROW_EXTERN_C()
1479 assert(from
!= nullptr);
1480 rtl_uString_assign(newStr
, str
);
1481 for (sal_Int32 i
= 0;; i
+= toLength
) {
1482 rtl_uString_newReplaceFirstToAsciiL(
1483 newStr
, *newStr
, from
, to
, toLength
, &i
);
1490 void rtl_uString_newReplaceAllAsciiLAsciiL(
1491 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
1492 sal_Int32 fromLength
, char const * to
, sal_Int32 toLength
)
1493 SAL_THROW_EXTERN_C()
1495 assert(toLength
>= 0);
1496 rtl_uString_assign(newStr
, str
);
1497 for (sal_Int32 i
= 0;; i
+= toLength
) {
1498 rtl_uString_newReplaceFirstAsciiLAsciiL(
1499 newStr
, *newStr
, from
, fromLength
, to
, toLength
, &i
);
1506 void rtl_uString_newReplaceAllAsciiLUtf16L(
1507 rtl_uString
** newStr
, rtl_uString
* str
, char const * from
,
1508 sal_Int32 fromLength
, sal_Unicode
const * to
, sal_Int32 toLength
)
1509 SAL_THROW_EXTERN_C()
1511 assert(toLength
>= 0);
1512 rtl_uString_assign(newStr
, str
);
1513 for (sal_Int32 i
= 0;; i
+= toLength
) {
1514 rtl_uString_newReplaceFirstAsciiLUtf16L(
1515 newStr
, *newStr
, from
, fromLength
, to
, toLength
, &i
);
1516 if (i
== -1 || *newStr
== nullptr) {
1522 void rtl_uString_newReplaceAllUtf16LAsciiL(
1523 rtl_uString
** newStr
, rtl_uString
* str
, sal_Unicode
const * from
,
1524 sal_Int32 fromLength
, char const * to
, sal_Int32 toLength
)
1525 SAL_THROW_EXTERN_C()
1527 assert(toLength
>= 0);
1528 rtl_uString_assign(newStr
, str
);
1529 for (sal_Int32 i
= 0;; i
+= toLength
) {
1530 rtl_uString_newReplaceFirstUtf16LAsciiL(
1531 newStr
, *newStr
, from
, fromLength
, to
, toLength
, &i
);
1532 if (i
== -1 || *newStr
== nullptr) {
1538 void rtl_uString_newReplaceAllUtf16LUtf16L(
1539 rtl_uString
** newStr
, rtl_uString
* str
, sal_Unicode
const * from
,
1540 sal_Int32 fromLength
, sal_Unicode
const * to
, sal_Int32 toLength
)
1541 SAL_THROW_EXTERN_C()
1543 assert(toLength
>= 0);
1544 rtl_uString_assign(newStr
, str
);
1545 for (sal_Int32 i
= 0;; i
+= toLength
) {
1546 rtl_uString_newReplaceFirstUtf16LUtf16L(
1547 newStr
, *newStr
, from
, fromLength
, to
, toLength
, &i
);
1548 if (i
== -1 || *newStr
== nullptr) {
1554 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */