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 <cstdlib>
24 #include <limits>
25 #include <stdexcept>
26 #include <string>
27 
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>
33 
34 #include <string.h>
35 #include <sal/alloca.h>
36 #include <sal/log.hxx>
37 
38 #include "hash.hxx"
39 #include "strimp.hxx"
40 #include <rtl/character.hxx>
41 #include <rtl/ustring.h>
42 
43 #include <rtl/math.h>
44 
45 #if defined _WIN32
46 // Temporary check to verify that the #pragma pack around rtl_uString is indeed cargo cult and can
47 // safely be removed:
48 static_assert(alignof (rtl_uString) == 4);
49 static_assert(sizeof (rtl_uString) == 12);
50 #endif
51 
52 /* ======================================================================= */
53 
54 #if USE_SDT_PROBES
55 #define RTL_LOG_STRING_BITS         16
56 #endif
57 
58 #include "strtmpl.hxx"
59 
60 /* static data to be referenced by all empty strings
61  * the refCount is predefined to 1 and must never become 0 !
62  */
63 template<>
64 rtl_uString rtl::str::EmptyStringImpl<rtl_uString>::data =
65 {
66     sal_Int32(SAL_STRING_INTERN_FLAG|SAL_STRING_STATIC_FLAG|1), /*sal_Int32    refCount; */
67     0,                                               /*sal_Int32    length;   */
68     { 0 }                                            /*sal_Unicode  buffer[1];*/
69 };
70 
71 /* ======================================================================= */
72 
rtl_ustr_indexOfAscii_WithLength(sal_Unicode const * str,sal_Int32 len,char const * subStr,sal_Int32 subLen)73 sal_Int32 rtl_ustr_indexOfAscii_WithLength(
74     sal_Unicode const * str, sal_Int32 len,
75     char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
76 {
77     assert(len >= 0);
78     assert(subLen >= 0);
79     if (subLen > 0 && subLen <= len)
80     {
81         sal_Unicode const* end = str + len;
82         sal_Unicode const* cursor = str;
83 
84         while(cursor < end)
85         {
86             cursor = std::char_traits<sal_Unicode>::find(cursor, end - cursor, *subStr);
87             if(!cursor || (end - cursor < subLen))
88             {
89                 /* no enough left to actually have a match */
90                 break;
91             }
92             /* now it is worth trying a full match */
93             if (rtl_ustr_asciil_reverseEquals_WithLength(cursor, subStr, subLen))
94             {
95                 return cursor - str;
96             }
97             cursor += 1;
98         }
99     }
100     return -1;
101 }
102 
rtl_ustr_lastIndexOfAscii_WithLength(sal_Unicode const * str,sal_Int32 len,char const * subStr,sal_Int32 subLen)103 sal_Int32 rtl_ustr_lastIndexOfAscii_WithLength(
104     sal_Unicode const * str, sal_Int32 len,
105     char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
106 {
107     assert(len >= 0);
108     assert(subLen >= 0);
109     if (subLen > 0 && subLen <= len) {
110         sal_Int32 i;
111         for (i = len - subLen; i >= 0; --i) {
112             if (rtl_ustr_asciil_reverseEquals_WithLength(
113                     str + i, subStr, subLen))
114             {
115                 return i;
116             }
117         }
118     }
119     return -1;
120 }
121 
rtl_ustr_valueOfFloat(sal_Unicode * pStr,float f)122 sal_Int32 SAL_CALL rtl_ustr_valueOfFloat(sal_Unicode * pStr, float f)
123     SAL_THROW_EXTERN_C()
124 {
125     assert(pStr);
126     rtl_uString * pResult = nullptr;
127     sal_Int32 nLen;
128     rtl_math_doubleToUString(
129         &pResult, nullptr, 0, f, rtl_math_StringFormat_G,
130         RTL_USTR_MAX_VALUEOFFLOAT - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', nullptr,
131         0, true);
132     nLen = pResult->length;
133     OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFFLOAT);
134     memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode));
135     rtl_uString_release(pResult);
136     return nLen;
137 }
138 
rtl_ustr_valueOfDouble(sal_Unicode * pStr,double d)139 sal_Int32 SAL_CALL rtl_ustr_valueOfDouble(sal_Unicode * pStr, double d)
140     SAL_THROW_EXTERN_C()
141 {
142     assert(pStr);
143     rtl_uString * pResult = nullptr;
144     sal_Int32 nLen;
145     rtl_math_doubleToUString(
146         &pResult, nullptr, 0, d, rtl_math_StringFormat_G,
147         RTL_USTR_MAX_VALUEOFDOUBLE - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', nullptr,
148         0, true);
149     nLen = pResult->length;
150     OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFDOUBLE);
151     memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode));
152     rtl_uString_release(pResult);
153     return nLen;
154 }
155 
156 namespace {
157 
158 // Avoid -fsanitize=undefined warning e.g. "runtime error: value 1e+99 is
159 // outside the range of representable values of type 'float'":
doubleToFloat(double x)160 float doubleToFloat(double x) {
161     return
162         x < -std::numeric_limits<float>::max()
163         ? -std::numeric_limits<float>::infinity()
164         : x > std::numeric_limits<float>::max()
165         ? std::numeric_limits<float>::infinity()
166         : static_cast<float>(x);
167 }
168 
169 }
170 
rtl_ustr_toFloat(sal_Unicode const * pStr)171 float SAL_CALL rtl_ustr_toFloat(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
172 {
173     assert(pStr);
174     return doubleToFloat(rtl_math_uStringToDouble(pStr,
175                                             pStr + rtl_ustr_getLength(pStr),
176                                             '.', 0, nullptr, nullptr));
177 }
178 
rtl_ustr_toDouble(sal_Unicode const * pStr)179 double SAL_CALL rtl_ustr_toDouble(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
180 {
181     assert(pStr);
182     return rtl_math_uStringToDouble(pStr, pStr + rtl_ustr_getLength(pStr), '.',
183                                     0, nullptr, nullptr);
184 }
185 
186 /* ======================================================================= */
187 
rtl_ustr_ascii_compare(const sal_Unicode * pStr1,const char * pStr2)188 sal_Int32 SAL_CALL rtl_ustr_ascii_compare( const sal_Unicode* pStr1,
189                                            const char* pStr2 )
190     SAL_THROW_EXTERN_C()
191 {
192     assert(pStr1);
193     assert(pStr2);
194     sal_Int32 nRet;
195     for (;;)
196     {
197         nRet = static_cast<sal_Int32>(*pStr1)-
198                      static_cast<sal_Int32>(static_cast<unsigned char>(*pStr2));
199         if (!(nRet == 0 && *pStr2 ))
200             break;
201         /* Check ASCII range */
202         SAL_WARN_IF( (static_cast<unsigned char>(*pStr2)) > 127, "rtl.string",
203                     "rtl_ustr_ascii_compare - Found char > 127" );
204         pStr1++;
205         pStr2++;
206     }
207 
208     return nRet;
209 }
210 
211 /* ----------------------------------------------------------------------- */
212 
rtl_ustr_ascii_compare_WithLength(const sal_Unicode * pStr1,sal_Int32 nStr1Len,const char * pStr2)213 sal_Int32 SAL_CALL rtl_ustr_ascii_compare_WithLength( const sal_Unicode* pStr1,
214                                                       sal_Int32 nStr1Len,
215                                                       const char* pStr2 )
216     SAL_THROW_EXTERN_C()
217 {
218     assert(pStr1);
219     assert(nStr1Len >= 0);
220     assert(pStr2);
221     sal_Int32 nRet = 0;
222     for (;;)
223     {
224         nRet = (nStr1Len ? static_cast<sal_Int32>(*pStr1) : 0) -
225                static_cast<sal_Int32>(static_cast<unsigned char>(*pStr2));
226         if (!(nRet == 0 && nStr1Len && *pStr2 ))
227             break;
228         /* Check ASCII range */
229         SAL_WARN_IF( (static_cast<unsigned char>(*pStr2)) > 127, "rtl.string",
230                     "rtl_ustr_ascii_compare_WithLength - Found char > 127" );
231         pStr1++;
232         pStr2++;
233         nStr1Len--;
234     }
235 
236     return nRet;
237 }
238 
239 /* ----------------------------------------------------------------------- */
240 
rtl_ustr_ascii_shortenedCompare_WithLength(const sal_Unicode * pStr1,sal_Int32 nStr1Len,const char * pStr2,sal_Int32 nShortenedLength)241 sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompare_WithLength( const sal_Unicode* pStr1,
242                                                                sal_Int32 nStr1Len,
243                                                                const char* pStr2,
244                                                                sal_Int32 nShortenedLength )
245     SAL_THROW_EXTERN_C()
246 {
247     assert(nStr1Len >= 0);
248     assert(nShortenedLength >= 0);
249     const sal_Unicode*  pStr1End = pStr1 + nStr1Len;
250     sal_Int32           nRet;
251     while ( (nShortenedLength > 0) &&
252             (pStr1 < pStr1End) && *pStr2 )
253     {
254         /* Check ASCII range */
255         SAL_WARN_IF( (static_cast<unsigned char>(*pStr2)) > 127, "rtl.string",
256                     "rtl_ustr_ascii_shortenedCompare_WithLength - Found char > 127" );
257 
258         nRet = static_cast<sal_Int32>(*pStr1)-
259                static_cast<sal_Int32>(static_cast<unsigned char>(*pStr2));
260         if ( nRet != 0 )
261             return nRet;
262 
263         nShortenedLength--;
264         pStr1++;
265         pStr2++;
266     }
267 
268     if ( nShortenedLength <= 0 )
269         return 0;
270 
271     if ( *pStr2 )
272     {
273         OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" );
274         // first is a substring of the second string => less (negative value)
275         nRet = -1;
276     }
277     else
278     {
279         // greater or equal
280         nRet = pStr1End - pStr1;
281     }
282 
283     return nRet;
284 }
285 
286 /* ----------------------------------------------------------------------- */
287 
rtl_ustr_asciil_reverseCompare_WithLength(const sal_Unicode * pStr1,sal_Int32 nStr1Len,const char * pStr2,sal_Int32 nStr2Len)288 sal_Int32 SAL_CALL rtl_ustr_asciil_reverseCompare_WithLength( const sal_Unicode* pStr1,
289                                                               sal_Int32 nStr1Len,
290                                                               const char* pStr2,
291                                                               sal_Int32 nStr2Len )
292     SAL_THROW_EXTERN_C()
293 {
294     assert(nStr1Len >= 0 && nStr2Len >= 0);
295     const sal_Unicode*  pStr1Run = pStr1+nStr1Len;
296     const char*     pStr2Run = pStr2+nStr2Len;
297     sal_Int32           nRet;
298     while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
299     {
300         /* Check ASCII range */
301         SAL_WARN_IF( (static_cast<unsigned char>(*pStr2)) > 127, "rtl.string",
302                     "rtl_ustr_asciil_reverseCompare_WithLength - Found char > 127" );
303         pStr1Run--;
304         pStr2Run--;
305         nRet = static_cast<sal_Int32>(*pStr1Run)- static_cast<sal_Int32>(*pStr2Run);
306         if ( nRet )
307             return nRet;
308     }
309 
310     return nStr1Len - nStr2Len;
311 }
312 
313 /* ----------------------------------------------------------------------- */
314 
rtl_ustr_asciil_reverseEquals_WithLength(const sal_Unicode * pStr1,const char * pStr2,sal_Int32 nStrLen)315 sal_Bool SAL_CALL rtl_ustr_asciil_reverseEquals_WithLength( const sal_Unicode* pStr1,
316                                                               const char* pStr2,
317                                                               sal_Int32 nStrLen )
318     SAL_THROW_EXTERN_C()
319 {
320     assert(nStrLen >= 0);
321     const sal_Unicode*  pStr1Run = pStr1+nStrLen;
322     const char*     pStr2Run = pStr2+nStrLen;
323     while ( pStr1 < pStr1Run )
324     {
325         /* Check ASCII range */
326         SAL_WARN_IF( (static_cast<unsigned char>(*pStr2)) > 127, "rtl.string",
327                     "rtl_ustr_asciil_reverseEquals_WithLength - Found char > 127" );
328         pStr1Run--;
329         pStr2Run--;
330         if( *pStr1Run != static_cast<sal_Unicode>(*pStr2Run) )
331             return false;
332     }
333 
334     return true;
335 }
336 
337 /* ----------------------------------------------------------------------- */
338 
rtl_ustr_ascii_compareIgnoreAsciiCase(const sal_Unicode * pStr1,const char * pStr2)339 sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase( const sal_Unicode* pStr1,
340                                                           const char* pStr2 )
341     SAL_THROW_EXTERN_C()
342 {
343     assert(pStr1);
344     assert(pStr2);
345     sal_Int32   nRet;
346     sal_Int32   c1;
347     sal_Int32   c2;
348     do
349     {
350         /* Check ASCII range */
351         SAL_WARN_IF( (static_cast<unsigned char>(*pStr2)) > 127, "rtl.string",
352                     "rtl_ustr_ascii_compareIgnoreAsciiCase - Found char > 127" );
353         /* If character between 'A' and 'Z', then convert it to lowercase */
354         c1 = static_cast<sal_Int32>(*pStr1);
355         c2 = static_cast<sal_Int32>(static_cast<unsigned char>(*pStr2));
356         if ( (c1 >= 65) && (c1 <= 90) )
357             c1 += 32;
358         if ( (c2 >= 65) && (c2 <= 90) )
359             c2 += 32;
360         nRet = c1-c2;
361         if ( nRet != 0 )
362             return nRet;
363 
364         pStr1++;
365         pStr2++;
366     }
367     while ( c2 );
368 
369     return 0;
370 }
371 
372 /* ----------------------------------------------------------------------- */
373 
rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength(const sal_Unicode * pStr1,sal_Int32 nStr1Len,const char * pStr2)374 sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1,
375                                                                      sal_Int32 nStr1Len,
376                                                                      const char* pStr2 )
377     SAL_THROW_EXTERN_C()
378 {
379     assert(nStr1Len >= 0);
380     assert(pStr2);
381     sal_Int32   nRet;
382     sal_Int32   c1;
383     sal_Int32   c2;
384     do
385     {
386         /* Check ASCII range */
387         SAL_WARN_IF( (static_cast<unsigned char>(*pStr2)) > 127, "rtl.string",
388                     "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength - Found char > 127" );
389         if ( !nStr1Len )
390             return *pStr2 == '\0' ? 0 : -1;
391 
392         /* If character between 'A' and 'Z', then convert it to lowercase */
393         c1 = static_cast<sal_Int32>(*pStr1);
394         c2 = static_cast<sal_Int32>(static_cast<unsigned char>(*pStr2));
395         if ( (c1 >= 65) && (c1 <= 90) )
396             c1 += 32;
397         if ( (c2 >= 65) && (c2 <= 90) )
398             c2 += 32;
399         nRet = c1-c2;
400         if ( nRet != 0 )
401             return nRet;
402 
403         pStr1++;
404         pStr2++;
405         nStr1Len--;
406     }
407     while( c2 );
408 
409     return 0;
410 }
411 
rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(sal_Unicode const * first,sal_Int32 firstLen,char const * second,sal_Int32 secondLen)412 sal_Int32 rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
413     sal_Unicode const * first, sal_Int32 firstLen,
414     char const * second, sal_Int32 secondLen) SAL_THROW_EXTERN_C()
415 {
416     assert(firstLen >= 0 && secondLen >= 0);
417     sal_Int32 i;
418     sal_Int32 len = std::min(firstLen, secondLen);
419     for (i = 0; i < len; ++i) {
420         /* Check ASCII range */
421         SAL_WARN_IF( (static_cast<unsigned char>(*second)) > 127, "rtl.string",
422                     "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths - Found char > 127" );
423         sal_Int32 c1 = *first++;
424         sal_Int32 c2 = static_cast<unsigned char>(*second++);
425         sal_Int32 d;
426         if (c1 >= 65 && c1 <= 90) {
427             c1 += 32;
428         }
429         if (c2 >= 65 && c2 <= 90) {
430             c2 += 32;
431         }
432         d = c1 - c2;
433         if (d != 0) {
434             return d;
435         }
436     }
437     return firstLen - secondLen;
438 }
439 
440 /* ----------------------------------------------------------------------- */
441 
rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength(const sal_Unicode * pStr1,sal_Int32 nStr1Len,const char * pStr2,sal_Int32 nShortenedLength)442 sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1,
443                                                                               sal_Int32 nStr1Len,
444                                                                               const char* pStr2,
445                                                                               sal_Int32 nShortenedLength )
446     SAL_THROW_EXTERN_C()
447 {
448     assert(nStr1Len >= 0);
449     assert(nShortenedLength >= 0);
450     const sal_Unicode*  pStr1End = pStr1 + nStr1Len;
451     sal_Int32           nRet;
452     sal_Int32           c1;
453     sal_Int32           c2;
454     while ( (nShortenedLength > 0) &&
455             (pStr1 < pStr1End) && *pStr2 )
456     {
457         /* Check ASCII range */
458         SAL_WARN_IF( (static_cast<unsigned char>(*pStr2)) > 127, "rtl.string",
459                     "rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength - Found char > 127" );
460 
461         /* If character between 'A' and 'Z', then convert it to lowercase */
462         c1 = static_cast<sal_Int32>(*pStr1);
463         c2 = static_cast<sal_Int32>(static_cast<unsigned char>(*pStr2));
464         if ( (c1 >= 65) && (c1 <= 90) )
465             c1 += 32;
466         if ( (c2 >= 65) && (c2 <= 90) )
467             c2 += 32;
468         nRet = c1-c2;
469         if ( nRet != 0 )
470             return nRet;
471 
472         nShortenedLength--;
473         pStr1++;
474         pStr2++;
475     }
476 
477     if ( nShortenedLength <= 0 )
478         return 0;
479 
480     if ( *pStr2 )
481     {
482         OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" );
483         // first is a substring of the second string => less (negative value)
484         nRet = -1;
485     }
486     else
487     {
488         // greater or equal
489         nRet = pStr1End - pStr1;
490     }
491 
492     return nRet;
493 }
494 
495 /* ----------------------------------------------------------------------- */
496 
rtl_uString_newFromAscii(rtl_uString ** ppThis,const char * pCharStr)497 void SAL_CALL rtl_uString_newFromAscii( rtl_uString** ppThis,
498                                         const char* pCharStr )
499     SAL_THROW_EXTERN_C()
500 {
501     assert(ppThis);
502     sal_Int32 nLen;
503 
504     if ( pCharStr )
505     {
506         const char* pTempStr = pCharStr;
507         while( *pTempStr )
508             pTempStr++;
509         nLen = pTempStr-pCharStr;
510     }
511     else
512         nLen = 0;
513 
514     if ( !nLen )
515     {
516         rtl_uString_new( ppThis );
517         return;
518     }
519 
520     if ( *ppThis )
521         rtl_uString_release( *ppThis );
522 
523     *ppThis = rtl_uString_ImplAlloc( nLen );
524     OSL_ASSERT(*ppThis != nullptr);
525     if ( !(*ppThis) )
526         return;
527 
528     sal_Unicode* pBuffer = (*ppThis)->buffer;
529     do
530     {
531         assert(static_cast<unsigned char>(*pCharStr) < 0x80); // ASCII range
532         *pBuffer = *pCharStr;
533         pBuffer++;
534         pCharStr++;
535     }
536     while ( *pCharStr );
537 
538     RTL_LOG_STRING_NEW( *ppThis );
539 }
540 
rtl_uString_newFromCodePoints(rtl_uString ** newString,sal_uInt32 const * codePoints,sal_Int32 codePointCount)541 void SAL_CALL rtl_uString_newFromCodePoints(
542     rtl_uString ** newString, sal_uInt32 const * codePoints,
543     sal_Int32 codePointCount) SAL_THROW_EXTERN_C()
544 {
545     sal_Int32 n;
546     sal_Int32 i;
547     sal_Unicode * p;
548     assert(newString != nullptr);
549     assert((codePoints != nullptr || codePointCount == 0) && codePointCount >= 0);
550     if (codePointCount == 0) {
551         rtl_uString_new(newString);
552         return;
553     }
554     if (*newString != nullptr) {
555         rtl_uString_release(*newString);
556     }
557     n = codePointCount;
558     for (i = 0; i < codePointCount; ++i) {
559         OSL_ASSERT(rtl::isUnicodeCodePoint(codePoints[i]));
560         if (codePoints[i] >= 0x10000) {
561             ++n;
562         }
563     }
564     /* Builds on the assumption that sal_Int32 uses 32 bit two's complement
565        representation with wrap around (the necessary number of UTF-16 code
566        units will be no larger than 2 * SAL_MAX_INT32, represented as
567        sal_Int32 -2): */
568     if (n < 0) {
569         // coverity[dead_error_begin] - assumes wrap around
570         *newString = nullptr;
571         return;
572     }
573     *newString = rtl_uString_ImplAlloc(n);
574     if (*newString == nullptr) {
575         return;
576     }
577     p = (*newString)->buffer;
578     for (i = 0; i < codePointCount; ++i) {
579         p += rtl::splitSurrogates(codePoints[i], p);
580     }
581     RTL_LOG_STRING_NEW( *newString );
582 }
583 
rtl_uString_newConcatAsciiL(rtl_uString ** newString,rtl_uString * left,char const * right,sal_Int32 rightLength)584 void rtl_uString_newConcatAsciiL(
585     rtl_uString ** newString, rtl_uString * left, char const * right,
586     sal_Int32 rightLength)
587 {
588     assert(newString != nullptr);
589     assert(left != nullptr);
590     assert(right != nullptr);
591     assert(rightLength >= 0);
592     if (left->length > std::numeric_limits<sal_Int32>::max() - rightLength) {
593 #if !defined(__COVERITY__)
594         throw std::length_error("rtl_uString_newConcatAsciiL");
595 #else
596         //coverity doesn't report std::bad_alloc as an unhandled exception when
597         //potentially thrown from destructors but does report std::length_error
598         throw std::bad_alloc();
599 #endif
600     }
601     sal_Int32 n = left->length + rightLength;
602     rtl_uString_assign(newString, left);
603     rtl_uString_ensureCapacity(newString, n);
604     sal_Unicode * p = (*newString)->buffer + (*newString)->length;
605     for (sal_Int32 i = 0; i != rightLength; ++i) {
606         p[i] = static_cast<unsigned char>(right[i]);
607     }
608     (*newString)->buffer[n] = 0;
609     (*newString)->length = n;
610 }
611 
rtl_uString_newConcatUtf16L(rtl_uString ** newString,rtl_uString * left,sal_Unicode const * right,sal_Int32 rightLength)612 void rtl_uString_newConcatUtf16L(
613     rtl_uString ** newString, rtl_uString * left, sal_Unicode const * right,
614     sal_Int32 rightLength)
615 {
616     assert(newString != nullptr);
617     assert(left != nullptr);
618     assert(right != nullptr || rightLength == 0);
619     assert(rightLength >= 0);
620     if (left->length > std::numeric_limits<sal_Int32>::max() - rightLength) {
621 #if !defined(__COVERITY__)
622         throw std::length_error("rtl_uString_newConcatUtf16L");
623 #else
624         //coverity doesn't report std::bad_alloc as an unhandled exception when
625         //potentially thrown from destructors but does report std::length_error
626         throw std::bad_alloc();
627 #endif
628     }
629     sal_Int32 n = left->length + rightLength;
630     rtl_uString_assign(newString, left);
631     rtl_uString_ensureCapacity(newString, n);
632     if (rightLength != 0) {
633         memcpy(
634             (*newString)->buffer + (*newString)->length, right,
635             rightLength * sizeof (sal_Unicode));
636     }
637     (*newString)->buffer[n] = 0;
638     (*newString)->length = n;
639 }
640 
641 /* ======================================================================= */
642 
rtl_ImplGetFastUTF8UnicodeLen(const char * pStr,sal_Int32 nLen,bool * ascii)643 static int rtl_ImplGetFastUTF8UnicodeLen( const char* pStr, sal_Int32 nLen, bool * ascii )
644 {
645     int             n;
646     const char* pEndStr;
647 
648     *ascii = true;
649     n = 0;
650     pEndStr  = pStr+nLen;
651     while ( pStr < pEndStr )
652     {
653         unsigned char c = static_cast<unsigned char>(*pStr);
654 
655         if ( !(c & 0x80) )
656             pStr++;
657         else
658         {
659             if ( (c & 0xE0) == 0xC0 )
660                 pStr += 2;
661             else if ( (c & 0xF0) == 0xE0 )
662                 pStr += 3;
663             else if ( (c & 0xF8) == 0xF0 )
664                 pStr += 4;
665             else if ( (c & 0xFC) == 0xF8 )
666                 pStr += 5;
667             else if ( (c & 0xFE) == 0xFC )
668                 pStr += 6;
669             else
670                 pStr++;
671             *ascii = false;
672         }
673 
674         n++;
675     }
676 
677     return n;
678 }
679 
680 /* ----------------------------------------------------------------------- */
681 
rtl_string2UString_status(rtl_uString ** ppThis,const char * pStr,sal_Int32 nLen,rtl_TextEncoding eTextEncoding,sal_uInt32 nCvtFlags,sal_uInt32 * pInfo)682 static void rtl_string2UString_status( rtl_uString** ppThis,
683                                        const char* pStr,
684                                        sal_Int32 nLen,
685                                        rtl_TextEncoding eTextEncoding,
686                                        sal_uInt32 nCvtFlags,
687                                        sal_uInt32 *pInfo )
688 {
689     OSL_ENSURE(nLen == 0 || rtl_isOctetTextEncoding(eTextEncoding),
690                "rtl_string2UString_status() - Wrong TextEncoding" );
691 
692     if ( !nLen )
693     {
694         rtl_uString_new( ppThis );
695         if (pInfo != nullptr) {
696             *pInfo = 0;
697         }
698     }
699     else
700     {
701         if ( *ppThis )
702             rtl_uString_release( *ppThis );
703 
704         /* Optimization for US-ASCII */
705         if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
706         {
707             sal_Unicode* pBuffer;
708             *ppThis = rtl_uString_ImplAlloc( nLen );
709             if (*ppThis == nullptr) {
710                 if (pInfo != nullptr) {
711                     *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
712                         RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL;
713                 }
714                 return;
715             }
716             pBuffer = (*ppThis)->buffer;
717             sal_Int32 nLenCopy(nLen);
718             const char *pStrCopy(pStr);
719             do
720             {
721                 /* Check ASCII range */
722                 if (static_cast<unsigned char>(*pStrCopy) > 127)
723                 {
724                     rtl_uString_release(*ppThis);
725                     goto retry; // cancel loop - try again with the converter
726                 }
727 
728                 *pBuffer = *pStrCopy;
729                 pBuffer++;
730                 pStrCopy++;
731                 nLenCopy--;
732             }
733             while (nLenCopy);
734             if (pInfo != nullptr) {
735                 *pInfo = 0;
736             }
737             RTL_LOG_STRING_NEW( *ppThis );
738             return;
739         }
740 retry:
741         {
742             rtl_uString*                pTemp;
743             rtl_uString*                pTemp2 = nullptr;
744             rtl_TextToUnicodeConverter  hConverter;
745             sal_uInt32                  nInfo;
746             sal_Size                    nSrcBytes;
747             sal_Size                    nDestChars;
748             sal_Size                    nNewLen;
749 
750             /* Optimization for UTF-8 - we try to calculate the exact length */
751             /* For all other encoding we try the maximum - and reallocate
752                the buffer if needed */
753             if ( eTextEncoding == RTL_TEXTENCODING_UTF8 )
754             {
755                 bool ascii;
756                 nNewLen = rtl_ImplGetFastUTF8UnicodeLen( pStr, nLen, &ascii );
757                 /* Includes the string only ASCII, then we could copy
758                    the buffer faster */
759                 if ( ascii )
760                 {
761                     sal_Unicode* pBuffer;
762                     *ppThis = rtl_uString_ImplAlloc( nLen );
763                     if (*ppThis == nullptr)
764                     {
765                         if (pInfo != nullptr) {
766                             *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
767                                 RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL;
768                         }
769                         return;
770                     }
771                     pBuffer = (*ppThis)->buffer;
772                     do
773                     {
774                         assert((static_cast<unsigned char>(*pStr)) <= 127);
775                         *pBuffer = *pStr;
776                         pBuffer++;
777                         pStr++;
778                         nLen--;
779                     }
780                     while ( nLen );
781                     if (pInfo != nullptr) {
782                         *pInfo = 0;
783                     }
784                     RTL_LOG_STRING_NEW( *ppThis );
785                     return;
786                 }
787             }
788             else
789                 nNewLen = nLen;
790 
791             nCvtFlags |= RTL_TEXTTOUNICODE_FLAGS_FLUSH;
792             hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
793 
794             pTemp = rtl_uString_ImplAlloc( nNewLen );
795             if (pTemp == nullptr) {
796                 if (pInfo != nullptr) {
797                     *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
798                         RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL;
799                 }
800                 return;
801             }
802             nDestChars = rtl_convertTextToUnicode( hConverter, nullptr,
803                                                    pStr, nLen,
804                                                    pTemp->buffer, nNewLen,
805                                                    nCvtFlags,
806                                                    &nInfo, &nSrcBytes );
807 
808             /* Buffer not big enough, try again with enough space */
809             /* Shouldn't be the case, but if we get textencoding which
810                could results in more unicode characters we have this
811                code here. Could be the case for apple encodings */
812             while ( nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL )
813             {
814                 rtl_freeString( pTemp );
815                 nNewLen += 8;
816                 pTemp = rtl_uString_ImplAlloc( nNewLen );
817                 if (pTemp == nullptr) {
818                     if (pInfo != nullptr) {
819                         *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
820                             RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL;
821                     }
822                     return;
823                 }
824                 nDestChars = rtl_convertTextToUnicode( hConverter, nullptr,
825                                                        pStr, nLen,
826                                                        pTemp->buffer, nNewLen,
827                                                        nCvtFlags,
828                                                        &nInfo, &nSrcBytes );
829             }
830 
831             if (pInfo)
832                 *pInfo = nInfo;
833 
834             /* Set the buffer to the correct size or if there is too
835                much overhead, reallocate to the correct size */
836             if ( nNewLen > nDestChars+8 )
837             {
838                 pTemp2 = rtl_uString_ImplAlloc( nDestChars );
839             }
840             if (pTemp2 != nullptr)
841             {
842                 rtl::str::Copy(pTemp2->buffer, pTemp->buffer, nDestChars);
843                 rtl_freeString(pTemp);
844                 pTemp = pTemp2;
845             }
846             else
847             {
848                 pTemp->length = nDestChars;
849                 pTemp->buffer[nDestChars] = 0;
850             }
851 
852             rtl_destroyTextToUnicodeConverter( hConverter );
853             *ppThis = pTemp;
854 
855             /* Results the conversion in an empty buffer -
856                create an empty string */
857             if ( pTemp && !nDestChars )
858                 rtl_uString_new( ppThis );
859         }
860     }
861     RTL_LOG_STRING_NEW( *ppThis );
862 }
863 
rtl_string2UString(rtl_uString ** ppThis,const char * pStr,sal_Int32 nLen,rtl_TextEncoding eTextEncoding,sal_uInt32 nCvtFlags)864 void SAL_CALL rtl_string2UString( rtl_uString** ppThis,
865                                   const char* pStr,
866                                   sal_Int32 nLen,
867                                   rtl_TextEncoding eTextEncoding,
868                                   sal_uInt32 nCvtFlags ) SAL_THROW_EXTERN_C()
869 {
870     assert(ppThis);
871     assert(nLen >= 0);
872     rtl_string2UString_status( ppThis, pStr, nLen, eTextEncoding,
873                                nCvtFlags, nullptr );
874 }
875 
876 /* ----------------------------------------------------------------------- */
877 
878 namespace {
879 
880 enum StrLifecycle {
881     CANNOT_RETURN,
882     CAN_RETURN = 1
883 };
884 
885 }
886 
887 static oslMutex
getInternMutex()888 getInternMutex()
889 {
890     static oslMutex pPoolGuard = osl_createMutex();
891 
892     return pPoolGuard;
893 }
894 
895 /* returns true if we found a dup in the pool */
rtl_ustring_intern_internal(rtl_uString ** newStr,rtl_uString * str,StrLifecycle can_return)896 static void rtl_ustring_intern_internal( rtl_uString ** newStr,
897                                          rtl_uString  * str,
898                                          StrLifecycle   can_return )
899 {
900     oslMutex pPoolMutex;
901 
902     pPoolMutex = getInternMutex();
903 
904     osl_acquireMutex( pPoolMutex );
905 
906     *newStr = rtl_str_hash_intern (str, can_return);
907 
908     osl_releaseMutex( pPoolMutex );
909 
910     RTL_LOG_STRING_INTERN_NEW(*newStr, str);
911 
912     if( can_return && *newStr != str )
913     { /* we dupped, then found a match */
914         rtl_freeString( str );
915     }
916 }
917 
rtl_uString_intern(rtl_uString ** newStr,rtl_uString * str)918 void SAL_CALL rtl_uString_intern( rtl_uString ** newStr,
919                                   rtl_uString  * str) SAL_THROW_EXTERN_C()
920 {
921     assert(newStr);
922     assert(str);
923     if (SAL_STRING_IS_INTERN(str))
924     {
925         rtl::str::acquire(str);
926         *newStr = str;
927     }
928     else
929     {
930         rtl_uString *pOrg = *newStr;
931         *newStr = nullptr;
932         rtl_ustring_intern_internal( newStr, str, CANNOT_RETURN );
933         if (pOrg)
934             rtl_uString_release (pOrg);
935     }
936 }
937 
rtl_canGuessUOutputLength(int len,rtl_TextEncoding eTextEncoding)938 static int rtl_canGuessUOutputLength( int len, rtl_TextEncoding eTextEncoding )
939 {
940     // FIXME: Maybe we should use a bit flag in the higher bits of the
941     // eTextEncoding value itself to determine the encoding type.  But if we
942     // do, be sure to mask the value in certain places that expect the values
943     // to be numbered serially from 0 and up.  One such place is
944     // Impl_getTextEncodingData().
945 
946     switch ( eTextEncoding )
947     {
948         // 1 to 1 (with no zero elements)
949         case RTL_TEXTENCODING_IBM_437:
950         case RTL_TEXTENCODING_IBM_850:
951         case RTL_TEXTENCODING_IBM_860:
952         case RTL_TEXTENCODING_IBM_861:
953         case RTL_TEXTENCODING_IBM_863:
954         case RTL_TEXTENCODING_IBM_865:
955             return len;
956     }
957     return 0;
958 }
959 
rtl_uString_internConvert(rtl_uString ** newStr,const char * str,sal_Int32 len,rtl_TextEncoding eTextEncoding,sal_uInt32 convertFlags,sal_uInt32 * pInfo)960 void SAL_CALL rtl_uString_internConvert( rtl_uString   ** newStr,
961                                          const char * str,
962                                          sal_Int32        len,
963                                          rtl_TextEncoding eTextEncoding,
964                                          sal_uInt32       convertFlags,
965                                          sal_uInt32     * pInfo )
966     SAL_THROW_EXTERN_C()
967 {
968     assert(newStr);
969     assert(len >= 0);
970     rtl_uString *scratch;
971 
972     if (*newStr)
973     {
974         rtl_uString_release (*newStr);
975         *newStr = nullptr;
976     }
977 
978     if ( len < 256 )
979     { // try various optimisations
980         sal_Int32 ulen;
981         if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
982         {
983             int i;
984             rtl_uString *pScratch;
985             pScratch = static_cast< rtl_uString * >(
986                 alloca(sizeof (rtl_uString) + len * sizeof (sal_Unicode)));
987             for (i = 0; i < len; i++)
988             {
989                 /* Check ASCII range */
990                 SAL_WARN_IF( (static_cast<unsigned char>(str[i])) > 127, "rtl.string",
991                             "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
992                 pScratch->buffer[i] = str[i];
993             }
994             pScratch->length = len;
995             rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
996             return;
997         }
998         if ( (ulen = rtl_canGuessUOutputLength(len, eTextEncoding)) != 0 )
999         {
1000             rtl_uString *pScratch;
1001             rtl_TextToUnicodeConverter hConverter;
1002             sal_Size nSrcBytes;
1003             sal_uInt32 nInfo;
1004 
1005             pScratch = static_cast< rtl_uString * >(
1006                 alloca(
1007                     sizeof (rtl_uString) + ulen * sizeof (sal_Unicode)));
1008 
1009             hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
1010             rtl_convertTextToUnicode(
1011                 hConverter, nullptr, str, len, pScratch->buffer, ulen, convertFlags, &nInfo, &nSrcBytes );
1012             rtl_destroyTextToUnicodeConverter( hConverter );
1013 
1014             if (pInfo)
1015                 *pInfo = nInfo;
1016 
1017             pScratch->length = ulen;
1018             rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
1019             return;
1020         }
1021 
1022         /* FIXME: we want a nice UTF-8 / alloca shortcut here */
1023     }
1024 
1025     scratch = nullptr;
1026     rtl_string2UString_status( &scratch, str, len, eTextEncoding, convertFlags,
1027                                pInfo );
1028     if (!scratch) {
1029         return;
1030     }
1031     rtl_ustring_intern_internal( newStr, scratch, CAN_RETURN );
1032 }
1033 
1034 static void
internRelease(rtl_uString * pThis)1035 internRelease (rtl_uString *pThis)
1036 {
1037     rtl_uString *pFree = nullptr;
1038     if ( SAL_STRING_REFCOUNT(
1039              osl_atomic_decrement( &(pThis->refCount) ) ) == 0)
1040     {
1041         RTL_LOG_STRING_INTERN_DELETE(pThis);
1042         oslMutex pPoolMutex = getInternMutex();
1043         osl_acquireMutex( pPoolMutex );
1044 
1045         rtl_str_hash_remove (pThis);
1046 
1047         /* May have been separately acquired */
1048         if ( SAL_STRING_REFCOUNT(
1049                  osl_atomic_increment( &(pThis->refCount) ) ) == 1 )
1050         {
1051             /* we got the last ref */
1052             pFree = pThis;
1053         }
1054         else /* very unusual */
1055         {
1056             internRelease (pThis);
1057         }
1058 
1059         osl_releaseMutex( pPoolMutex );
1060     }
1061     if (pFree)
1062         rtl_freeString (pFree);
1063 }
1064 
rtl_uString_iterateCodePoints(rtl_uString const * string,sal_Int32 * indexUtf16,sal_Int32 incrementCodePoints)1065 sal_uInt32 SAL_CALL rtl_uString_iterateCodePoints(
1066     rtl_uString const * string, sal_Int32 * indexUtf16,
1067     sal_Int32 incrementCodePoints)
1068 {
1069     sal_Int32 n;
1070     sal_Unicode cu;
1071     sal_uInt32 cp;
1072     assert(string != nullptr && indexUtf16 != nullptr);
1073     n = *indexUtf16;
1074     assert(n >= 0 && n <= string->length);
1075     while (incrementCodePoints < 0) {
1076         assert(n > 0);
1077         cu = string->buffer[--n];
1078         if (rtl::isLowSurrogate(cu) && n != 0 &&
1079             rtl::isHighSurrogate(string->buffer[n - 1]))
1080         {
1081             --n;
1082         }
1083         ++incrementCodePoints;
1084     }
1085     assert(n >= 0 && n < string->length);
1086     cu = string->buffer[n];
1087     if (rtl::isHighSurrogate(cu) && string->length - n >= 2 &&
1088         rtl::isLowSurrogate(string->buffer[n + 1]))
1089     {
1090         cp = rtl::combineSurrogates(cu, string->buffer[n + 1]);
1091     } else {
1092         cp = cu;
1093     }
1094     while (incrementCodePoints > 0) {
1095         assert(n < string->length);
1096         cu = string->buffer[n++];
1097         if (rtl::isHighSurrogate(cu) && n != string->length &&
1098             rtl::isLowSurrogate(string->buffer[n]))
1099         {
1100             ++n;
1101         }
1102         --incrementCodePoints;
1103     }
1104     assert(n >= 0 && n <= string->length);
1105     *indexUtf16 = n;
1106     return cp;
1107 }
1108 
rtl_convertStringToUString(rtl_uString ** target,char const * source,sal_Int32 length,rtl_TextEncoding encoding,sal_uInt32 flags)1109 sal_Bool rtl_convertStringToUString(
1110     rtl_uString ** target, char const * source, sal_Int32 length,
1111     rtl_TextEncoding encoding, sal_uInt32 flags) SAL_THROW_EXTERN_C()
1112 {
1113     assert(target);
1114     assert(length >= 0);
1115     sal_uInt32 info;
1116     rtl_string2UString_status(target, source, length, encoding, flags, &info);
1117     return (info & RTL_TEXTTOUNICODE_INFO_ERROR) == 0;
1118 }
1119 
rtl_uString_newReplaceFirst(rtl_uString ** newStr,rtl_uString * str,rtl_uString const * from,rtl_uString const * to,sal_Int32 * index)1120 void rtl_uString_newReplaceFirst(
1121     rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
1122     rtl_uString const * to, sal_Int32 * index) SAL_THROW_EXTERN_C()
1123 {
1124     assert(str != nullptr);
1125     assert(index != nullptr);
1126     assert(*index >= 0 && *index <= str->length);
1127     assert(from != nullptr);
1128     assert(to != nullptr);
1129     sal_Int32 i = rtl_ustr_indexOfStr_WithLength(
1130         str->buffer + *index, str->length - *index, from->buffer, from->length);
1131     if (i == -1) {
1132         rtl_uString_assign(newStr, str);
1133     } else {
1134         assert(i <= str->length - *index);
1135         i += *index;
1136         assert(from->length <= str->length);
1137         if (str->length - from->length > SAL_MAX_INT32 - to->length) {
1138             std::abort();
1139         }
1140         sal_Int32 n = str->length - from->length + to->length;
1141         rtl_uString_acquire(str); // in case *newStr == str
1142         rtl_uString_new_WithLength(newStr, n);
1143         if (n != 0) {
1144             (*newStr)->length = n;
1145             assert(i >= 0 && i < str->length);
1146             memcpy(
1147                 (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1148             memcpy(
1149                 (*newStr)->buffer + i, to->buffer,
1150                 to->length * sizeof (sal_Unicode));
1151             memcpy(
1152                 (*newStr)->buffer + i + to->length,
1153                 str->buffer + i + from->length,
1154                 (str->length - i - from->length) * sizeof (sal_Unicode));
1155         }
1156         rtl_uString_release(str);
1157     }
1158     *index = i;
1159 }
1160 
rtl_uString_newReplaceFirstAsciiL(rtl_uString ** newStr,rtl_uString * str,char const * from,sal_Int32 fromLength,rtl_uString const * to,sal_Int32 * index)1161 void rtl_uString_newReplaceFirstAsciiL(
1162     rtl_uString ** newStr, rtl_uString * str, char const * from,
1163     sal_Int32 fromLength, rtl_uString const * to, sal_Int32 * index)
1164     SAL_THROW_EXTERN_C()
1165 {
1166     assert(str != nullptr);
1167     assert(index != nullptr);
1168     assert(*index >= 0 && *index <= str->length);
1169     assert(fromLength >= 0);
1170     assert(to != nullptr);
1171     sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
1172         str->buffer + *index, str->length - *index, from, fromLength);
1173     if (i == -1) {
1174         rtl_uString_assign(newStr, str);
1175     } else {
1176         assert(i <= str->length - *index);
1177         i += *index;
1178         assert(fromLength <= str->length);
1179         if (str->length - fromLength > SAL_MAX_INT32 - to->length) {
1180             std::abort();
1181         }
1182         sal_Int32 n = str->length - fromLength + to->length;
1183         rtl_uString_acquire(str); // in case *newStr == str
1184         rtl_uString_new_WithLength(newStr, n);
1185         if (n != 0) {
1186             (*newStr)->length = n;
1187             assert(i >= 0 && i < str->length);
1188             memcpy(
1189                 (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1190             memcpy(
1191                 (*newStr)->buffer + i, to->buffer,
1192                 to->length * sizeof (sal_Unicode));
1193             memcpy(
1194                 (*newStr)->buffer + i + to->length,
1195                 str->buffer + i + fromLength,
1196                 (str->length - i - fromLength) * sizeof (sal_Unicode));
1197         }
1198         rtl_uString_release(str);
1199     }
1200     *index = i;
1201 }
1202 
rtl_uString_newReplaceFirstToAsciiL(rtl_uString ** newStr,rtl_uString * str,rtl_uString const * from,char const * to,sal_Int32 toLength,sal_Int32 * index)1203 void rtl_uString_newReplaceFirstToAsciiL(
1204     rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
1205     char const * to, sal_Int32 toLength, sal_Int32 * index)
1206     SAL_THROW_EXTERN_C()
1207 {
1208     assert(str != nullptr);
1209     assert(index != nullptr);
1210     assert(*index >= 0 && *index <= str->length);
1211     assert(from != nullptr);
1212     assert(toLength >= 0);
1213     sal_Int32 i = rtl_ustr_indexOfStr_WithLength(
1214         str->buffer + *index, str->length - *index, from->buffer, from->length);
1215     if (i == -1) {
1216         rtl_uString_assign(newStr, str);
1217     } else {
1218         assert(i <= str->length - *index);
1219         i += *index;
1220         assert(from->length <= str->length);
1221         if (str->length - from->length > SAL_MAX_INT32 - toLength) {
1222             std::abort();
1223         }
1224         sal_Int32 n = str->length - from->length + toLength;
1225         rtl_uString_acquire(str); // in case *newStr == str
1226         rtl_uString_new_WithLength(newStr, n);
1227         if (n != 0) {
1228             (*newStr)->length = n;
1229             assert(i >= 0 && i < str->length);
1230             memcpy(
1231                 (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1232             for (sal_Int32 j = 0; j != toLength; ++j) {
1233                 assert(static_cast< unsigned char >(to[j]) <= 0x7F);
1234                 (*newStr)->buffer[i + j] = to[j];
1235             }
1236             memcpy(
1237                 (*newStr)->buffer + i + toLength,
1238                 str->buffer + i + from->length,
1239                 (str->length - i - from->length) * sizeof (sal_Unicode));
1240         }
1241         rtl_uString_release(str);
1242     }
1243     *index = i;
1244 }
1245 
rtl_uString_newReplaceFirstAsciiLAsciiL(rtl_uString ** newStr,rtl_uString * str,char const * from,sal_Int32 fromLength,char const * to,sal_Int32 toLength,sal_Int32 * index)1246 void rtl_uString_newReplaceFirstAsciiLAsciiL(
1247     rtl_uString ** newStr, rtl_uString * str, char const * from,
1248     sal_Int32 fromLength, char const * to, sal_Int32 toLength,
1249     sal_Int32 * index) SAL_THROW_EXTERN_C()
1250 {
1251     assert(str != nullptr);
1252     assert(index != nullptr);
1253     assert(*index >= 0 && *index <= str->length);
1254     assert(fromLength >= 0);
1255     assert(to != nullptr);
1256     assert(toLength >= 0);
1257     sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
1258         str->buffer + *index, str->length - *index, from, fromLength);
1259     if (i == -1) {
1260         rtl_uString_assign(newStr, str);
1261     } else {
1262         assert(i <= str->length - *index);
1263         i += *index;
1264         assert(fromLength <= str->length);
1265         if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
1266             std::abort();
1267         }
1268         sal_Int32 n = str->length - fromLength + toLength;
1269         rtl_uString_acquire(str); // in case *newStr == str
1270         rtl_uString_new_WithLength(newStr, n);
1271         if (n != 0) {
1272             (*newStr)->length = n;
1273             assert(i >= 0 && i < str->length);
1274             memcpy(
1275                 (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1276             for (sal_Int32 j = 0; j != toLength; ++j) {
1277                 assert(static_cast< unsigned char >(to[j]) <= 0x7F);
1278                 (*newStr)->buffer[i + j] = to[j];
1279             }
1280             memcpy(
1281                 (*newStr)->buffer + i + toLength,
1282                 str->buffer + i + fromLength,
1283                 (str->length - i - fromLength) * sizeof (sal_Unicode));
1284         }
1285         rtl_uString_release(str);
1286     }
1287     *index = i;
1288 }
1289 
rtl_uString_newReplaceFirstAsciiLUtf16L(rtl_uString ** newStr,rtl_uString * str,char const * from,sal_Int32 fromLength,sal_Unicode const * to,sal_Int32 toLength,sal_Int32 * index)1290 void rtl_uString_newReplaceFirstAsciiLUtf16L(
1291     rtl_uString ** newStr, rtl_uString * str, char const * from,
1292     sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength,
1293     sal_Int32 * index) SAL_THROW_EXTERN_C()
1294 {
1295     assert(str != nullptr);
1296     assert(index != nullptr);
1297     assert(*index >= 0 && *index <= str->length);
1298     assert(fromLength >= 0);
1299     assert(to != nullptr || toLength == 0);
1300     assert(toLength >= 0);
1301     sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
1302         str->buffer + *index, str->length - *index, from, fromLength);
1303     if (i == -1) {
1304         rtl_uString_assign(newStr, str);
1305     } else {
1306         assert(i <= str->length - *index);
1307         i += *index;
1308         assert(fromLength <= str->length);
1309         if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
1310             rtl_uString_release(*newStr);
1311             *newStr = nullptr;
1312         } else {
1313             sal_Int32 n = str->length - fromLength + toLength;
1314             rtl_uString_acquire(str); // in case *newStr == str
1315             rtl_uString_new_WithLength(newStr, n);
1316             if (n != 0 && /*TODO:*/ *newStr != nullptr) {
1317                 (*newStr)->length = n;
1318                 assert(i >= 0 && i < str->length);
1319                 memcpy(
1320                     (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1321                 if (toLength != 0) {
1322                     memcpy(
1323                         (*newStr)->buffer + i, to, toLength * sizeof (sal_Unicode));
1324                 }
1325                 memcpy(
1326                     (*newStr)->buffer + i + toLength,
1327                     str->buffer + i + fromLength,
1328                     (str->length - i - fromLength) * sizeof (sal_Unicode));
1329             }
1330             rtl_uString_release(str);
1331         }
1332     }
1333     *index = i;
1334 }
1335 
rtl_uString_newReplaceFirstUtf16LAsciiL(rtl_uString ** newStr,rtl_uString * str,sal_Unicode const * from,sal_Int32 fromLength,char const * to,sal_Int32 toLength,sal_Int32 * index)1336 void rtl_uString_newReplaceFirstUtf16LAsciiL(
1337     rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from,
1338     sal_Int32 fromLength, char const * to, sal_Int32 toLength,
1339     sal_Int32 * index) SAL_THROW_EXTERN_C()
1340 {
1341     assert(str != nullptr);
1342     assert(index != nullptr);
1343     assert(*index >= 0 && *index <= str->length);
1344     assert(fromLength >= 0);
1345     assert(to != nullptr);
1346     assert(toLength >= 0);
1347     sal_Int32 i = rtl_ustr_indexOfStr_WithLength(
1348         str->buffer + *index, str->length - *index, from, fromLength);
1349     if (i == -1) {
1350         rtl_uString_assign(newStr, str);
1351     } else {
1352         assert(i <= str->length - *index);
1353         i += *index;
1354         assert(fromLength <= str->length);
1355         if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
1356             rtl_uString_release(*newStr);
1357             *newStr = nullptr;
1358         } else {
1359             sal_Int32 n = str->length - fromLength + toLength;
1360             rtl_uString_acquire(str); // in case *newStr == str
1361             rtl_uString_new_WithLength(newStr, n);
1362             if (n != 0 && /*TODO:*/ *newStr != nullptr) {
1363                 (*newStr)->length = n;
1364                 assert(i >= 0 && i < str->length);
1365                 memcpy(
1366                     (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1367                 for (sal_Int32 j = 0; j != toLength; ++j) {
1368                     assert(static_cast< unsigned char >(to[j]) <= 0x7F);
1369                     (*newStr)->buffer[i + j] = to[j];
1370                 }
1371                 memcpy(
1372                     (*newStr)->buffer + i + toLength,
1373                     str->buffer + i + fromLength,
1374                     (str->length - i - fromLength) * sizeof (sal_Unicode));
1375             }
1376             rtl_uString_release(str);
1377         }
1378     }
1379     *index = i;
1380 }
1381 
rtl_uString_newReplaceFirstUtf16LUtf16L(rtl_uString ** newStr,rtl_uString * str,sal_Unicode const * from,sal_Int32 fromLength,sal_Unicode const * to,sal_Int32 toLength,sal_Int32 * index)1382 void rtl_uString_newReplaceFirstUtf16LUtf16L(
1383     rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from,
1384     sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength,
1385     sal_Int32 * index) SAL_THROW_EXTERN_C()
1386 {
1387     assert(str != nullptr);
1388     assert(index != nullptr);
1389     assert(*index >= 0 && *index <= str->length);
1390     assert(from != nullptr || fromLength == 0);
1391     assert(fromLength >= 0);
1392     assert(to != nullptr || toLength == 0);
1393     assert(toLength >= 0);
1394     sal_Int32 i = rtl_ustr_indexOfStr_WithLength(
1395         str->buffer + *index, str->length - *index, from, fromLength);
1396     if (i == -1) {
1397         rtl_uString_assign(newStr, str);
1398     } else {
1399         assert(i <= str->length - *index);
1400         i += *index;
1401         assert(fromLength <= str->length);
1402         if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
1403             rtl_uString_release(*newStr);
1404             *newStr = nullptr;
1405         } else {
1406             sal_Int32 n = str->length - fromLength + toLength;
1407             rtl_uString_acquire(str); // in case *newStr == str
1408             rtl_uString_new_WithLength(newStr, n);
1409             if (n != 0 && /*TODO:*/ *newStr != nullptr) {
1410                 (*newStr)->length = n;
1411                 assert(i >= 0 && i < str->length);
1412                 memcpy(
1413                     (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1414                 if (toLength != 0) {
1415                     memcpy(
1416                         (*newStr)->buffer + i, to, toLength * sizeof (sal_Unicode));
1417                 }
1418                 memcpy(
1419                     (*newStr)->buffer + i + toLength,
1420                     str->buffer + i + fromLength,
1421                     (str->length - i - fromLength) * sizeof (sal_Unicode));
1422             }
1423             rtl_uString_release(str);
1424         }
1425     }
1426     *index = i;
1427 }
1428 
rtl_uString_newReplaceAll(rtl_uString ** newStr,rtl_uString * str,rtl_uString const * from,rtl_uString const * to)1429 void rtl_uString_newReplaceAll(
1430     rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
1431     rtl_uString const * to) SAL_THROW_EXTERN_C()
1432 {
1433     rtl_uString_newReplaceAllFromIndex( newStr, str, from, to, 0 );
1434 }
1435 
rtl_uString_newReplaceAllFromIndex(rtl_uString ** newStr,rtl_uString * str,rtl_uString const * from,rtl_uString const * to,sal_Int32 fromIndex)1436 void rtl_uString_newReplaceAllFromIndex(
1437     rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
1438     rtl_uString const * to, sal_Int32 fromIndex) SAL_THROW_EXTERN_C()
1439 {
1440     assert(to != nullptr);
1441     assert(fromIndex >= 0 && fromIndex <= str->length);
1442     rtl_uString_assign(newStr, str);
1443     for (sal_Int32 i = fromIndex;; i += to->length) {
1444         rtl_uString_newReplaceFirst(newStr, *newStr, from, to, &i);
1445         if (i == -1) {
1446             break;
1447         }
1448     }
1449 }
1450 
rtl_uString_newReplaceAllAsciiL(rtl_uString ** newStr,rtl_uString * str,char const * from,sal_Int32 fromLength,rtl_uString const * to)1451 void rtl_uString_newReplaceAllAsciiL(
1452     rtl_uString ** newStr, rtl_uString * str, char const * from,
1453     sal_Int32 fromLength, rtl_uString const * to) SAL_THROW_EXTERN_C()
1454 {
1455     assert(to != nullptr);
1456     rtl_uString_assign(newStr, str);
1457     for (sal_Int32 i = 0;; i += to->length) {
1458         rtl_uString_newReplaceFirstAsciiL(
1459             newStr, *newStr, from, fromLength, to, &i);
1460         if (i == -1) {
1461             break;
1462         }
1463     }
1464 }
1465 
rtl_uString_newReplaceAllToAsciiL(rtl_uString ** newStr,rtl_uString * str,rtl_uString const * from,char const * to,sal_Int32 toLength)1466 void rtl_uString_newReplaceAllToAsciiL(
1467     rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
1468     char const * to, sal_Int32 toLength) SAL_THROW_EXTERN_C()
1469 {
1470     assert(from != nullptr);
1471     rtl_uString_assign(newStr, str);
1472     for (sal_Int32 i = 0;; i += toLength) {
1473         rtl_uString_newReplaceFirstToAsciiL(
1474             newStr, *newStr, from, to, toLength, &i);
1475         if (i == -1) {
1476             break;
1477         }
1478     }
1479 }
1480 
rtl_uString_newReplaceAllAsciiLAsciiL(rtl_uString ** newStr,rtl_uString * str,char const * from,sal_Int32 fromLength,char const * to,sal_Int32 toLength)1481 void rtl_uString_newReplaceAllAsciiLAsciiL(
1482     rtl_uString ** newStr, rtl_uString * str, char const * from,
1483     sal_Int32 fromLength, char const * to, sal_Int32 toLength)
1484     SAL_THROW_EXTERN_C()
1485 {
1486     assert(toLength >= 0);
1487     rtl_uString_assign(newStr, str);
1488     for (sal_Int32 i = 0;; i += toLength) {
1489         rtl_uString_newReplaceFirstAsciiLAsciiL(
1490             newStr, *newStr, from, fromLength, to, toLength, &i);
1491         if (i == -1) {
1492             break;
1493         }
1494     }
1495 }
1496 
rtl_uString_newReplaceAllAsciiLUtf16L(rtl_uString ** newStr,rtl_uString * str,char const * from,sal_Int32 fromLength,sal_Unicode const * to,sal_Int32 toLength)1497 void rtl_uString_newReplaceAllAsciiLUtf16L(
1498     rtl_uString ** newStr, rtl_uString * str, char const * from,
1499     sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength)
1500     SAL_THROW_EXTERN_C()
1501 {
1502     assert(toLength >= 0);
1503     rtl_uString_assign(newStr, str);
1504     for (sal_Int32 i = 0;; i += toLength) {
1505         rtl_uString_newReplaceFirstAsciiLUtf16L(
1506             newStr, *newStr, from, fromLength, to, toLength, &i);
1507         if (i == -1 || *newStr == nullptr) {
1508             break;
1509         }
1510     }
1511 }
1512 
rtl_uString_newReplaceAllUtf16LAsciiL(rtl_uString ** newStr,rtl_uString * str,sal_Unicode const * from,sal_Int32 fromLength,char const * to,sal_Int32 toLength)1513 void rtl_uString_newReplaceAllUtf16LAsciiL(
1514     rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from,
1515     sal_Int32 fromLength, char const * to, sal_Int32 toLength)
1516     SAL_THROW_EXTERN_C()
1517 {
1518     assert(toLength >= 0);
1519     rtl_uString_assign(newStr, str);
1520     for (sal_Int32 i = 0;; i += toLength) {
1521         rtl_uString_newReplaceFirstUtf16LAsciiL(
1522             newStr, *newStr, from, fromLength, to, toLength, &i);
1523         if (i == -1 || *newStr == nullptr) {
1524             break;
1525         }
1526     }
1527 }
1528 
rtl_uString_newReplaceAllUtf16LUtf16L(rtl_uString ** newStr,rtl_uString * str,sal_Unicode const * from,sal_Int32 fromLength,sal_Unicode const * to,sal_Int32 toLength)1529 void rtl_uString_newReplaceAllUtf16LUtf16L(
1530     rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from,
1531     sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength)
1532     SAL_THROW_EXTERN_C()
1533 {
1534     rtl_uString_newReplaceAllFromIndexUtf16LUtf16L(newStr, str, from, fromLength, to, toLength, 0);
1535 }
1536 
rtl_uString_newReplaceAllFromIndexUtf16LUtf16L(rtl_uString ** newStr,rtl_uString * str,sal_Unicode const * from,sal_Int32 fromLength,sal_Unicode const * to,sal_Int32 toLength,sal_Int32 fromIndex)1537 void rtl_uString_newReplaceAllFromIndexUtf16LUtf16L(
1538     rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from,
1539     sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength, sal_Int32 fromIndex)
1540     SAL_THROW_EXTERN_C()
1541 {
1542     assert(toLength >= 0);
1543     assert(fromIndex >= 0 && fromIndex <= str->length);
1544     rtl_uString_assign(newStr, str);
1545     for (sal_Int32 i = fromIndex;; i += toLength) {
1546         rtl_uString_newReplaceFirstUtf16LUtf16L(
1547             newStr, *newStr, from, fromLength, to, toLength, &i);
1548         if (i == -1 || *newStr == nullptr) {
1549             break;
1550         }
1551     }
1552 }
1553 
rtl_ustr_getLength(const sal_Unicode * pStr)1554 sal_Int32 SAL_CALL rtl_ustr_getLength(const sal_Unicode* pStr) SAL_THROW_EXTERN_C()
1555 {
1556     return rtl::str::getLength(pStr);
1557 }
1558 
rtl_ustr_compare(const sal_Unicode * pStr1,const sal_Unicode * pStr2)1559 sal_Int32 SAL_CALL rtl_ustr_compare(const sal_Unicode* pStr1, const sal_Unicode* pStr2)
1560     SAL_THROW_EXTERN_C()
1561 {
1562     return rtl::str::compare(pStr1, pStr2);
1563 }
1564 
rtl_ustr_compare_WithLength(const sal_Unicode * pStr1,sal_Int32 nStr1Len,const sal_Unicode * pStr2,sal_Int32 nStr2Len)1565 sal_Int32 SAL_CALL rtl_ustr_compare_WithLength(const sal_Unicode* pStr1, sal_Int32 nStr1Len,
1566                                                const sal_Unicode* pStr2, sal_Int32 nStr2Len)
1567     SAL_THROW_EXTERN_C()
1568 {
1569     return rtl::str::compare_WithLength(pStr1, nStr1Len, pStr2, nStr2Len);
1570 }
1571 
rtl_ustr_shortenedCompare_WithLength(const sal_Unicode * pStr1,sal_Int32 nStr1Len,const sal_Unicode * pStr2,sal_Int32 nStr2Len,sal_Int32 nShortenedLength)1572 sal_Int32 SAL_CALL rtl_ustr_shortenedCompare_WithLength(
1573     const sal_Unicode* pStr1, sal_Int32 nStr1Len, const sal_Unicode* pStr2, sal_Int32 nStr2Len,
1574     sal_Int32 nShortenedLength) SAL_THROW_EXTERN_C()
1575 {
1576     return rtl::str::shortenedCompare_WithLength(pStr1, nStr1Len, pStr2, nStr2Len, nShortenedLength);
1577 }
1578 
rtl_ustr_reverseCompare_WithLength(const sal_Unicode * pStr1,sal_Int32 nStr1Len,const sal_Unicode * pStr2,sal_Int32 nStr2Len)1579 sal_Int32 SAL_CALL rtl_ustr_reverseCompare_WithLength(const sal_Unicode* pStr1, sal_Int32 nStr1Len,
1580                                                       const sal_Unicode* pStr2, sal_Int32 nStr2Len)
1581     SAL_THROW_EXTERN_C()
1582 {
1583     return rtl::str::reverseCompare_WithLength(pStr1, nStr1Len, pStr2, nStr2Len);
1584 }
1585 
rtl_ustr_compareIgnoreAsciiCase(const sal_Unicode * pStr1,const sal_Unicode * pStr2)1586 sal_Int32 SAL_CALL rtl_ustr_compareIgnoreAsciiCase(const sal_Unicode* pStr1,
1587                                                    const sal_Unicode* pStr2) SAL_THROW_EXTERN_C()
1588 {
1589     return rtl::str::compareIgnoreAsciiCase(pStr1, pStr2);
1590 }
1591 
rtl_ustr_compareIgnoreAsciiCase_WithLength(const sal_Unicode * pStr1,sal_Int32 nStr1Len,const sal_Unicode * pStr2,sal_Int32 nStr2Len)1592 sal_Int32 SAL_CALL rtl_ustr_compareIgnoreAsciiCase_WithLength(const sal_Unicode* pStr1,
1593                                                               sal_Int32 nStr1Len,
1594                                                               const sal_Unicode* pStr2,
1595                                                               sal_Int32 nStr2Len)
1596     SAL_THROW_EXTERN_C()
1597 {
1598     return rtl::str::compareIgnoreAsciiCase_WithLength(pStr1, nStr1Len, pStr2, nStr2Len);
1599 }
1600 
rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength(const sal_Unicode * pStr1,sal_Int32 nStr1Len,const sal_Unicode * pStr2,sal_Int32 nStr2Len,sal_Int32 nShortenedLength)1601 sal_Int32 SAL_CALL rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength(
1602     const sal_Unicode* pStr1, sal_Int32 nStr1Len, const sal_Unicode* pStr2, sal_Int32 nStr2Len,
1603     sal_Int32 nShortenedLength) SAL_THROW_EXTERN_C()
1604 {
1605     return rtl::str::shortenedCompareIgnoreAsciiCase_WithLength(pStr1, nStr1Len, pStr2, nStr2Len,
1606                                                               nShortenedLength);
1607 }
1608 
rtl_ustr_hashCode(const sal_Unicode * pStr)1609 sal_Int32 SAL_CALL rtl_ustr_hashCode(const sal_Unicode* pStr) SAL_THROW_EXTERN_C()
1610 {
1611     return rtl::str::hashCode(pStr);
1612 }
1613 
rtl_ustr_hashCode_WithLength(const sal_Unicode * pStr,sal_Int32 nLen)1614 sal_Int32 SAL_CALL rtl_ustr_hashCode_WithLength(const sal_Unicode* pStr, sal_Int32 nLen)
1615     SAL_THROW_EXTERN_C()
1616 {
1617     return rtl::str::hashCode_WithLength(pStr, nLen);
1618 }
1619 
rtl_ustr_indexOfChar(const sal_Unicode * pStr,sal_Unicode c)1620 sal_Int32 SAL_CALL rtl_ustr_indexOfChar(const sal_Unicode* pStr, sal_Unicode c) SAL_THROW_EXTERN_C()
1621 {
1622     return rtl::str::indexOfChar(pStr, c);
1623 }
1624 
rtl_ustr_indexOfChar_WithLength(const sal_Unicode * pStr,sal_Int32 nLen,sal_Unicode c)1625 sal_Int32 SAL_CALL rtl_ustr_indexOfChar_WithLength(const sal_Unicode* pStr, sal_Int32 nLen,
1626                                                    sal_Unicode c) SAL_THROW_EXTERN_C()
1627 {
1628     return rtl::str::indexOfChar_WithLength(pStr, nLen, c);
1629 }
1630 
rtl_ustr_lastIndexOfChar(const sal_Unicode * pStr,sal_Unicode c)1631 sal_Int32 SAL_CALL rtl_ustr_lastIndexOfChar(const sal_Unicode* pStr, sal_Unicode c)
1632     SAL_THROW_EXTERN_C()
1633 {
1634     return rtl::str::lastIndexOfChar(pStr, c);
1635 }
1636 
rtl_ustr_lastIndexOfChar_WithLength(const sal_Unicode * pStr,sal_Int32 nLen,sal_Unicode c)1637 sal_Int32 SAL_CALL rtl_ustr_lastIndexOfChar_WithLength(const sal_Unicode* pStr, sal_Int32 nLen,
1638                                                        sal_Unicode c) SAL_THROW_EXTERN_C()
1639 {
1640     return rtl::str::lastIndexOfChar_WithLength(pStr, nLen, c);
1641 }
1642 
rtl_ustr_indexOfStr(const sal_Unicode * pStr,const sal_Unicode * pSubStr)1643 sal_Int32 SAL_CALL rtl_ustr_indexOfStr(const sal_Unicode* pStr, const sal_Unicode* pSubStr)
1644     SAL_THROW_EXTERN_C()
1645 {
1646     return rtl::str::indexOfStr(pStr, pSubStr);
1647 }
1648 
rtl_ustr_indexOfStr_WithLength(const sal_Unicode * pStr,sal_Int32 nStrLen,const sal_Unicode * pSubStr,sal_Int32 nSubLen)1649 sal_Int32 SAL_CALL rtl_ustr_indexOfStr_WithLength(const sal_Unicode* pStr, sal_Int32 nStrLen,
1650                                                   const sal_Unicode* pSubStr, sal_Int32 nSubLen)
1651     SAL_THROW_EXTERN_C()
1652 {
1653     return rtl::str::indexOfStr_WithLength(pStr, nStrLen, pSubStr, nSubLen);
1654 }
1655 
rtl_ustr_lastIndexOfStr(const sal_Unicode * pStr,const sal_Unicode * pSubStr)1656 sal_Int32 SAL_CALL rtl_ustr_lastIndexOfStr(const sal_Unicode* pStr, const sal_Unicode* pSubStr)
1657     SAL_THROW_EXTERN_C()
1658 {
1659     return rtl::str::lastIndexOfStr(pStr, pSubStr);
1660 }
1661 
rtl_ustr_lastIndexOfStr_WithLength(const sal_Unicode * pStr,sal_Int32 nStrLen,const sal_Unicode * pSubStr,sal_Int32 nSubLen)1662 sal_Int32 SAL_CALL rtl_ustr_lastIndexOfStr_WithLength(const sal_Unicode* pStr, sal_Int32 nStrLen,
1663                                                       const sal_Unicode* pSubStr, sal_Int32 nSubLen)
1664     SAL_THROW_EXTERN_C()
1665 {
1666     return rtl::str::lastIndexOfStr_WithLength(pStr, nStrLen, pSubStr, nSubLen);
1667 }
1668 
rtl_ustr_replaceChar(sal_Unicode * pStr,sal_Unicode cOld,sal_Unicode cNew)1669 void SAL_CALL rtl_ustr_replaceChar(sal_Unicode* pStr, sal_Unicode cOld, sal_Unicode cNew)
1670     SAL_THROW_EXTERN_C()
1671 {
1672     return rtl::str::replaceChar(pStr, cOld, cNew);
1673 }
1674 
rtl_ustr_replaceChar_WithLength(sal_Unicode * pStr,sal_Int32 nLen,sal_Unicode cOld,sal_Unicode cNew)1675 void SAL_CALL rtl_ustr_replaceChar_WithLength(sal_Unicode* pStr, sal_Int32 nLen, sal_Unicode cOld,
1676                                               sal_Unicode cNew) SAL_THROW_EXTERN_C()
1677 {
1678     return rtl::str::replaceChar_WithLength(pStr, nLen, cOld, cNew);
1679 }
1680 
rtl_ustr_toAsciiLowerCase(sal_Unicode * pStr)1681 void SAL_CALL rtl_ustr_toAsciiLowerCase(sal_Unicode* pStr) SAL_THROW_EXTERN_C()
1682 {
1683     return rtl::str::toAsciiLowerCase(pStr);
1684 }
1685 
rtl_ustr_toAsciiLowerCase_WithLength(sal_Unicode * pStr,sal_Int32 nLen)1686 void SAL_CALL rtl_ustr_toAsciiLowerCase_WithLength(sal_Unicode* pStr, sal_Int32 nLen)
1687     SAL_THROW_EXTERN_C()
1688 {
1689     return rtl::str::toAsciiLowerCase_WithLength(pStr, nLen);
1690 }
1691 
rtl_ustr_toAsciiUpperCase(sal_Unicode * pStr)1692 void SAL_CALL rtl_ustr_toAsciiUpperCase(sal_Unicode* pStr) SAL_THROW_EXTERN_C()
1693 {
1694     return rtl::str::toAsciiUpperCase(pStr);
1695 }
1696 
rtl_ustr_toAsciiUpperCase_WithLength(sal_Unicode * pStr,sal_Int32 nLen)1697 void SAL_CALL rtl_ustr_toAsciiUpperCase_WithLength(sal_Unicode* pStr, sal_Int32 nLen)
1698     SAL_THROW_EXTERN_C()
1699 {
1700     return rtl::str::toAsciiUpperCase_WithLength(pStr, nLen);
1701 }
1702 
rtl_ustr_trim(sal_Unicode * pStr)1703 sal_Int32 SAL_CALL rtl_ustr_trim(sal_Unicode* pStr) SAL_THROW_EXTERN_C()
1704 {
1705     return rtl::str::trim(pStr);
1706 }
1707 
rtl_ustr_trim_WithLength(sal_Unicode * pStr,sal_Int32 nLen)1708 sal_Int32 SAL_CALL rtl_ustr_trim_WithLength(sal_Unicode* pStr, sal_Int32 nLen) SAL_THROW_EXTERN_C()
1709 {
1710     return rtl::str::trim_WithLength(pStr, nLen);
1711 }
1712 
rtl_ustr_valueOfBoolean(sal_Unicode * pStr,sal_Bool b)1713 sal_Int32 SAL_CALL rtl_ustr_valueOfBoolean(sal_Unicode* pStr, sal_Bool b) SAL_THROW_EXTERN_C()
1714 {
1715     return rtl::str::valueOfBoolean(pStr, b);
1716 }
1717 
rtl_ustr_valueOfChar(sal_Unicode * pStr,sal_Unicode c)1718 sal_Int32 SAL_CALL rtl_ustr_valueOfChar(sal_Unicode* pStr, sal_Unicode c) SAL_THROW_EXTERN_C()
1719 {
1720     return rtl::str::valueOfChar(pStr, c);
1721 }
1722 
rtl_ustr_valueOfInt32(sal_Unicode * pStr,sal_Int32 n,sal_Int16 nRadix)1723 sal_Int32 SAL_CALL rtl_ustr_valueOfInt32(sal_Unicode* pStr, sal_Int32 n, sal_Int16 nRadix)
1724     SAL_THROW_EXTERN_C()
1725 {
1726     return rtl::str::valueOfInt32(pStr, n, nRadix);
1727 }
1728 
rtl_ustr_valueOfInt64(sal_Unicode * pStr,sal_Int64 n,sal_Int16 nRadix)1729 sal_Int32 SAL_CALL rtl_ustr_valueOfInt64(sal_Unicode* pStr, sal_Int64 n, sal_Int16 nRadix)
1730     SAL_THROW_EXTERN_C()
1731 {
1732     return rtl::str::valueOfInt64(pStr, n, nRadix);
1733 }
1734 
rtl_ustr_valueOfUInt64(sal_Unicode * pStr,sal_uInt64 n,sal_Int16 nRadix)1735 sal_Int32 SAL_CALL rtl_ustr_valueOfUInt64(sal_Unicode* pStr, sal_uInt64 n, sal_Int16 nRadix)
1736     SAL_THROW_EXTERN_C()
1737 {
1738     return rtl::str::valueOfUInt64(pStr, n, nRadix);
1739 }
1740 
rtl_ustr_toBoolean(const sal_Unicode * pStr)1741 sal_Bool SAL_CALL rtl_ustr_toBoolean(const sal_Unicode* pStr) SAL_THROW_EXTERN_C()
1742 {
1743     return rtl::str::toBoolean(pStr);
1744 }
1745 
rtl_ustr_toInt32(const sal_Unicode * pStr,sal_Int16 nRadix)1746 sal_Int32 SAL_CALL rtl_ustr_toInt32(const sal_Unicode* pStr, sal_Int16 nRadix) SAL_THROW_EXTERN_C()
1747 {
1748     return rtl::str::toInt32(pStr, nRadix);
1749 }
1750 
rtl_ustr_toInt64(const sal_Unicode * pStr,sal_Int16 nRadix)1751 sal_Int64 SAL_CALL rtl_ustr_toInt64(const sal_Unicode* pStr, sal_Int16 nRadix) SAL_THROW_EXTERN_C()
1752 {
1753     return rtl::str::toInt64(pStr, nRadix);
1754 }
1755 
rtl_ustr_toInt64_WithLength(const sal_Unicode * pStr,sal_Int16 nRadix,sal_Int32 nStrLength)1756 sal_Int64 SAL_CALL rtl_ustr_toInt64_WithLength(const sal_Unicode* pStr, sal_Int16 nRadix,
1757                                                sal_Int32 nStrLength) SAL_THROW_EXTERN_C()
1758 {
1759     return rtl::str::toInt64_WithLength(pStr, nRadix, nStrLength);
1760 }
1761 
rtl_ustr_toUInt32(const sal_Unicode * pStr,sal_Int16 nRadix)1762 sal_uInt32 SAL_CALL rtl_ustr_toUInt32(const sal_Unicode* pStr, sal_Int16 nRadix)
1763     SAL_THROW_EXTERN_C()
1764 {
1765     return rtl::str::toUInt32(pStr, nRadix);
1766 }
1767 
rtl_ustr_toUInt64(const sal_Unicode * pStr,sal_Int16 nRadix)1768 sal_uInt64 SAL_CALL rtl_ustr_toUInt64(const sal_Unicode* pStr, sal_Int16 nRadix)
1769     SAL_THROW_EXTERN_C()
1770 {
1771     return rtl::str::toUInt64(pStr, nRadix);
1772 }
1773 
rtl_uString_ImplAlloc(sal_Int32 nLen)1774 rtl_uString* rtl_uString_ImplAlloc(sal_Int32 nLen)
1775 {
1776     return rtl::str::Alloc<rtl_uString>(nLen);
1777 }
1778 
rtl_uString_acquire(rtl_uString * pThis)1779 void SAL_CALL rtl_uString_acquire(rtl_uString* pThis) SAL_THROW_EXTERN_C()
1780 {
1781     return rtl::str::acquire(pThis);
1782 }
1783 
rtl_uString_release(rtl_uString * pThis)1784 void SAL_CALL rtl_uString_release(rtl_uString* pThis) SAL_THROW_EXTERN_C()
1785 {
1786     return rtl::str::release(pThis);
1787 }
1788 
rtl_uString_new(rtl_uString ** ppThis)1789 void SAL_CALL rtl_uString_new(rtl_uString** ppThis) SAL_THROW_EXTERN_C()
1790 {
1791     return rtl::str::new_(ppThis);
1792 }
1793 
rtl_uString_alloc(sal_Int32 nLen)1794 rtl_uString* SAL_CALL rtl_uString_alloc(sal_Int32 nLen) SAL_THROW_EXTERN_C()
1795 {
1796     return rtl::str::alloc<rtl_uString>(nLen);
1797 }
1798 
rtl_uString_new_WithLength(rtl_uString ** ppThis,sal_Int32 nLen)1799 void SAL_CALL rtl_uString_new_WithLength(rtl_uString** ppThis, sal_Int32 nLen) SAL_THROW_EXTERN_C()
1800 {
1801     rtl::str::new_WithLength(ppThis, nLen);
1802 }
1803 
rtl_uString_newFromString(rtl_uString ** ppThis,const rtl_uString * pStr)1804 void SAL_CALL rtl_uString_newFromString(rtl_uString** ppThis, const rtl_uString* pStr)
1805     SAL_THROW_EXTERN_C()
1806 {
1807     rtl::str::newFromString(ppThis, pStr);
1808 }
1809 
rtl_uString_newFromStr(rtl_uString ** ppThis,const sal_Unicode * pCharStr)1810 void SAL_CALL rtl_uString_newFromStr(rtl_uString** ppThis, const sal_Unicode* pCharStr)
1811     SAL_THROW_EXTERN_C()
1812 {
1813     rtl::str::newFromStr(ppThis, pCharStr);
1814 }
1815 
rtl_uString_newFromStr_WithLength(rtl_uString ** ppThis,const sal_Unicode * pCharStr,sal_Int32 nLen)1816 void SAL_CALL rtl_uString_newFromStr_WithLength(rtl_uString** ppThis, const sal_Unicode* pCharStr,
1817                                                 sal_Int32 nLen) SAL_THROW_EXTERN_C()
1818 {
1819     rtl::str::newFromStr_WithLength(ppThis, pCharStr, nLen);
1820 }
1821 
rtl_uString_newFromSubString(rtl_uString ** ppThis,const rtl_uString * pFrom,sal_Int32 beginIndex,sal_Int32 count)1822 void SAL_CALL rtl_uString_newFromSubString(rtl_uString** ppThis, const rtl_uString* pFrom,
1823                                            sal_Int32 beginIndex, sal_Int32 count)
1824     SAL_THROW_EXTERN_C()
1825 {
1826     rtl::str::newFromSubString(ppThis, pFrom, beginIndex, count);
1827 }
1828 
1829 // Used when creating from string literals.
rtl_uString_newFromLiteral(rtl_uString ** ppThis,const char * pCharStr,sal_Int32 nLen,sal_Int32 allocExtra)1830 void SAL_CALL rtl_uString_newFromLiteral(rtl_uString** ppThis, const char* pCharStr, sal_Int32 nLen,
1831                                          sal_Int32 allocExtra) SAL_THROW_EXTERN_C()
1832 {
1833     rtl::str::newFromLiteral(ppThis, pCharStr, nLen, allocExtra);
1834 }
1835 
rtl_uString_assign(rtl_uString ** ppThis,rtl_uString * pStr)1836 void SAL_CALL rtl_uString_assign(rtl_uString** ppThis, rtl_uString* pStr) SAL_THROW_EXTERN_C()
1837 {
1838     rtl::str::assign(ppThis, pStr);
1839 }
1840 
rtl_uString_getLength(const rtl_uString * pThis)1841 sal_Int32 SAL_CALL rtl_uString_getLength(const rtl_uString* pThis) SAL_THROW_EXTERN_C()
1842 {
1843     return rtl::str::getLength(pThis);
1844 }
1845 
rtl_uString_getStr(rtl_uString * pThis)1846 sal_Unicode* SAL_CALL rtl_uString_getStr(rtl_uString* pThis) SAL_THROW_EXTERN_C()
1847 {
1848     return rtl::str::getStr(pThis);
1849 }
1850 
rtl_uString_newConcat(rtl_uString ** ppThis,rtl_uString * pLeft,rtl_uString * pRight)1851 void SAL_CALL rtl_uString_newConcat(rtl_uString** ppThis, rtl_uString* pLeft, rtl_uString* pRight)
1852     SAL_THROW_EXTERN_C()
1853 {
1854     rtl::str::newConcat(ppThis, pLeft, pRight);
1855 }
1856 
rtl_uString_ensureCapacity(rtl_uString ** ppThis,sal_Int32 size)1857 void SAL_CALL rtl_uString_ensureCapacity(rtl_uString** ppThis, sal_Int32 size) SAL_THROW_EXTERN_C()
1858 {
1859     rtl::str::ensureCapacity(ppThis, size);
1860 }
1861 
rtl_uString_newReplaceStrAt(rtl_uString ** ppThis,rtl_uString * pStr,sal_Int32 nIndex,sal_Int32 nCount,rtl_uString * pNewSubStr)1862 void SAL_CALL rtl_uString_newReplaceStrAt(rtl_uString** ppThis, rtl_uString* pStr, sal_Int32 nIndex,
1863                                           sal_Int32 nCount, rtl_uString* pNewSubStr)
1864     SAL_THROW_EXTERN_C()
1865 {
1866     rtl::str::newReplaceStrAt(ppThis, pStr, nIndex, nCount, pNewSubStr);
1867 }
1868 
rtl_uString_newReplace(rtl_uString ** ppThis,rtl_uString * pStr,sal_Unicode cOld,sal_Unicode cNew)1869 void SAL_CALL rtl_uString_newReplace(rtl_uString** ppThis, rtl_uString* pStr, sal_Unicode cOld,
1870                                      sal_Unicode cNew) SAL_THROW_EXTERN_C()
1871 {
1872     rtl::str::newReplace(ppThis, pStr, cOld, cNew);
1873 }
1874 
rtl_uString_newToAsciiLowerCase(rtl_uString ** ppThis,rtl_uString * pStr)1875 void SAL_CALL rtl_uString_newToAsciiLowerCase(rtl_uString** ppThis, rtl_uString* pStr)
1876     SAL_THROW_EXTERN_C()
1877 {
1878     rtl::str::newToAsciiLowerCase(ppThis, pStr);
1879 }
1880 
rtl_uString_newToAsciiUpperCase(rtl_uString ** ppThis,rtl_uString * pStr)1881 void SAL_CALL rtl_uString_newToAsciiUpperCase(rtl_uString** ppThis, rtl_uString* pStr)
1882     SAL_THROW_EXTERN_C()
1883 {
1884     rtl::str::newToAsciiUpperCase(ppThis, pStr);
1885 }
1886 
rtl_uString_newTrim(rtl_uString ** ppThis,rtl_uString * pStr)1887 void SAL_CALL rtl_uString_newTrim(rtl_uString** ppThis, rtl_uString* pStr) SAL_THROW_EXTERN_C()
1888 {
1889     rtl::str::newTrim(ppThis, pStr);
1890 }
1891 
rtl_uString_getToken(rtl_uString ** ppThis,rtl_uString * pStr,sal_Int32 nToken,sal_Unicode cTok,sal_Int32 nIndex)1892 sal_Int32 SAL_CALL rtl_uString_getToken(rtl_uString** ppThis, rtl_uString* pStr, sal_Int32 nToken,
1893                                         sal_Unicode cTok, sal_Int32 nIndex) SAL_THROW_EXTERN_C()
1894 {
1895     return rtl::str::getToken(ppThis, pStr, nToken, cTok, nIndex);
1896 }
1897 
1898 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1899