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