Line data Source code
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 : #ifdef _MSC_VER
23 : #pragma warning(disable:4738) // storing 32-bit float result in memory, possible loss of performance
24 : #endif
25 :
26 : #include <cassert>
27 : #include <cstdlib>
28 :
29 : #include <osl/diagnose.h>
30 : #include <osl/interlck.h>
31 : #include <rtl/alloc.h>
32 : #include <osl/mutex.h>
33 : #include <osl/doublecheckedlocking.h>
34 : #include <rtl/tencinfo.h>
35 :
36 : #include <string.h>
37 : #include <sal/alloca.h>
38 : #include <sal/log.hxx>
39 :
40 : #include "hash.hxx"
41 : #include "strimp.hxx"
42 : #include "surrogates.hxx"
43 : #include <rtl/ustring.h>
44 :
45 : #include "rtl/math.h"
46 :
47 : /* ======================================================================= */
48 :
49 : /* static data to be referenced by all empty strings
50 : * the refCount is predefined to 1 and must never become 0 !
51 : */
52 : static rtl_uString const aImplEmpty_rtl_uString =
53 : {
54 : (sal_Int32) (SAL_STRING_INTERN_FLAG|SAL_STRING_STATIC_FLAG|1), /*sal_Int32 refCount; */
55 : 0, /*sal_Int32 length; */
56 : { 0 } /*sal_Unicode buffer[1];*/
57 : };
58 :
59 : /* ======================================================================= */
60 : /* These macros are for the "poor-man templates" included from
61 : * the strtmpl.cxx just below, used to share code between here and
62 : * string.cxx
63 : */
64 :
65 : #define IMPL_RTL_STRCODE sal_Unicode
66 : #define IMPL_RTL_USTRCODE( c ) (c)
67 : #define IMPL_RTL_STRNAME( n ) rtl_ustr_ ## n
68 :
69 : #define IMPL_RTL_STRINGNAME( n ) rtl_uString_ ## n
70 : #define IMPL_RTL_STRINGDATA rtl_uString
71 : #define IMPL_RTL_EMPTYSTRING aImplEmpty_rtl_uString
72 : #define IMPL_RTL_INTERN
73 : static void internRelease (rtl_uString *pThis);
74 :
75 : #if USE_SDT_PROBES
76 : #define RTL_LOG_STRING_BITS 16
77 : #endif
78 :
79 : /* ======================================================================= */
80 :
81 : /* Include String/UString template code */
82 :
83 : #include "strtmpl.cxx"
84 :
85 6544964 : sal_Int32 rtl_ustr_indexOfAscii_WithLength(
86 : sal_Unicode const * str, sal_Int32 len,
87 : char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
88 : {
89 6544964 : if (subLen > 0 && subLen <= len) {
90 : sal_Int32 i;
91 63684906 : for (i = 0; i <= len - subLen; ++i) {
92 60060997 : if (rtl_ustr_asciil_reverseEquals_WithLength(
93 60060997 : str + i, subStr, subLen))
94 : {
95 295235 : return i;
96 : }
97 : }
98 : }
99 6249729 : return -1;
100 : }
101 :
102 5599 : sal_Int32 rtl_ustr_lastIndexOfAscii_WithLength(
103 : sal_Unicode const * str, sal_Int32 len,
104 : char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
105 : {
106 5599 : if (subLen > 0 && subLen <= len) {
107 : sal_Int32 i;
108 6389 : for (i = len - subLen; i >= 0; --i) {
109 6387 : if (rtl_ustr_asciil_reverseEquals_WithLength(
110 6387 : str + i, subStr, subLen))
111 : {
112 5595 : return i;
113 : }
114 : }
115 : }
116 4 : return -1;
117 : }
118 :
119 82 : sal_Int32 SAL_CALL rtl_ustr_valueOfFloat(sal_Unicode * pStr, float f)
120 : SAL_THROW_EXTERN_C()
121 : {
122 82 : rtl_uString * pResult = NULL;
123 : sal_Int32 nLen;
124 : rtl_math_doubleToUString(
125 : &pResult, 0, 0, f, rtl_math_StringFormat_G,
126 : RTL_USTR_MAX_VALUEOFFLOAT - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0,
127 82 : 0, sal_True);
128 82 : nLen = pResult->length;
129 : OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFFLOAT);
130 82 : memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode));
131 82 : rtl_uString_release(pResult);
132 82 : return nLen;
133 : }
134 :
135 198517 : sal_Int32 SAL_CALL rtl_ustr_valueOfDouble(sal_Unicode * pStr, double d)
136 : SAL_THROW_EXTERN_C()
137 : {
138 198517 : rtl_uString * pResult = NULL;
139 : sal_Int32 nLen;
140 : rtl_math_doubleToUString(
141 : &pResult, 0, 0, d, rtl_math_StringFormat_G,
142 : RTL_USTR_MAX_VALUEOFDOUBLE - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0,
143 198517 : 0, sal_True);
144 198517 : nLen = pResult->length;
145 : OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFDOUBLE);
146 198517 : memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode));
147 198517 : rtl_uString_release(pResult);
148 198517 : return nLen;
149 : }
150 :
151 : namespace {
152 :
153 : // Avoid -fsanitize=undefined warning e.g. "runtime error: value 1e+99 is
154 : // outside the range of representable values of type 'float'":
155 232 : float doubleToFloat(double x) {
156 : return
157 232 : x < -std::numeric_limits<float>::max()
158 4 : ? -std::numeric_limits<float>::infinity()
159 228 : : x > std::numeric_limits<float>::max()
160 : ? std::numeric_limits<float>::infinity()
161 464 : : static_cast<float>(x);
162 : }
163 :
164 : }
165 :
166 232 : float SAL_CALL rtl_ustr_toFloat(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
167 : {
168 : return doubleToFloat(rtl_math_uStringToDouble(pStr,
169 232 : pStr + rtl_ustr_getLength(pStr),
170 232 : '.', 0, 0, 0));
171 : }
172 :
173 42946 : double SAL_CALL rtl_ustr_toDouble(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
174 : {
175 42946 : return rtl_math_uStringToDouble(pStr, pStr + rtl_ustr_getLength(pStr), '.',
176 42946 : 0, 0, 0);
177 : }
178 :
179 : /* ======================================================================= */
180 :
181 70555 : sal_Int32 SAL_CALL rtl_ustr_ascii_compare( const sal_Unicode* pStr1,
182 : const sal_Char* pStr2 )
183 : SAL_THROW_EXTERN_C()
184 : {
185 : sal_Int32 nRet;
186 857935 : while ( ((nRet = ((sal_Int32)(*pStr1))-
187 393690 : ((sal_Int32)((unsigned char)(*pStr2)))) == 0) &&
188 : *pStr2 )
189 : {
190 : /* Check ASCII range */
191 : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
192 : "rtl_ustr_ascii_compare - Found char > 127" );
193 323135 : pStr1++;
194 323135 : pStr2++;
195 : }
196 :
197 70555 : return nRet;
198 : }
199 :
200 : /* ----------------------------------------------------------------------- */
201 :
202 1106415333 : sal_Int32 SAL_CALL rtl_ustr_ascii_compare_WithLength( const sal_Unicode* pStr1,
203 : sal_Int32 nStr1Len,
204 : const sal_Char* pStr2 )
205 : SAL_THROW_EXTERN_C()
206 : {
207 1106415333 : sal_Int32 nRet = 0;
208 5707889585 : while( ((nRet = (nStr1Len ? (sal_Int32)(*pStr1) : 0)-
209 1208362204 : ((sal_Int32)((unsigned char)(*pStr2)))) == 0) &&
210 3495058921 : nStr1Len && *pStr2 )
211 : {
212 : /* Check ASCII range */
213 : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
214 : "rtl_ustr_ascii_compare_WithLength - Found char > 127" );
215 1194321793 : pStr1++;
216 1194321793 : pStr2++;
217 1194321793 : nStr1Len--;
218 : }
219 :
220 1106415333 : return nRet;
221 : }
222 :
223 : /* ----------------------------------------------------------------------- */
224 :
225 7614191 : sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompare_WithLength( const sal_Unicode* pStr1,
226 : sal_Int32 nStr1Len,
227 : const sal_Char* pStr2,
228 : sal_Int32 nShortenedLength )
229 : SAL_THROW_EXTERN_C()
230 : {
231 7614191 : const sal_Unicode* pStr1End = pStr1 + nStr1Len;
232 : sal_Int32 nRet;
233 32812630 : while ( (nShortenedLength > 0) &&
234 22056254 : (pStr1 < pStr1End) && *pStr2 )
235 : {
236 : /* Check ASCII range */
237 : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
238 : "rtl_ustr_ascii_shortenedCompare_WithLength - Found char > 127" );
239 :
240 22056254 : nRet = ((sal_Int32)*pStr1)-
241 22056254 : ((sal_Int32)(unsigned char)*pStr2);
242 22056254 : if ( nRet != 0 )
243 4472006 : return nRet;
244 :
245 17584248 : nShortenedLength--;
246 17584248 : pStr1++;
247 17584248 : pStr2++;
248 : }
249 :
250 3142185 : if ( nShortenedLength <= 0 )
251 3127548 : return 0;
252 :
253 14637 : if ( *pStr2 )
254 : {
255 : OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" );
256 : // first is a substring of the second string => less (negative value)
257 14637 : nRet = -1;
258 : }
259 : else
260 : {
261 : // greater or equal
262 0 : nRet = pStr1End - pStr1;
263 : }
264 :
265 14637 : return nRet;
266 : }
267 :
268 : /* ----------------------------------------------------------------------- */
269 :
270 6666 : sal_Int32 SAL_CALL rtl_ustr_asciil_reverseCompare_WithLength( const sal_Unicode* pStr1,
271 : sal_Int32 nStr1Len,
272 : const sal_Char* pStr2,
273 : sal_Int32 nStr2Len )
274 : SAL_THROW_EXTERN_C()
275 : {
276 6666 : const sal_Unicode* pStr1Run = pStr1+nStr1Len;
277 6666 : const sal_Char* pStr2Run = pStr2+nStr2Len;
278 : sal_Int32 nRet;
279 14174 : while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
280 : {
281 : /* Check ASCII range */
282 : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
283 : "rtl_ustr_asciil_reverseCompare_WithLength - Found char > 127" );
284 7468 : pStr1Run--;
285 7468 : pStr2Run--;
286 7468 : nRet = ((sal_Int32)*pStr1Run)-((sal_Int32)*pStr2Run);
287 7468 : if ( nRet )
288 6626 : return nRet;
289 : }
290 :
291 40 : return nStr1Len - nStr2Len;
292 : }
293 :
294 : /* ----------------------------------------------------------------------- */
295 :
296 121493281 : sal_Bool SAL_CALL rtl_ustr_asciil_reverseEquals_WithLength( const sal_Unicode* pStr1,
297 : const sal_Char* pStr2,
298 : sal_Int32 nStrLen )
299 : SAL_THROW_EXTERN_C()
300 : {
301 121493281 : const sal_Unicode* pStr1Run = pStr1+nStrLen;
302 121493281 : const sal_Char* pStr2Run = pStr2+nStrLen;
303 655654199 : while ( pStr1 < pStr1Run )
304 : {
305 : /* Check ASCII range */
306 : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
307 : "rtl_ustr_asciil_reverseEquals_WithLength - Found char > 127" );
308 496429868 : pStr1Run--;
309 496429868 : pStr2Run--;
310 496429868 : if( *pStr1Run != (sal_Unicode)*pStr2Run )
311 83762231 : return sal_False;
312 : }
313 :
314 37731050 : return sal_True;
315 : }
316 :
317 : /* ----------------------------------------------------------------------- */
318 :
319 0 : sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase( const sal_Unicode* pStr1,
320 : const sal_Char* pStr2 )
321 : SAL_THROW_EXTERN_C()
322 : {
323 : sal_Int32 nRet;
324 : sal_Int32 c1;
325 : sal_Int32 c2;
326 0 : do
327 : {
328 : /* Check ASCII range */
329 : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
330 : "rtl_ustr_ascii_compareIgnoreAsciiCase - Found char > 127" );
331 : /* If character between 'A' and 'Z', than convert it to lowercase */
332 0 : c1 = (sal_Int32)*pStr1;
333 0 : c2 = (sal_Int32)((unsigned char)*pStr2);
334 0 : if ( (c1 >= 65) && (c1 <= 90) )
335 0 : c1 += 32;
336 0 : if ( (c2 >= 65) && (c2 <= 90) )
337 0 : c2 += 32;
338 0 : nRet = c1-c2;
339 0 : if ( nRet != 0 )
340 0 : return nRet;
341 :
342 0 : pStr1++;
343 0 : pStr2++;
344 : }
345 : while ( c2 );
346 :
347 0 : return 0;
348 : }
349 :
350 : /* ----------------------------------------------------------------------- */
351 :
352 484099139 : sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1,
353 : sal_Int32 nStr1Len,
354 : const sal_Char* pStr2 )
355 : SAL_THROW_EXTERN_C()
356 : {
357 : sal_Int32 nRet;
358 : sal_Int32 c1;
359 : sal_Int32 c2;
360 67270637 : do
361 : {
362 : /* Check ASCII range */
363 : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
364 : "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength - Found char > 127" );
365 484099139 : if ( !nStr1Len )
366 2066679 : return *pStr2 == '\0' ? 0 : -1;
367 :
368 : /* If character between 'A' and 'Z', than convert it to lowercase */
369 482032460 : c1 = (sal_Int32)*pStr1;
370 482032460 : c2 = (sal_Int32)((unsigned char)*pStr2);
371 482032460 : if ( (c1 >= 65) && (c1 <= 90) )
372 420304964 : c1 += 32;
373 482032460 : if ( (c2 >= 65) && (c2 <= 90) )
374 415887783 : c2 += 32;
375 482032460 : nRet = c1-c2;
376 482032460 : if ( nRet != 0 )
377 414761823 : return nRet;
378 :
379 67270637 : pStr1++;
380 67270637 : pStr2++;
381 67270637 : nStr1Len--;
382 : }
383 : while( c2 );
384 :
385 0 : return 0;
386 : }
387 :
388 20199365 : sal_Int32 rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
389 : sal_Unicode const * first, sal_Int32 firstLen,
390 : char const * second, sal_Int32 secondLen) SAL_THROW_EXTERN_C()
391 : {
392 : sal_Int32 i;
393 20199365 : sal_Int32 len = firstLen < secondLen ? firstLen : secondLen;
394 22703940 : for (i = 0; i < len; ++i) {
395 : /* Check ASCII range */
396 : SAL_WARN_IF( ((unsigned char)*second) > 127, "rtl.string",
397 : "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths - Found char > 127" );
398 22594895 : sal_Int32 c1 = *first++;
399 22594895 : sal_Int32 c2 = (unsigned char) *second++;
400 : sal_Int32 d;
401 22594895 : if (c1 >= 65 && c1 <= 90) {
402 6081102 : c1 += 32;
403 : }
404 22594895 : if (c2 >= 65 && c2 <= 90) {
405 179198 : c2 += 32;
406 : }
407 22594895 : d = c1 - c2;
408 22594895 : if (d != 0) {
409 20090320 : return d;
410 : }
411 : }
412 109045 : return firstLen - secondLen;
413 : }
414 :
415 : /* ----------------------------------------------------------------------- */
416 :
417 3130811 : sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1,
418 : sal_Int32 nStr1Len,
419 : const sal_Char* pStr2,
420 : sal_Int32 nShortenedLength )
421 : SAL_THROW_EXTERN_C()
422 : {
423 3130811 : const sal_Unicode* pStr1End = pStr1 + nStr1Len;
424 : sal_Int32 nRet;
425 : sal_Int32 c1;
426 : sal_Int32 c2;
427 7736855 : while ( (nShortenedLength > 0) &&
428 4447088 : (pStr1 < pStr1End) && *pStr2 )
429 : {
430 : /* Check ASCII range */
431 : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
432 : "rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength - Found char > 127" );
433 :
434 : /* If character between 'A' and 'Z', than convert it to lowercase */
435 4447088 : c1 = (sal_Int32)*pStr1;
436 4447088 : c2 = (sal_Int32)((unsigned char)*pStr2);
437 4447088 : if ( (c1 >= 65) && (c1 <= 90) )
438 232276 : c1 += 32;
439 4447088 : if ( (c2 >= 65) && (c2 <= 90) )
440 232790 : c2 += 32;
441 4447088 : nRet = c1-c2;
442 4447088 : if ( nRet != 0 )
443 2971855 : return nRet;
444 :
445 1475233 : nShortenedLength--;
446 1475233 : pStr1++;
447 1475233 : pStr2++;
448 : }
449 :
450 158956 : if ( nShortenedLength <= 0 )
451 158854 : return 0;
452 :
453 102 : if ( *pStr2 )
454 : {
455 : OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" );
456 : // first is a substring of the second string => less (negative value)
457 102 : nRet = -1;
458 : }
459 : else
460 : {
461 : // greater or equal
462 0 : nRet = pStr1End - pStr1;
463 : }
464 :
465 102 : return nRet;
466 : }
467 :
468 : /* ----------------------------------------------------------------------- */
469 :
470 22452546 : void SAL_CALL rtl_uString_newFromAscii( rtl_uString** ppThis,
471 : const sal_Char* pCharStr )
472 : SAL_THROW_EXTERN_C()
473 : {
474 : sal_Int32 nLen;
475 :
476 22452546 : if ( pCharStr )
477 : {
478 22452232 : const sal_Char* pTempStr = pCharStr;
479 288157892 : while( *pTempStr )
480 243253428 : pTempStr++;
481 22452232 : nLen = pTempStr-pCharStr;
482 : }
483 : else
484 314 : nLen = 0;
485 :
486 22452546 : if ( !nLen )
487 : {
488 196934 : rtl_uString_new( ppThis );
489 22649480 : return;
490 : }
491 :
492 22255612 : if ( *ppThis )
493 9868 : rtl_uString_release( *ppThis );
494 :
495 22255612 : *ppThis = rtl_uString_ImplAlloc( nLen );
496 : OSL_ASSERT(*ppThis != NULL);
497 22255612 : if ( (*ppThis) )
498 : {
499 22255612 : sal_Unicode* pBuffer = (*ppThis)->buffer;
500 243253428 : do
501 : {
502 : /* Check ASCII range */
503 : SAL_WARN_IF( ((unsigned char)*pCharStr) > 127, "rtl.string",
504 : "rtl_uString_newFromAscii - Found char > 127" );
505 :
506 243253428 : *pBuffer = *pCharStr;
507 243253428 : pBuffer++;
508 243253428 : pCharStr++;
509 : }
510 : while ( *pCharStr );
511 :
512 : RTL_LOG_STRING_NEW( *ppThis );
513 : }
514 : }
515 :
516 13787 : void SAL_CALL rtl_uString_newFromCodePoints(
517 : rtl_uString ** newString, sal_uInt32 const * codePoints,
518 : sal_Int32 codePointCount) SAL_THROW_EXTERN_C()
519 : {
520 : sal_Int32 n;
521 : sal_Int32 i;
522 : sal_Unicode * p;
523 : OSL_ASSERT(
524 : newString != NULL &&
525 : (codePoints != NULL || codePointCount == 0) &&
526 : codePointCount >= 0);
527 13787 : if (codePointCount == 0) {
528 4254 : rtl_uString_new(newString);
529 4254 : return;
530 : }
531 9533 : if (*newString != NULL) {
532 0 : rtl_uString_release(*newString);
533 : }
534 9533 : n = codePointCount;
535 19462 : for (i = 0; i < codePointCount; ++i) {
536 : OSL_ASSERT(codePoints[i] <= 0x10FFFF);
537 9929 : if (codePoints[i] >= 0x10000) {
538 8 : ++n;
539 : }
540 : }
541 : /* Builds on the assumption that sal_Int32 uses 32 bit two's complement
542 : representation with wrap around (the necessary number of UTF-16 code
543 : units will be no larger than 2 * SAL_MAX_INT32, represented as
544 : sal_Int32 -2): */
545 9533 : if (n < 0) {
546 0 : *newString = NULL;
547 0 : return;
548 : }
549 9533 : *newString = rtl_uString_ImplAlloc(n);
550 9533 : if (*newString == NULL) {
551 0 : return;
552 : }
553 9533 : p = (*newString)->buffer;
554 19462 : for (i = 0; i < codePointCount; ++i) {
555 9929 : sal_uInt32 c = codePoints[i];
556 9929 : if (c < 0x10000) {
557 9921 : *p++ = (sal_Unicode) c;
558 : } else {
559 8 : c -= 0x10000;
560 8 : *p++ = (sal_Unicode) ((c >> 10) | SAL_RTL_FIRST_HIGH_SURROGATE);
561 8 : *p++ = (sal_Unicode) ((c & 0x3FF) | SAL_RTL_FIRST_LOW_SURROGATE);
562 : }
563 : }
564 : RTL_LOG_STRING_NEW( *newString );
565 : }
566 :
567 : /* ======================================================================= */
568 :
569 41459541 : static int rtl_ImplGetFastUTF8UnicodeLen( const sal_Char* pStr, sal_Int32 nLen, bool * ascii )
570 : {
571 : int n;
572 : unsigned char c;
573 : const sal_Char* pEndStr;
574 :
575 41459541 : *ascii = true;
576 41459541 : n = 0;
577 41459541 : pEndStr = pStr+nLen;
578 684123326 : while ( pStr < pEndStr )
579 : {
580 601204244 : c = (unsigned char)*pStr;
581 :
582 601204244 : if ( !(c & 0x80) )
583 598186270 : pStr++;
584 : else
585 : {
586 3017974 : if ( (c & 0xE0) == 0xC0 )
587 53918 : pStr += 2;
588 2964056 : else if ( (c & 0xF0) == 0xE0 )
589 2956918 : pStr += 3;
590 7138 : else if ( (c & 0xF8) == 0xF0 )
591 438 : pStr += 4;
592 6700 : else if ( (c & 0xFC) == 0xF8 )
593 0 : pStr += 5;
594 6700 : else if ( (c & 0xFE) == 0xFC )
595 30 : pStr += 6;
596 : else
597 6670 : pStr++;
598 3017974 : *ascii = false;
599 : }
600 :
601 601204244 : n++;
602 : }
603 :
604 41459541 : return n;
605 : }
606 :
607 : /* ----------------------------------------------------------------------- */
608 :
609 61805236 : static void rtl_string2UString_status( rtl_uString** ppThis,
610 : const sal_Char* pStr,
611 : sal_Int32 nLen,
612 : rtl_TextEncoding eTextEncoding,
613 : sal_uInt32 nCvtFlags,
614 : sal_uInt32 *pInfo )
615 : {
616 : OSL_ENSURE(nLen == 0 || rtl_isOctetTextEncoding(eTextEncoding),
617 : "rtl_string2UString_status() - Wrong TextEncoding" );
618 :
619 61805236 : if ( !nLen )
620 : {
621 1252282 : rtl_uString_new( ppThis );
622 1252282 : if (pInfo != NULL) {
623 959591 : *pInfo = 0;
624 : }
625 : }
626 : else
627 : {
628 60552954 : if ( *ppThis )
629 14160513 : rtl_uString_release( *ppThis );
630 :
631 : /* Optimization for US-ASCII */
632 60552957 : if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
633 : {
634 : sal_Unicode* pBuffer;
635 18872191 : *ppThis = rtl_uString_ImplAlloc( nLen );
636 18872191 : if (*ppThis == NULL) {
637 0 : if (pInfo != NULL) {
638 : *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
639 0 : RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
640 : }
641 0 : return;
642 : }
643 18872191 : pBuffer = (*ppThis)->buffer;
644 262317504 : do
645 : {
646 : /* Check ASCII range */
647 : SAL_WARN_IF( ((unsigned char)*pStr) > 127, "rtl.string",
648 : "rtl_string2UString_status() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
649 :
650 262317504 : *pBuffer = *pStr;
651 262317504 : pBuffer++;
652 262317504 : pStr++;
653 262317504 : nLen--;
654 : }
655 : while ( nLen );
656 18872191 : if (pInfo != NULL) {
657 13571748 : *pInfo = 0;
658 : }
659 : }
660 : else
661 : {
662 : rtl_uString* pTemp;
663 41680766 : rtl_uString* pTemp2 = NULL;
664 : rtl_TextToUnicodeConverter hConverter;
665 : sal_uInt32 nInfo;
666 : sal_Size nSrcBytes;
667 : sal_Size nDestChars;
668 : sal_Size nNewLen;
669 :
670 : /* Optimization for UTF-8 - we try to calculate the exact length */
671 : /* For all other encoding we try the maximum - and reallocate
672 : the buffer if needed */
673 41680766 : if ( eTextEncoding == RTL_TEXTENCODING_UTF8 )
674 : {
675 : bool ascii;
676 41459541 : nNewLen = rtl_ImplGetFastUTF8UnicodeLen( pStr, nLen, &ascii );
677 : /* Includes the string only ASCII, then we could copy
678 : the buffer faster */
679 41459542 : if ( ascii )
680 : {
681 : sal_Unicode* pBuffer;
682 40684680 : *ppThis = rtl_uString_ImplAlloc( nLen );
683 40684683 : if (*ppThis == NULL)
684 : {
685 0 : if (pInfo != NULL) {
686 : *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
687 0 : RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
688 : }
689 40684683 : return;
690 : }
691 40684683 : pBuffer = (*ppThis)->buffer;
692 588783326 : do
693 : {
694 : /* Check ASCII range */
695 : SAL_WARN_IF( ((unsigned char)*pStr) > 127, "rtl.string",
696 : "rtl_string2UString_status() - UTF8 test encoding is wrong" );
697 :
698 588783326 : *pBuffer = *pStr;
699 588783326 : pBuffer++;
700 588783326 : pStr++;
701 588783326 : nLen--;
702 : }
703 : while ( nLen );
704 40684683 : if (pInfo != NULL) {
705 20463161 : *pInfo = 0;
706 : }
707 : RTL_LOG_STRING_NEW( *ppThis );
708 40684683 : return;
709 : }
710 : }
711 : else
712 221225 : nNewLen = nLen;
713 :
714 996087 : nCvtFlags |= RTL_TEXTTOUNICODE_FLAGS_FLUSH;
715 996087 : hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
716 :
717 996087 : pTemp = rtl_uString_ImplAlloc( nNewLen );
718 996087 : if (pTemp == NULL) {
719 0 : if (pInfo != NULL) {
720 : *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
721 0 : RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
722 : }
723 0 : return;
724 : }
725 : nDestChars = rtl_convertTextToUnicode( hConverter, 0,
726 : pStr, nLen,
727 : pTemp->buffer, nNewLen,
728 : nCvtFlags,
729 996087 : &nInfo, &nSrcBytes );
730 :
731 : /* Buffer not big enough, try again with enough space */
732 : /* Shouldn't be the case, but if we get textencoding which
733 : could results in more unicode characters we have this
734 : code here. Could be the case for apple encodings */
735 1992532 : while ( nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL )
736 : {
737 358 : rtl_freeMemory( pTemp );
738 358 : nNewLen += 8;
739 358 : pTemp = rtl_uString_ImplAlloc( nNewLen );
740 358 : if (pTemp == NULL) {
741 0 : if (pInfo != NULL) {
742 : *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
743 0 : RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
744 : }
745 0 : return;
746 : }
747 : nDestChars = rtl_convertTextToUnicode( hConverter, 0,
748 : pStr, nLen,
749 : pTemp->buffer, nNewLen,
750 : nCvtFlags,
751 358 : &nInfo, &nSrcBytes );
752 : }
753 :
754 996087 : if (pInfo)
755 54886 : *pInfo = nInfo;
756 :
757 : /* Set the buffer to the correct size or if there is too
758 : much overhead, reallocate to the correct size */
759 996087 : if ( nNewLen > nDestChars+8 )
760 : {
761 4 : pTemp2 = rtl_uString_ImplAlloc( nDestChars );
762 : }
763 996087 : if (pTemp2 != NULL)
764 : {
765 4 : rtl_str_ImplCopy(pTemp2->buffer, pTemp->buffer, nDestChars);
766 4 : rtl_freeMemory(pTemp);
767 4 : pTemp = pTemp2;
768 : }
769 : else
770 : {
771 996083 : pTemp->length = nDestChars;
772 996083 : pTemp->buffer[nDestChars] = 0;
773 : }
774 :
775 996087 : rtl_destroyTextToUnicodeConverter( hConverter );
776 996087 : *ppThis = pTemp;
777 :
778 : /* Results the conversion in an empty buffer -
779 : create an empty string */
780 996087 : if ( pTemp && !nDestChars )
781 12 : rtl_uString_new( ppThis );
782 : }
783 : }
784 : RTL_LOG_STRING_NEW( *ppThis );
785 : }
786 :
787 25604648 : void SAL_CALL rtl_string2UString( rtl_uString** ppThis,
788 : const sal_Char* pStr,
789 : sal_Int32 nLen,
790 : rtl_TextEncoding eTextEncoding,
791 : sal_uInt32 nCvtFlags ) SAL_THROW_EXTERN_C()
792 : {
793 : rtl_string2UString_status( ppThis, pStr, nLen, eTextEncoding,
794 25604648 : nCvtFlags, NULL );
795 25604648 : }
796 :
797 : /* ----------------------------------------------------------------------- */
798 :
799 : enum StrLifecycle {
800 : CANNOT_RETURN,
801 : CAN_RETURN = 1
802 : };
803 :
804 : static oslMutex
805 2184547 : getInternMutex()
806 : {
807 : static oslMutex pPoolGuard = NULL;
808 2184547 : if( !pPoolGuard )
809 : {
810 : oslMutex pGlobalGuard;
811 243 : pGlobalGuard = *osl_getGlobalMutex();
812 243 : osl_acquireMutex( pGlobalGuard );
813 243 : if( !pPoolGuard )
814 : {
815 243 : oslMutex p = osl_createMutex();
816 : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
817 243 : pPoolGuard = p;
818 : }
819 243 : osl_releaseMutex( pGlobalGuard );
820 : }
821 : else
822 : {
823 : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
824 : }
825 :
826 2184547 : return pPoolGuard;
827 : }
828 :
829 : /* returns true if we found a dup in the pool */
830 1254763 : static void rtl_ustring_intern_internal( rtl_uString ** newStr,
831 : rtl_uString * str,
832 : StrLifecycle can_return )
833 : {
834 : oslMutex pPoolMutex;
835 :
836 1254763 : pPoolMutex = getInternMutex();
837 :
838 1254763 : osl_acquireMutex( pPoolMutex );
839 :
840 1254763 : *newStr = rtl_str_hash_intern (str, can_return);
841 :
842 1254763 : osl_releaseMutex( pPoolMutex );
843 :
844 : RTL_LOG_STRING_INTERN_NEW(*newStr, str);
845 :
846 1254763 : if( can_return && *newStr != str )
847 : { /* we dupped, then found a match */
848 283978 : rtl_freeMemory( str );
849 : }
850 1254763 : }
851 :
852 83201 : void SAL_CALL rtl_uString_intern( rtl_uString ** newStr,
853 : rtl_uString * str) SAL_THROW_EXTERN_C()
854 : {
855 83201 : if (SAL_STRING_IS_INTERN(str))
856 : {
857 2 : IMPL_RTL_AQUIRE( str );
858 2 : *newStr = str;
859 : }
860 : else
861 : {
862 83199 : rtl_uString *pOrg = *newStr;
863 83199 : *newStr = NULL;
864 83199 : rtl_ustring_intern_internal( newStr, str, CANNOT_RETURN );
865 83199 : if (pOrg)
866 0 : rtl_uString_release (pOrg);
867 : }
868 83201 : }
869 :
870 1151216 : static int rtl_canGuessUOutputLength( int len, rtl_TextEncoding eTextEncoding )
871 : {
872 : // FIXME: Maybe we should use a bit flag in the higher bits of the
873 : // eTextEncoding value itself to determine the encoding type. But if we
874 : // do, be sure to mask the value in certain places that expect the values
875 : // to be numbered serially from 0 and up. One such place is
876 : // Impl_getTextEncodingData().
877 :
878 1151216 : switch ( eTextEncoding )
879 : {
880 : // 1 to 1 (with no zero elements)
881 : case RTL_TEXTENCODING_IBM_437:
882 : case RTL_TEXTENCODING_IBM_850:
883 : case RTL_TEXTENCODING_IBM_860:
884 : case RTL_TEXTENCODING_IBM_861:
885 : case RTL_TEXTENCODING_IBM_863:
886 : case RTL_TEXTENCODING_IBM_865:
887 0 : return len;
888 : break;
889 : }
890 1151216 : return 0;
891 : }
892 :
893 1171564 : void SAL_CALL rtl_uString_internConvert( rtl_uString ** newStr,
894 : const sal_Char * str,
895 : sal_Int32 len,
896 : rtl_TextEncoding eTextEncoding,
897 : sal_uInt32 convertFlags,
898 : sal_uInt32 * pInfo )
899 : SAL_THROW_EXTERN_C()
900 : {
901 : rtl_uString *scratch;
902 :
903 1171564 : if (*newStr)
904 : {
905 0 : rtl_uString_release (*newStr);
906 0 : *newStr = NULL;
907 : }
908 :
909 1171564 : if ( len < 256 )
910 : { // try various optimisations
911 : sal_Int32 ulen;
912 1171564 : if ( len < 0 )
913 0 : len = strlen( str );
914 1171564 : if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
915 : {
916 : int i;
917 : rtl_uString *pScratch;
918 : pScratch = static_cast< rtl_uString * >(
919 20348 : alloca(sizeof (rtl_uString) + len * sizeof (sal_Unicode)));
920 142480 : for (i = 0; i < len; i++)
921 : {
922 : /* Check ASCII range */
923 : SAL_WARN_IF( ((unsigned char)str[i]) > 127, "rtl.string",
924 : "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
925 122132 : pScratch->buffer[i] = str[i];
926 : }
927 20348 : pScratch->length = len;
928 20348 : rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
929 40696 : return;
930 : }
931 1151216 : else if ( (ulen = rtl_canGuessUOutputLength(len, eTextEncoding)) != 0 )
932 : {
933 : rtl_uString *pScratch;
934 : rtl_TextToUnicodeConverter hConverter;
935 : sal_Size nSrcBytes;
936 : sal_uInt32 nInfo;
937 :
938 : pScratch = static_cast< rtl_uString * >(
939 0 : alloca(
940 0 : sizeof (rtl_uString) + ulen * sizeof (sal_Unicode)));
941 :
942 0 : hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
943 : rtl_convertTextToUnicode(
944 0 : hConverter, 0, str, len, pScratch->buffer, ulen, convertFlags, &nInfo, &nSrcBytes );
945 0 : rtl_destroyTextToUnicodeConverter( hConverter );
946 :
947 0 : if (pInfo)
948 0 : *pInfo = nInfo;
949 :
950 0 : pScratch->length = ulen;
951 0 : rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
952 0 : return;
953 : }
954 :
955 : /* FIXME: we want a nice UTF-8 / alloca shortcut here */
956 : }
957 :
958 1151216 : scratch = NULL;
959 : rtl_string2UString_status( &scratch, str, len, eTextEncoding, convertFlags,
960 1151216 : pInfo );
961 1151216 : if (!scratch) {
962 0 : return;
963 : }
964 1151216 : rtl_ustring_intern_internal( newStr, scratch, CAN_RETURN );
965 : }
966 :
967 : static void
968 11795268 : internRelease (rtl_uString *pThis)
969 : {
970 : oslMutex pPoolMutex;
971 :
972 11795268 : rtl_uString *pFree = NULL;
973 11795268 : if ( SAL_STRING_REFCOUNT(
974 : osl_atomic_decrement( &(pThis->refCount) ) ) == 0)
975 : {
976 : RTL_LOG_STRING_INTERN_DELETE(pThis);
977 929784 : pPoolMutex = getInternMutex();
978 929784 : osl_acquireMutex( pPoolMutex );
979 :
980 929784 : rtl_str_hash_remove (pThis);
981 :
982 : /* May have been separately acquired */
983 929784 : if ( SAL_STRING_REFCOUNT(
984 : osl_atomic_increment( &(pThis->refCount) ) ) == 1 )
985 : {
986 : /* we got the last ref */
987 929784 : pFree = pThis;
988 : }
989 : else /* very unusual */
990 : {
991 0 : internRelease (pThis);
992 : }
993 :
994 929784 : osl_releaseMutex( pPoolMutex );
995 : }
996 11795269 : if (pFree)
997 929784 : rtl_freeMemory (pFree);
998 11795269 : }
999 :
1000 26731358 : sal_uInt32 SAL_CALL rtl_uString_iterateCodePoints(
1001 : rtl_uString const * string, sal_Int32 * indexUtf16,
1002 : sal_Int32 incrementCodePoints)
1003 : {
1004 : sal_Int32 n;
1005 : sal_Unicode cu;
1006 : sal_uInt32 cp;
1007 : assert(string != NULL && indexUtf16 != NULL);
1008 26731358 : n = *indexUtf16;
1009 : assert(n >= 0 && n <= string->length);
1010 53666356 : while (incrementCodePoints < 0) {
1011 : assert(n > 0);
1012 203640 : cu = string->buffer[--n];
1013 203648 : if (isLowSurrogate(cu) && n != 0 &&
1014 8 : isHighSurrogate(string->buffer[n - 1]))
1015 : {
1016 6 : --n;
1017 : }
1018 203640 : ++incrementCodePoints;
1019 : }
1020 : assert(n >= 0 && n < string->length);
1021 26731358 : cu = string->buffer[n];
1022 26731380 : if (isHighSurrogate(cu) && string->length - n >= 2 &&
1023 22 : isLowSurrogate(string->buffer[n + 1]))
1024 : {
1025 22 : cp = combineSurrogates(cu, string->buffer[n + 1]);
1026 : } else {
1027 26731336 : cp = cu;
1028 : }
1029 66193180 : while (incrementCodePoints > 0) {
1030 : assert(n < string->length);
1031 12730464 : cu = string->buffer[n++];
1032 12730480 : if (isHighSurrogate(cu) && n != string->length &&
1033 16 : isLowSurrogate(string->buffer[n]))
1034 : {
1035 16 : ++n;
1036 : }
1037 12730464 : --incrementCodePoints;
1038 : }
1039 : assert(n >= 0 && n <= string->length);
1040 26731358 : *indexUtf16 = n;
1041 26731358 : return cp;
1042 : }
1043 :
1044 35049386 : sal_Bool rtl_convertStringToUString(
1045 : rtl_uString ** target, char const * source, sal_Int32 length,
1046 : rtl_TextEncoding encoding, sal_uInt32 flags) SAL_THROW_EXTERN_C()
1047 : {
1048 : sal_uInt32 info;
1049 35049386 : rtl_string2UString_status(target, source, length, encoding, flags, &info);
1050 35049385 : return (info & RTL_TEXTTOUNICODE_INFO_ERROR) == 0;
1051 : }
1052 :
1053 293354 : void rtl_uString_newReplaceFirst(
1054 : rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
1055 : rtl_uString const * to, sal_Int32 * index) SAL_THROW_EXTERN_C()
1056 : {
1057 : assert(str != 0);
1058 : assert(index != 0);
1059 : assert(*index >= 0 && *index <= str->length);
1060 : assert(from != 0);
1061 : assert(to != 0);
1062 : sal_Int32 i = rtl_ustr_indexOfStr_WithLength(
1063 293354 : str->buffer + *index, str->length - *index, from->buffer, from->length);
1064 293354 : if (i == -1) {
1065 248772 : rtl_uString_assign(newStr, str);
1066 : } else {
1067 : assert(i <= str->length - *index);
1068 44582 : i += *index;
1069 : assert(from->length <= str->length);
1070 44582 : if (str->length - from->length > SAL_MAX_INT32 - to->length) {
1071 0 : std::abort();
1072 : }
1073 44582 : sal_Int32 n = str->length - from->length + to->length;
1074 44582 : rtl_uString_acquire(str); // in case *newStr == str
1075 44582 : rtl_uString_new_WithLength(newStr, n);
1076 44582 : if (n != 0) {
1077 44580 : (*newStr)->length = n;
1078 : assert(i >= 0 && i < str->length);
1079 : memcpy(
1080 44580 : (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1081 : memcpy(
1082 44580 : (*newStr)->buffer + i, to->buffer,
1083 89160 : to->length * sizeof (sal_Unicode));
1084 : memcpy(
1085 44580 : (*newStr)->buffer + i + to->length,
1086 44580 : str->buffer + i + from->length,
1087 89160 : (str->length - i - from->length) * sizeof (sal_Unicode));
1088 : }
1089 44582 : rtl_uString_release(str);
1090 : }
1091 293354 : *index = i;
1092 293354 : }
1093 :
1094 55387 : void rtl_uString_newReplaceFirstAsciiL(
1095 : rtl_uString ** newStr, rtl_uString * str, char const * from,
1096 : sal_Int32 fromLength, rtl_uString const * to, sal_Int32 * index)
1097 : SAL_THROW_EXTERN_C()
1098 : {
1099 : assert(str != 0);
1100 : assert(index != 0);
1101 : assert(*index >= 0 && *index <= str->length);
1102 : assert(fromLength >= 0);
1103 : assert(to != 0);
1104 : sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
1105 55387 : str->buffer + *index, str->length - *index, from, fromLength);
1106 55387 : if (i == -1) {
1107 26404 : rtl_uString_assign(newStr, str);
1108 : } else {
1109 : assert(i <= str->length - *index);
1110 28983 : i += *index;
1111 : assert(fromLength <= str->length);
1112 28983 : if (str->length - fromLength > SAL_MAX_INT32 - to->length) {
1113 0 : std::abort();
1114 : }
1115 28983 : sal_Int32 n = str->length - fromLength + to->length;
1116 28983 : rtl_uString_acquire(str); // in case *newStr == str
1117 28983 : if (n != 0) {
1118 28983 : rtl_uString_new_WithLength(newStr, n);
1119 28983 : (*newStr)->length = n;
1120 : assert(i >= 0 && i < str->length);
1121 : memcpy(
1122 28983 : (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1123 : memcpy(
1124 28983 : (*newStr)->buffer + i, to->buffer,
1125 57966 : to->length * sizeof (sal_Unicode));
1126 : memcpy(
1127 28983 : (*newStr)->buffer + i + to->length,
1128 28983 : str->buffer + i + fromLength,
1129 57966 : (str->length - i - fromLength) * sizeof (sal_Unicode));
1130 : }
1131 28983 : rtl_uString_release(str);
1132 : }
1133 55387 : *index = i;
1134 55387 : }
1135 :
1136 57236 : void rtl_uString_newReplaceFirstAsciiLAsciiL(
1137 : rtl_uString ** newStr, rtl_uString * str, char const * from,
1138 : sal_Int32 fromLength, char const * to, sal_Int32 toLength,
1139 : sal_Int32 * index) SAL_THROW_EXTERN_C()
1140 : {
1141 : assert(str != 0);
1142 : assert(index != 0);
1143 : assert(*index >= 0 && *index <= str->length);
1144 : assert(fromLength >= 0);
1145 : assert(to != 0);
1146 : assert(toLength >= 0);
1147 : sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
1148 57236 : str->buffer + *index, str->length - *index, from, fromLength);
1149 57236 : if (i == -1) {
1150 18216 : rtl_uString_assign(newStr, str);
1151 : } else {
1152 : assert(i <= str->length - *index);
1153 39020 : i += *index;
1154 : assert(fromLength <= str->length);
1155 39020 : if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
1156 0 : std::abort();
1157 : }
1158 39020 : sal_Int32 n = str->length - fromLength + toLength;
1159 39020 : rtl_uString_acquire(str); // in case *newStr == str
1160 39020 : if (n != 0) {
1161 39020 : rtl_uString_new_WithLength(newStr, n);
1162 39020 : (*newStr)->length = n;
1163 : assert(i >= 0 && i < str->length);
1164 : memcpy(
1165 39020 : (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1166 217278 : for (sal_Int32 j = 0; j != toLength; ++j) {
1167 : assert(static_cast< unsigned char >(to[j]) <= 0x7F);
1168 178258 : (*newStr)->buffer[i + j] = to[j];
1169 : }
1170 : memcpy(
1171 39020 : (*newStr)->buffer + i + toLength,
1172 39020 : str->buffer + i + fromLength,
1173 78040 : (str->length - i - fromLength) * sizeof (sal_Unicode));
1174 : }
1175 39020 : rtl_uString_release(str);
1176 : }
1177 57236 : *index = i;
1178 57236 : }
1179 :
1180 0 : void rtl_uString_newReplaceAll(
1181 : rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
1182 : rtl_uString const * to) SAL_THROW_EXTERN_C()
1183 : {
1184 0 : rtl_uString_newReplaceAllFromIndex( newStr, str, from, to, 0 );
1185 0 : }
1186 :
1187 247078 : void rtl_uString_newReplaceAllFromIndex(
1188 : rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
1189 : rtl_uString const * to, sal_Int32 fromIndex) SAL_THROW_EXTERN_C()
1190 : {
1191 : assert(to != 0);
1192 : assert(fromIndex >= 0 && fromIndex <= str->length);
1193 247078 : rtl_uString_assign(newStr, str);
1194 290388 : for (sal_Int32 i = fromIndex;; i += to->length) {
1195 290388 : rtl_uString_newReplaceFirst(newStr, *newStr, from, to, &i);
1196 290388 : if (i == -1) {
1197 247078 : break;
1198 : }
1199 43310 : }
1200 247078 : }
1201 :
1202 24652 : void rtl_uString_newReplaceAllAsciiL(
1203 : rtl_uString ** newStr, rtl_uString * str, char const * from,
1204 : sal_Int32 fromLength, rtl_uString const * to) SAL_THROW_EXTERN_C()
1205 : {
1206 : assert(to != 0);
1207 24652 : rtl_uString_assign(newStr, str);
1208 27998 : for (sal_Int32 i = 0;; i += to->length) {
1209 : rtl_uString_newReplaceFirstAsciiL(
1210 27998 : newStr, *newStr, from, fromLength, to, &i);
1211 27998 : if (i == -1) {
1212 24652 : break;
1213 : }
1214 3346 : }
1215 24652 : }
1216 :
1217 18204 : void rtl_uString_newReplaceAllAsciiLAsciiL(
1218 : rtl_uString ** newStr, rtl_uString * str, char const * from,
1219 : sal_Int32 fromLength, char const * to, sal_Int32 toLength)
1220 : SAL_THROW_EXTERN_C()
1221 : {
1222 : assert(toLength >= 0);
1223 18204 : rtl_uString_assign(newStr, str);
1224 55992 : for (sal_Int32 i = 0;; i += toLength) {
1225 : rtl_uString_newReplaceFirstAsciiLAsciiL(
1226 55992 : newStr, *newStr, from, fromLength, to, toLength, &i);
1227 55992 : if (i == -1) {
1228 18204 : break;
1229 : }
1230 37788 : }
1231 18204 : }
1232 :
1233 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|