Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "sal/config.h"
30 : :
31 : : #if defined(_MSC_VER) && (_MSC_VER >= 1400)
32 : : #pragma warning(disable:4738) // storing 32-bit float result in memory, possible loss of performance
33 : : #endif
34 : :
35 : : #include <cassert>
36 : : #include <cstdlib>
37 : :
38 : : #include <rtl/memory.h>
39 : : #include <osl/diagnose.h>
40 : : #include <osl/interlck.h>
41 : : #include <rtl/alloc.h>
42 : : #include <osl/mutex.h>
43 : : #include <osl/doublecheckedlocking.h>
44 : : #include <rtl/tencinfo.h>
45 : :
46 : : #include <string.h>
47 : : #include <sal/alloca.h>
48 : : #include <sal/log.hxx>
49 : :
50 : : #include "hash.hxx"
51 : : #include "strimp.hxx"
52 : : #include "surrogates.hxx"
53 : : #include <rtl/ustring.h>
54 : :
55 : : #include "rtl/math.h"
56 : : #include "rtl/tencinfo.h"
57 : :
58 : : /* ======================================================================= */
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 : : static rtl_uString const aImplEmpty_rtl_uString =
64 : : {
65 : : (sal_Int32) (SAL_STRING_INTERN_FLAG|SAL_STRING_STATIC_FLAG|1), /*sal_Int32 refCount; */
66 : : 0, /*sal_Int32 length; */
67 : : { 0 } /*sal_Unicode buffer[1];*/
68 : : };
69 : :
70 : : /* ======================================================================= */
71 : :
72 : : #define IMPL_RTL_STRCODE sal_Unicode
73 : : #define IMPL_RTL_USTRCODE( c ) (c)
74 : : #define IMPL_RTL_STRNAME( n ) rtl_ustr_ ## n
75 : :
76 : : #define IMPL_RTL_STRINGNAME( n ) rtl_uString_ ## n
77 : : #define IMPL_RTL_STRINGDATA rtl_uString
78 : : #define IMPL_RTL_EMPTYSTRING aImplEmpty_rtl_uString
79 : : #define IMPL_RTL_INTERN
80 : : static void internRelease (rtl_uString *pThis);
81 : :
82 : : /* ======================================================================= */
83 : :
84 : : /* Include String/UString template code */
85 : :
86 : : #include "strtmpl.cxx"
87 : :
88 : 5890191 : sal_Int32 rtl_ustr_indexOfAscii_WithLength(
89 : : sal_Unicode const * str, sal_Int32 len,
90 : : char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
91 : : {
92 [ + - ][ + + ]: 5890191 : if (subLen > 0 && subLen <= len) {
93 : : sal_Int32 i;
94 [ + + ]: 23180809 : for (i = 0; i <= len - subLen; ++i) {
95 [ + + ]: 20634894 : if (rtl_ustr_asciil_reverseEquals_WithLength(
96 : 20634894 : str + i, subStr, subLen))
97 : : {
98 : 64905 : return i;
99 : : }
100 : : }
101 : : }
102 : 5890191 : return -1;
103 : : }
104 : :
105 : 5983 : sal_Int32 rtl_ustr_lastIndexOfAscii_WithLength(
106 : : sal_Unicode const * str, sal_Int32 len,
107 : : char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C()
108 : : {
109 [ + - ][ + - ]: 5983 : if (subLen > 0 && subLen <= len) {
110 : : sal_Int32 i;
111 [ + - ]: 5983 : for (i = len - subLen; i >= 0; --i) {
112 [ + - ]: 5983 : if (rtl_ustr_asciil_reverseEquals_WithLength(
113 : 5983 : str + i, subStr, subLen))
114 : : {
115 : 5983 : return i;
116 : : }
117 : : }
118 : : }
119 : 5983 : return -1;
120 : : }
121 : :
122 : 0 : sal_Int32 SAL_CALL rtl_ustr_valueOfFloat(sal_Unicode * pStr, float f)
123 : : SAL_THROW_EXTERN_C()
124 : : {
125 : 0 : rtl_uString * pResult = NULL;
126 : : sal_Int32 nLen;
127 : : rtl_math_doubleToUString(
128 : : &pResult, 0, 0, f, rtl_math_StringFormat_G,
129 : : RTL_USTR_MAX_VALUEOFFLOAT - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0,
130 : 0 : 0, sal_True);
131 : 0 : nLen = pResult->length;
132 : : OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFFLOAT);
133 : 0 : memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode));
134 : 0 : rtl_uString_release(pResult);
135 : 0 : return nLen;
136 : : }
137 : :
138 : 20010 : sal_Int32 SAL_CALL rtl_ustr_valueOfDouble(sal_Unicode * pStr, double d)
139 : : SAL_THROW_EXTERN_C()
140 : : {
141 : 20010 : rtl_uString * pResult = NULL;
142 : : sal_Int32 nLen;
143 : : rtl_math_doubleToUString(
144 : : &pResult, 0, 0, d, rtl_math_StringFormat_G,
145 : : RTL_USTR_MAX_VALUEOFDOUBLE - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0,
146 : 20010 : 0, sal_True);
147 : 20010 : nLen = pResult->length;
148 : : OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFDOUBLE);
149 : 20010 : memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode));
150 : 20010 : rtl_uString_release(pResult);
151 : 20010 : return nLen;
152 : : }
153 : :
154 : 0 : float SAL_CALL rtl_ustr_toFloat(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
155 : : {
156 : : return (float) rtl_math_uStringToDouble(pStr,
157 : 0 : pStr + rtl_ustr_getLength(pStr),
158 : 0 : '.', 0, 0, 0);
159 : : }
160 : :
161 : 10024 : double SAL_CALL rtl_ustr_toDouble(sal_Unicode const * pStr) SAL_THROW_EXTERN_C()
162 : : {
163 : 10024 : return rtl_math_uStringToDouble(pStr, pStr + rtl_ustr_getLength(pStr), '.',
164 : 10024 : 0, 0, 0);
165 : : }
166 : :
167 : : /* ======================================================================= */
168 : :
169 : 40888 : sal_Int32 SAL_CALL rtl_ustr_ascii_compare( const sal_Unicode* pStr1,
170 : : const sal_Char* pStr2 )
171 : : SAL_THROW_EXTERN_C()
172 : : {
173 : : sal_Int32 nRet;
174 [ + + ][ + + ]: 351231 : while ( ((nRet = ((sal_Int32)(*pStr1))-
[ + + ]
175 : : ((sal_Int32)((unsigned char)(*pStr2)))) == 0) &&
176 : : *pStr2 )
177 : : {
178 : : /* Check ASCII range */
179 : : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
180 : : "rtl_ustr_ascii_compare - Found char > 127" );
181 : 310343 : pStr1++;
182 : 310343 : pStr2++;
183 : : }
184 : :
185 : 40888 : return nRet;
186 : : }
187 : :
188 : : /* ----------------------------------------------------------------------- */
189 : :
190 : 69495677 : sal_Int32 SAL_CALL rtl_ustr_ascii_compare_WithLength( const sal_Unicode* pStr1,
191 : : sal_Int32 nStr1Len,
192 : : const sal_Char* pStr2 )
193 : : SAL_THROW_EXTERN_C()
194 : : {
195 : 69495677 : sal_Int32 nRet = 0;
196 [ + + ][ + + ]: 114092836 : while( ((nRet = (nStr1Len ? (sal_Int32)(*pStr1) : 0)-
[ + + ][ + + ]
[ + + ]
197 : : ((sal_Int32)((unsigned char)(*pStr2)))) == 0) &&
198 : : nStr1Len && *pStr2 )
199 : : {
200 : : /* Check ASCII range */
201 : : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
202 : : "rtl_ustr_ascii_compare_WithLength - Found char > 127" );
203 : 44597159 : pStr1++;
204 : 44597159 : pStr2++;
205 : 44597159 : nStr1Len--;
206 : : }
207 : :
208 : 69495677 : return nRet;
209 : : }
210 : :
211 : : /* ----------------------------------------------------------------------- */
212 : :
213 : 2152081 : sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompare_WithLength( const sal_Unicode* pStr1,
214 : : sal_Int32 nStr1Len,
215 : : const sal_Char* pStr2,
216 : : sal_Int32 nShortenedLength )
217 : : SAL_THROW_EXTERN_C()
218 : : {
219 : 2152081 : const sal_Unicode* pStr1End = pStr1 + nStr1Len;
220 : : sal_Int32 nRet;
221 [ + + ][ + + ]: 5230463 : while ( (nShortenedLength > 0) &&
[ + - ][ + + ]
222 : : (pStr1 < pStr1End) && *pStr2 )
223 : : {
224 : : /* Check ASCII range */
225 : : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
226 : : "rtl_ustr_ascii_shortenedCompare_WithLength - Found char > 127" );
227 : :
228 : : nRet = ((sal_Int32)*pStr1)-
229 : 4785634 : ((sal_Int32)(unsigned char)*pStr2);
230 [ + + ]: 4785634 : if ( nRet != 0 )
231 : 1707252 : return nRet;
232 : :
233 : 3078382 : nShortenedLength--;
234 : 3078382 : pStr1++;
235 : 3078382 : pStr2++;
236 : : }
237 : :
238 [ + + ]: 444829 : if ( nShortenedLength <= 0 )
239 : 314028 : return 0;
240 : :
241 [ + - ]: 130801 : if ( *pStr2 )
242 : : {
243 : : OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" );
244 : : // first is a substring of the second string => less (negative value)
245 : 130801 : nRet = -1;
246 : : }
247 : : else
248 : : {
249 : : // greater or equal
250 : 0 : nRet = pStr1End - pStr1;
251 : : }
252 : :
253 : 2152081 : return nRet;
254 : : }
255 : :
256 : : /* ----------------------------------------------------------------------- */
257 : :
258 : 751743 : sal_Int32 SAL_CALL rtl_ustr_asciil_reverseCompare_WithLength( const sal_Unicode* pStr1,
259 : : sal_Int32 nStr1Len,
260 : : const sal_Char* pStr2,
261 : : sal_Int32 nStr2Len )
262 : : SAL_THROW_EXTERN_C()
263 : : {
264 : 751743 : const sal_Unicode* pStr1Run = pStr1+nStr1Len;
265 : 751743 : const sal_Char* pStr2Run = pStr2+nStr2Len;
266 : : sal_Int32 nRet;
267 [ + + ][ + - ]: 1458000 : while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
[ + + ]
268 : : {
269 : : /* Check ASCII range */
270 : : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
271 : : "rtl_ustr_asciil_reverseCompare_WithLength - Found char > 127" );
272 : 1455623 : pStr1Run--;
273 : 1455623 : pStr2Run--;
274 : 1455623 : nRet = ((sal_Int32)*pStr1Run)-((sal_Int32)*pStr2Run);
275 [ + + ]: 1455623 : if ( nRet )
276 : 749366 : return nRet;
277 : : }
278 : :
279 : 751743 : return nStr1Len - nStr2Len;
280 : : }
281 : :
282 : : /* ----------------------------------------------------------------------- */
283 : :
284 : 37066145 : sal_Bool SAL_CALL rtl_ustr_asciil_reverseEquals_WithLength( const sal_Unicode* pStr1,
285 : : const sal_Char* pStr2,
286 : : sal_Int32 nStrLen )
287 : : SAL_THROW_EXTERN_C()
288 : : {
289 : 37066145 : const sal_Unicode* pStr1Run = pStr1+nStrLen;
290 : 37066145 : const sal_Char* pStr2Run = pStr2+nStrLen;
291 [ + + ]: 168352960 : while ( pStr1 < pStr1Run )
292 : : {
293 : : /* Check ASCII range */
294 : : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
295 : : "rtl_ustr_asciil_reverseEquals_WithLength - Found char > 127" );
296 : 155591683 : pStr1Run--;
297 : 155591683 : pStr2Run--;
298 [ + + ]: 155591683 : if( *pStr1Run != (sal_Unicode)*pStr2Run )
299 : 24304868 : return sal_False;
300 : : }
301 : :
302 : 37066145 : return sal_True;
303 : : }
304 : :
305 : : /* ----------------------------------------------------------------------- */
306 : :
307 : 0 : sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase( const sal_Unicode* pStr1,
308 : : const sal_Char* pStr2 )
309 : : SAL_THROW_EXTERN_C()
310 : : {
311 : : sal_Int32 nRet;
312 : : sal_Int32 c1;
313 : : sal_Int32 c2;
314 [ # # ]: 0 : do
315 : : {
316 : : /* Check ASCII range */
317 : : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
318 : : "rtl_ustr_ascii_compareIgnoreAsciiCase - Found char > 127" );
319 : : /* If character between 'A' and 'Z', than convert it to lowercase */
320 : 0 : c1 = (sal_Int32)*pStr1;
321 : 0 : c2 = (sal_Int32)((unsigned char)*pStr2);
322 [ # # ][ # # ]: 0 : if ( (c1 >= 65) && (c1 <= 90) )
323 : 0 : c1 += 32;
324 [ # # ][ # # ]: 0 : if ( (c2 >= 65) && (c2 <= 90) )
325 : 0 : c2 += 32;
326 : 0 : nRet = c1-c2;
327 [ # # ]: 0 : if ( nRet != 0 )
328 : 0 : return nRet;
329 : :
330 : 0 : pStr1++;
331 : 0 : pStr2++;
332 : : }
333 : : while ( c2 );
334 : :
335 : 0 : return 0;
336 : : }
337 : :
338 : : /* ----------------------------------------------------------------------- */
339 : :
340 : 8401136 : sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1,
341 : : sal_Int32 nStr1Len,
342 : : const sal_Char* pStr2 )
343 : : SAL_THROW_EXTERN_C()
344 : : {
345 : : sal_Int32 nRet;
346 : : sal_Int32 c1;
347 : : sal_Int32 c2;
348 [ + - ]: 6368385 : do
349 : : {
350 : : /* Check ASCII range */
351 : : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
352 : : "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength - Found char > 127" );
353 [ + + ]: 8401136 : if ( !nStr1Len )
354 [ + + ]: 747571 : return *pStr2 == '\0' ? 0 : -1;
355 : :
356 : : /* If character between 'A' and 'Z', than convert it to lowercase */
357 : 7653565 : c1 = (sal_Int32)*pStr1;
358 : 7653565 : c2 = (sal_Int32)((unsigned char)*pStr2);
359 [ + + ][ + + ]: 7653565 : if ( (c1 >= 65) && (c1 <= 90) )
360 : 1147395 : c1 += 32;
361 [ + + ][ + + ]: 7653565 : if ( (c2 >= 65) && (c2 <= 90) )
362 : 320450 : c2 += 32;
363 : 7653565 : nRet = c1-c2;
364 [ + + ]: 7653565 : if ( nRet != 0 )
365 : 1285180 : return nRet;
366 : :
367 : 6368385 : pStr1++;
368 : 6368385 : pStr2++;
369 : 6368385 : nStr1Len--;
370 : : }
371 : : while( c2 );
372 : :
373 : 2032751 : return 0;
374 : : }
375 : :
376 : 2163706 : sal_Int32 rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
377 : : sal_Unicode const * first, sal_Int32 firstLen,
378 : : char const * second, sal_Int32 secondLen) SAL_THROW_EXTERN_C()
379 : : {
380 : : sal_Int32 i;
381 [ - + ]: 2163706 : sal_Int32 len = firstLen < secondLen ? firstLen : secondLen;
382 [ + + ]: 7083077 : for (i = 0; i < len; ++i) {
383 : : /* Check ASCII range */
384 : : SAL_WARN_IF( ((unsigned char)*second) > 127, "rtl.string",
385 : : "rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths - Found char > 127" );
386 : 5872863 : sal_Int32 c1 = *first++;
387 : 5872863 : sal_Int32 c2 = (unsigned char) *second++;
388 : : sal_Int32 d;
389 [ + + ][ + + ]: 5872863 : if (c1 >= 65 && c1 <= 90) {
390 : 233768 : c1 += 32;
391 : : }
392 [ + + ][ + + ]: 5872863 : if (c2 >= 65 && c2 <= 90) {
393 : 328 : c2 += 32;
394 : : }
395 : 5872863 : d = c1 - c2;
396 [ + + ]: 5872863 : if (d != 0) {
397 : 953492 : return d;
398 : : }
399 : : }
400 : 2163706 : return firstLen - secondLen;
401 : : }
402 : :
403 : : /* ----------------------------------------------------------------------- */
404 : :
405 : 22698 : sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1,
406 : : sal_Int32 nStr1Len,
407 : : const sal_Char* pStr2,
408 : : sal_Int32 nShortenedLength )
409 : : SAL_THROW_EXTERN_C()
410 : : {
411 : 22698 : const sal_Unicode* pStr1End = pStr1 + nStr1Len;
412 : : sal_Int32 nRet;
413 : : sal_Int32 c1;
414 : : sal_Int32 c2;
415 [ + + ][ + + ]: 526438 : while ( (nShortenedLength > 0) &&
[ + - ][ + + ]
416 : : (pStr1 < pStr1End) && *pStr2 )
417 : : {
418 : : /* Check ASCII range */
419 : : SAL_WARN_IF( ((unsigned char)*pStr2) > 127, "rtl.string",
420 : : "rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength - Found char > 127" );
421 : :
422 : : /* If character between 'A' and 'Z', than convert it to lowercase */
423 : 524863 : c1 = (sal_Int32)*pStr1;
424 : 524863 : c2 = (sal_Int32)((unsigned char)*pStr2);
425 [ + + ][ + + ]: 524863 : if ( (c1 >= 65) && (c1 <= 90) )
426 : 139 : c1 += 32;
427 [ + + ][ + + ]: 524863 : if ( (c2 >= 65) && (c2 <= 90) )
428 : 292 : c2 += 32;
429 : 524863 : nRet = c1-c2;
430 [ + + ]: 524863 : if ( nRet != 0 )
431 : 21123 : return nRet;
432 : :
433 : 503740 : nShortenedLength--;
434 : 503740 : pStr1++;
435 : 503740 : pStr2++;
436 : : }
437 : :
438 [ + + ]: 1575 : if ( nShortenedLength <= 0 )
439 : 1465 : return 0;
440 : :
441 [ + - ]: 110 : if ( *pStr2 )
442 : : {
443 : : OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" );
444 : : // first is a substring of the second string => less (negative value)
445 : 110 : nRet = -1;
446 : : }
447 : : else
448 : : {
449 : : // greater or equal
450 : 0 : nRet = pStr1End - pStr1;
451 : : }
452 : :
453 : 22698 : return nRet;
454 : : }
455 : :
456 : : /* ----------------------------------------------------------------------- */
457 : :
458 : 6674902 : void SAL_CALL rtl_uString_newFromAscii( rtl_uString** ppThis,
459 : : const sal_Char* pCharStr )
460 : : SAL_THROW_EXTERN_C()
461 : : {
462 : : sal_Int32 nLen;
463 : :
464 [ + + ]: 6674902 : if ( pCharStr )
465 : : {
466 : 6674822 : const sal_Char* pTempStr = pCharStr;
467 [ + + ]: 68474300 : while( *pTempStr )
468 : 61799478 : pTempStr++;
469 : 6674822 : nLen = pTempStr-pCharStr;
470 : : }
471 : : else
472 : 80 : nLen = 0;
473 : :
474 [ + + ]: 6674902 : if ( !nLen )
475 : : {
476 : 31974 : IMPL_RTL_STRINGNAME( new )( ppThis );
477 : 6674905 : return;
478 : : }
479 : :
480 [ + + ]: 6642928 : if ( *ppThis )
481 : 11301 : IMPL_RTL_STRINGNAME( release )( *ppThis );
482 : :
483 : 6642928 : *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
484 : : OSL_ASSERT(*ppThis != NULL);
485 [ + - ]: 6642931 : if ( (*ppThis) )
486 : : {
487 : 6642931 : IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer;
488 [ + + ]: 61799739 : do
489 : : {
490 : : /* Check ASCII range */
491 : : SAL_WARN_IF( ((unsigned char)*pCharStr) > 127, "rtl.string",
492 : : "rtl_uString_newFromAscii - Found char > 127" );
493 : :
494 : 61799739 : *pBuffer = *pCharStr;
495 : 61799739 : pBuffer++;
496 : 61799739 : pCharStr++;
497 : : }
498 : : while ( *pCharStr );
499 : : }
500 : :
501 : : RTL_LOG_STRING_NEW( *ppThis );
502 : : }
503 : :
504 : 27878 : void SAL_CALL rtl_uString_newFromCodePoints(
505 : : rtl_uString ** newString, sal_uInt32 const * codePoints,
506 : : sal_Int32 codePointCount) SAL_THROW_EXTERN_C()
507 : : {
508 : : sal_Int32 n;
509 : : sal_Int32 i;
510 : : sal_Unicode * p;
511 : : OSL_ASSERT(
512 : : newString != NULL &&
513 : : (codePoints != NULL || codePointCount == 0) &&
514 : : codePointCount >= 0);
515 [ + + ]: 27878 : if (codePointCount == 0) {
516 : 13183 : rtl_uString_new(newString);
517 : 13183 : return;
518 : : }
519 [ - + ]: 14695 : if (*newString != NULL) {
520 : 0 : rtl_uString_release(*newString);
521 : : }
522 : 14695 : n = codePointCount;
523 [ + + ]: 29395 : for (i = 0; i < codePointCount; ++i) {
524 : : OSL_ASSERT(codePoints[i] <= 0x10FFFF);
525 [ + + ]: 14700 : if (codePoints[i] >= 0x10000) {
526 : 10 : ++n;
527 : : }
528 : : }
529 : : /* Builds on the assumption that sal_Int32 uses 32 bit two's complement
530 : : representation with wrap around (the necessary number of UTF-16 code
531 : : units will be no larger than 2 * SAL_MAX_INT32, represented as
532 : : sal_Int32 -2): */
533 [ - + ]: 14695 : if (n < 0) {
534 : 0 : *newString = NULL;
535 : 0 : return;
536 : : }
537 : 14695 : *newString = rtl_uString_ImplAlloc(n);
538 [ - + ]: 14695 : if (*newString == NULL) {
539 : 0 : return;
540 : : }
541 : 14695 : p = (*newString)->buffer;
542 [ + + ]: 42578 : for (i = 0; i < codePointCount; ++i) {
543 : 14700 : sal_uInt32 c = codePoints[i];
544 [ + + ]: 14700 : if (c < 0x10000) {
545 : 14690 : *p++ = (sal_Unicode) c;
546 : : } else {
547 : 10 : c -= 0x10000;
548 : 10 : *p++ = (sal_Unicode) ((c >> 10) | SAL_RTL_FIRST_HIGH_SURROGATE);
549 : 10 : *p++ = (sal_Unicode) ((c & 0x3FF) | SAL_RTL_FIRST_LOW_SURROGATE);
550 : : }
551 : : }
552 : : RTL_LOG_STRING_NEW( *newString );
553 : : }
554 : :
555 : : /* ======================================================================= */
556 : :
557 : 27672958 : static int rtl_ImplGetFastUTF8UnicodeLen( const sal_Char* pStr, sal_Int32 nLen )
558 : : {
559 : : int n;
560 : : sal_uChar c;
561 : : const sal_Char* pEndStr;
562 : :
563 : 27672958 : n = 0;
564 : 27672958 : pEndStr = pStr+nLen;
565 [ + + ]: 457659753 : while ( pStr < pEndStr )
566 : : {
567 : 429986795 : c = (sal_uChar)*pStr;
568 : :
569 [ + + ]: 429986795 : if ( !(c & 0x80) )
570 : 427130398 : pStr++;
571 [ + + ]: 2856397 : else if ( (c & 0xE0) == 0xC0 )
572 : 232519 : pStr += 2;
573 [ + - ]: 2623878 : else if ( (c & 0xF0) == 0xE0 )
574 : 2623878 : pStr += 3;
575 [ # # ]: 0 : else if ( (c & 0xF8) == 0xF0 )
576 : 0 : pStr += 4;
577 [ # # ]: 0 : else if ( (c & 0xFC) == 0xF8 )
578 : 0 : pStr += 5;
579 [ # # ]: 0 : else if ( (c & 0xFE) == 0xFC )
580 : 0 : pStr += 6;
581 : : else
582 : 0 : pStr++;
583 : :
584 : 429986795 : n++;
585 : : }
586 : :
587 : 27672958 : return n;
588 : : }
589 : :
590 : : /* ----------------------------------------------------------------------- */
591 : :
592 : 47773063 : static void rtl_string2UString_status( rtl_uString** ppThis,
593 : : const sal_Char* pStr,
594 : : sal_Int32 nLen,
595 : : rtl_TextEncoding eTextEncoding,
596 : : sal_uInt32 nCvtFlags,
597 : : sal_uInt32 *pInfo )
598 : : {
599 : : OSL_ENSURE(nLen == 0 || rtl_isOctetTextEncoding(eTextEncoding),
600 : : "rtl_string2UString_status() - Wrong TextEncoding" );
601 : :
602 [ + + ]: 47773063 : if ( !nLen )
603 : : {
604 : 1082499 : rtl_uString_new( ppThis );
605 [ + + ]: 1082499 : if (pInfo != NULL) {
606 : 837964 : *pInfo = 0;
607 : : }
608 : : }
609 : : else
610 : : {
611 [ + + ]: 46690564 : if ( *ppThis )
612 : 506373 : IMPL_RTL_STRINGNAME( release )( *ppThis );
613 : :
614 : : /* Optimization for US-ASCII */
615 [ + + ]: 46690576 : if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
616 : : {
617 : : IMPL_RTL_STRCODE* pBuffer;
618 : 18784042 : *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
619 [ - + ]: 18784043 : if (*ppThis == NULL) {
620 [ # # ]: 0 : if (pInfo != NULL) {
621 : : *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
622 : 0 : RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
623 : : }
624 : 0 : return;
625 : : }
626 : 18784043 : pBuffer = (*ppThis)->buffer;
627 [ + + ]: 297016148 : do
628 : : {
629 : : /* Check ASCII range */
630 : : SAL_WARN_IF( ((unsigned char)*pStr) > 127, "rtl.string",
631 : : "rtl_string2UString_status() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
632 : :
633 : 297016148 : *pBuffer = *pStr;
634 : 297016148 : pBuffer++;
635 : 297016148 : pStr++;
636 : 297016148 : nLen--;
637 : : }
638 : : while ( nLen );
639 [ - + ]: 18784043 : if (pInfo != NULL) {
640 : 0 : *pInfo = 0;
641 : : }
642 : : }
643 : : else
644 : : {
645 : : rtl_uString* pTemp;
646 : 27906534 : rtl_uString* pTemp2 = NULL;
647 : : rtl_TextToUnicodeConverter hConverter;
648 : : sal_uInt32 nInfo;
649 : : sal_Size nSrcBytes;
650 : : sal_Size nDestChars;
651 : : sal_Size nNewLen;
652 : :
653 : : /* Optimization for UTF-8 - we try to calculate the exact length */
654 : : /* For all other encoding we try the maximum - and reallocate
655 : : the buffer if needed */
656 [ + + ]: 27906534 : if ( eTextEncoding == RTL_TEXTENCODING_UTF8 )
657 : : {
658 : 27672958 : nNewLen = rtl_ImplGetFastUTF8UnicodeLen( pStr, nLen );
659 : : /* Includes the string only ASCII, then we could copy
660 : : the buffer faster */
661 [ + + ]: 27672958 : if ( nNewLen == (sal_Size)nLen )
662 : : {
663 : : IMPL_RTL_STRCODE* pBuffer;
664 [ + - ]: 26830558 : *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
665 [ - + ]: 26830559 : if (*ppThis == NULL)
666 : : {
667 [ # # ]: 0 : if (pInfo != NULL) {
668 : : *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
669 : 0 : RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
670 : : }
671 : : return;
672 : : }
673 : 26830559 : pBuffer = (*ppThis)->buffer;
674 [ + + ]: 413966802 : do
675 : : {
676 : : /* Check ASCII range */
677 : : SAL_WARN_IF( ((unsigned char)*pStr) > 127, "rtl.string",
678 : : "rtl_string2UString_status() - UTF8 test encoding is wrong" );
679 : :
680 : 413966802 : *pBuffer = *pStr;
681 : 413966802 : pBuffer++;
682 : 413966802 : pStr++;
683 : 413966802 : nLen--;
684 : : }
685 : : while ( nLen );
686 [ + + ]: 26830559 : if (pInfo != NULL) {
687 : 17840887 : *pInfo = 0;
688 : : }
689 : : RTL_LOG_STRING_NEW( *ppThis );
690 : : return;
691 : : }
692 : : }
693 : : else
694 : 233576 : nNewLen = nLen;
695 : :
696 : 1075976 : nCvtFlags |= RTL_TEXTTOUNICODE_FLAGS_FLUSH;
697 [ + - ]: 1075976 : hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
698 : :
699 [ + - ]: 1075975 : pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
700 [ - + ]: 1075975 : if (pTemp == NULL) {
701 [ # # ]: 0 : if (pInfo != NULL) {
702 : : *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
703 : 0 : RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
704 : : }
705 : : return;
706 : : }
707 : : nDestChars = rtl_convertTextToUnicode( hConverter, 0,
708 : : pStr, nLen,
709 : : pTemp->buffer, nNewLen,
710 : : nCvtFlags,
711 [ + - ]: 1075975 : &nInfo, &nSrcBytes );
712 : :
713 : : /* Buffer not big enough, try again with enough space */
714 : : /* Shouldn't be the case, but if we get textencoding which
715 : : could results in more unicode characters we have this
716 : : code here. Could be the case for apple encodings */
717 [ + + ]: 1076255 : while ( nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL )
718 : : {
719 : 280 : rtl_freeMemory( pTemp );
720 : 280 : nNewLen += 8;
721 [ + - ]: 280 : pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
722 [ - + ]: 280 : if (pTemp == NULL) {
723 [ # # ]: 0 : if (pInfo != NULL) {
724 : : *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR |
725 : 0 : RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
726 : : }
727 : : return;
728 : : }
729 : : nDestChars = rtl_convertTextToUnicode( hConverter, 0,
730 : : pStr, nLen,
731 : : pTemp->buffer, nNewLen,
732 : : nCvtFlags,
733 [ + - ]: 280 : &nInfo, &nSrcBytes );
734 : : }
735 : :
736 [ + + ]: 1075975 : if (pInfo)
737 : 203089 : *pInfo = nInfo;
738 : :
739 : : /* Set the buffer to the correct size or if there is too
740 : : much overhead, reallocate to the correct size */
741 [ - + ]: 1075975 : if ( nNewLen > nDestChars+8 )
742 : : {
743 [ # # ]: 0 : pTemp2 = IMPL_RTL_STRINGNAME( ImplAlloc )( nDestChars );
744 : : }
745 [ - + ]: 1075975 : if (pTemp2 != NULL)
746 : : {
747 [ # # ]: 0 : rtl_str_ImplCopy(pTemp2->buffer, pTemp->buffer, nDestChars);
748 : 0 : rtl_freeMemory(pTemp);
749 : 0 : pTemp = pTemp2;
750 : : }
751 : : else
752 : : {
753 : 1075975 : pTemp->length = nDestChars;
754 : 1075975 : pTemp->buffer[nDestChars] = 0;
755 : : }
756 : :
757 [ + - ]: 1075975 : rtl_destroyTextToUnicodeConverter( hConverter );
758 : 1075975 : *ppThis = pTemp;
759 : :
760 : : /* Results the conversion in an empty buffer -
761 : : create an empty string */
762 [ + - ][ + + ]: 1075975 : if ( pTemp && !nDestChars )
763 : 47773076 : rtl_uString_new( ppThis );
764 : : }
765 : : }
766 : : RTL_LOG_STRING_NEW( *ppThis );
767 : : }
768 : :
769 : 28558180 : void SAL_CALL rtl_string2UString( rtl_uString** ppThis,
770 : : const sal_Char* pStr,
771 : : sal_Int32 nLen,
772 : : rtl_TextEncoding eTextEncoding,
773 : : sal_uInt32 nCvtFlags ) SAL_THROW_EXTERN_C()
774 : : {
775 : : rtl_string2UString_status( ppThis, pStr, nLen, eTextEncoding,
776 : 28558180 : nCvtFlags, NULL );
777 : 28558187 : }
778 : :
779 : : /* ----------------------------------------------------------------------- */
780 : :
781 : : enum StrLifecycle {
782 : : CANNOT_RETURN,
783 : : CAN_RETURN = 1
784 : : };
785 : :
786 : : static oslMutex
787 : 740019 : getInternMutex()
788 : : {
789 : : static oslMutex pPoolGuard = NULL;
790 [ + + ]: 740019 : if( !pPoolGuard )
791 : : {
792 : : oslMutex pGlobalGuard;
793 : 271 : pGlobalGuard = *osl_getGlobalMutex();
794 : 271 : osl_acquireMutex( pGlobalGuard );
795 [ + - ]: 271 : if( !pPoolGuard )
796 : : {
797 : 271 : oslMutex p = osl_createMutex();
798 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
799 : 271 : pPoolGuard = p;
800 : : }
801 : 271 : osl_releaseMutex( pGlobalGuard );
802 : : }
803 : : else
804 : : {
805 : : OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
806 : : }
807 : :
808 : 740019 : return pPoolGuard;
809 : : }
810 : :
811 : : /* returns true if we found a dup in the pool */
812 : 407324 : static void rtl_ustring_intern_internal( rtl_uString ** newStr,
813 : : rtl_uString * str,
814 : : StrLifecycle can_return )
815 : : {
816 : : oslMutex pPoolMutex;
817 : :
818 : 407324 : pPoolMutex = getInternMutex();
819 : :
820 : 407324 : osl_acquireMutex( pPoolMutex );
821 : :
822 : 407324 : *newStr = rtl_str_hash_intern (str, can_return);
823 : :
824 : 407324 : osl_releaseMutex( pPoolMutex );
825 : :
826 [ + + ][ + + ]: 407324 : if( can_return && *newStr != str )
827 : : { /* we dupped, then found a match */
828 : 47007 : rtl_freeMemory( str );
829 : : }
830 : 407324 : }
831 : :
832 : 53050 : void SAL_CALL rtl_uString_intern( rtl_uString ** newStr,
833 : : rtl_uString * str) SAL_THROW_EXTERN_C()
834 : : {
835 [ + + ]: 53050 : if (SAL_STRING_IS_INTERN(str))
836 : : {
837 [ + - ]: 1082 : IMPL_RTL_AQUIRE( str );
838 : 1082 : *newStr = str;
839 : : }
840 : : else
841 : : {
842 : 51968 : rtl_uString *pOrg = *newStr;
843 : 51968 : *newStr = NULL;
844 : 51968 : rtl_ustring_intern_internal( newStr, str, CANNOT_RETURN );
845 [ - + ]: 51968 : if (pOrg)
846 : 0 : rtl_uString_release (pOrg);
847 : : }
848 : 53050 : }
849 : :
850 : 332948 : static int rtl_canGuessUOutputLength( int len, rtl_TextEncoding eTextEncoding )
851 : : {
852 : : // FIXME: Maybe we should use a bit flag in the higher bits of the
853 : : // eTextEncoding value itself to determine the encoding type. But if we
854 : : // do, be sure to mask the value in certain places that expect the values
855 : : // to be numbered serially from 0 and up. One such place is
856 : : // Impl_getTextEncodingData().
857 : :
858 [ - + ]: 332948 : switch ( eTextEncoding )
859 : : {
860 : : // 1 to 1 (with no zero elements)
861 : : case RTL_TEXTENCODING_IBM_437:
862 : : case RTL_TEXTENCODING_IBM_850:
863 : : case RTL_TEXTENCODING_IBM_860:
864 : : case RTL_TEXTENCODING_IBM_861:
865 : : case RTL_TEXTENCODING_IBM_863:
866 : : case RTL_TEXTENCODING_IBM_865:
867 : 0 : return len;
868 : : break;
869 : : }
870 : 332948 : return 0;
871 : : }
872 : :
873 : 355356 : void SAL_CALL rtl_uString_internConvert( rtl_uString ** newStr,
874 : : const sal_Char * str,
875 : : sal_Int32 len,
876 : : rtl_TextEncoding eTextEncoding,
877 : : sal_uInt32 convertFlags,
878 : : sal_uInt32 * pInfo )
879 : : SAL_THROW_EXTERN_C()
880 : : {
881 : : rtl_uString *scratch;
882 : :
883 [ - + ]: 355356 : if (*newStr)
884 : : {
885 : 0 : rtl_uString_release (*newStr);
886 : 0 : *newStr = NULL;
887 : : }
888 : :
889 [ + - ]: 355356 : if ( len < 256 )
890 : : { // try various optimisations
891 : : sal_Int32 ulen;
892 [ - + ]: 355356 : if ( len < 0 )
893 : 0 : len = strlen( str );
894 [ + + ]: 355356 : if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US )
895 : : {
896 : : int i;
897 : : rtl_uString *pScratch;
898 : : pScratch = static_cast< rtl_uString * >(
899 : 22408 : alloca(sizeof (rtl_uString) + len * sizeof (IMPL_RTL_STRCODE)));
900 [ + + ]: 512220 : for (i = 0; i < len; i++)
901 : : {
902 : : /* Check ASCII range */
903 : : SAL_WARN_IF( ((unsigned char)str[i]) > 127, "rtl.string",
904 : : "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" );
905 : 489812 : pScratch->buffer[i] = str[i];
906 : : }
907 : 22408 : pScratch->length = len;
908 [ + - ]: 22408 : rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
909 : : return;
910 : : }
911 [ - + ]: 332948 : else if ( (ulen = rtl_canGuessUOutputLength(len, eTextEncoding)) != 0 )
912 : : {
913 : : rtl_uString *pScratch;
914 : : rtl_TextToUnicodeConverter hConverter;
915 : : sal_Size nSrcBytes;
916 : : sal_uInt32 nInfo;
917 : :
918 : : pScratch = static_cast< rtl_uString * >(
919 : 0 : alloca(
920 : 0 : sizeof (rtl_uString) + ulen * sizeof (IMPL_RTL_STRCODE)));
921 : :
922 [ # # ]: 0 : hConverter = rtl_createTextToUnicodeConverter( eTextEncoding );
923 : : rtl_convertTextToUnicode(
924 [ # # ]: 0 : hConverter, 0, str, len, pScratch->buffer, ulen, convertFlags, &nInfo, &nSrcBytes );
925 [ # # ]: 0 : rtl_destroyTextToUnicodeConverter( hConverter );
926 : :
927 [ # # ]: 0 : if (pInfo)
928 : 0 : *pInfo = nInfo;
929 : :
930 : 0 : pScratch->length = ulen;
931 [ # # ]: 0 : rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN );
932 : : return;
933 : : }
934 : :
935 : : /* FIXME: we want a nice UTF-8 / alloca shortcut here */
936 : : }
937 : :
938 : 332948 : scratch = NULL;
939 : : rtl_string2UString_status( &scratch, str, len, eTextEncoding, convertFlags,
940 [ + - ]: 332948 : pInfo );
941 [ + - ]: 332948 : if (!scratch) {
942 : : return;
943 : : }
944 [ + - ]: 355356 : rtl_ustring_intern_internal( newStr, scratch, CAN_RETURN );
945 : : }
946 : :
947 : : static void
948 : 6968549 : internRelease (rtl_uString *pThis)
949 : : {
950 : : oslMutex pPoolMutex;
951 : :
952 : 6968549 : rtl_uString *pFree = NULL;
953 [ + + ]: 6968549 : if ( SAL_STRING_REFCOUNT(
954 : : osl_decrementInterlockedCount( &(pThis->refCount) ) ) == 0)
955 : : {
956 : 332695 : pPoolMutex = getInternMutex();
957 : 332695 : osl_acquireMutex( pPoolMutex );
958 : :
959 : 332695 : rtl_str_hash_remove (pThis);
960 : :
961 : : /* May have been separately acquired */
962 [ + - ]: 332695 : if ( SAL_STRING_REFCOUNT(
963 : : osl_incrementInterlockedCount( &(pThis->refCount) ) ) == 1 )
964 : : {
965 : : /* we got the last ref */
966 : 332695 : pFree = pThis;
967 : : }
968 : : else /* very unusual */
969 : : {
970 : 0 : internRelease (pThis);
971 : : }
972 : :
973 : 332695 : osl_releaseMutex( pPoolMutex );
974 : : }
975 [ + + ]: 6968549 : if (pFree)
976 : 332695 : rtl_freeMemory (pFree);
977 : 6968549 : }
978 : :
979 : 24047524 : sal_uInt32 SAL_CALL rtl_uString_iterateCodePoints(
980 : : rtl_uString const * string, sal_Int32 * indexUtf16,
981 : : sal_Int32 incrementCodePoints)
982 : : {
983 : : sal_Int32 n;
984 : : sal_Unicode cu;
985 : : sal_uInt32 cp;
986 : : OSL_ASSERT(string != NULL && indexUtf16 != NULL);
987 : 24047524 : n = *indexUtf16;
988 : : OSL_ASSERT(n >= 0 && n <= string->length);
989 [ + + ]: 24418626 : while (incrementCodePoints < 0) {
990 : : OSL_ASSERT(n > 0);
991 : 371102 : cu = string->buffer[--n];
992 [ + + ][ - + ]: 371102 : if (SAL_RTL_IS_LOW_SURROGATE(cu) && n != 0 &&
[ # # ][ # # ]
[ # # ]
993 : 0 : SAL_RTL_IS_HIGH_SURROGATE(string->buffer[n - 1]))
994 : : {
995 : 0 : --n;
996 : : }
997 : 371102 : ++incrementCodePoints;
998 : : }
999 : : OSL_ASSERT(n >= 0 && n < string->length);
1000 : 24047524 : cu = string->buffer[n];
1001 [ + + ][ + + ]: 24047524 : if (SAL_RTL_IS_HIGH_SURROGATE(cu) && string->length - n >= 2 &&
[ + - ][ + - ]
[ + - ]
1002 : 20 : SAL_RTL_IS_LOW_SURROGATE(string->buffer[n + 1]))
1003 : : {
1004 : 10 : cp = SAL_RTL_COMBINE_SURROGATES(cu, string->buffer[n + 1]);
1005 : : } else {
1006 : 24047514 : cp = cu;
1007 : : }
1008 [ + + ]: 35417119 : while (incrementCodePoints > 0) {
1009 : : OSL_ASSERT(n < string->length);
1010 : 11369595 : cu = string->buffer[n++];
1011 [ + + ][ + + ]: 11369595 : if (SAL_RTL_IS_HIGH_SURROGATE(cu) && n != string->length &&
[ + - ][ + - ]
[ + - ]
1012 : 20 : SAL_RTL_IS_LOW_SURROGATE(string->buffer[n]))
1013 : : {
1014 : 10 : ++n;
1015 : : }
1016 : 11369595 : --incrementCodePoints;
1017 : : }
1018 : : OSL_ASSERT(n >= 0 && n <= string->length);
1019 : 24047524 : *indexUtf16 = n;
1020 : 24047524 : return cp;
1021 : : }
1022 : :
1023 : 18881940 : sal_Bool rtl_convertStringToUString(
1024 : : rtl_uString ** target, char const * source, sal_Int32 length,
1025 : : rtl_TextEncoding encoding, sal_uInt32 flags) SAL_THROW_EXTERN_C()
1026 : : {
1027 : : sal_uInt32 info;
1028 [ + - ]: 18881940 : rtl_string2UString_status(target, source, length, encoding, flags, &info);
1029 : 18881940 : return (sal_Bool) ((info & RTL_TEXTTOUNICODE_INFO_ERROR) == 0);
1030 : : }
1031 : :
1032 : 216421 : void rtl_uString_newReplaceFirst(
1033 : : rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
1034 : : rtl_uString const * to, sal_Int32 * index) SAL_THROW_EXTERN_C()
1035 : : {
1036 : : assert(str != 0);
1037 : : assert(index != 0);
1038 : : assert(*index >= 0 && *index <= str->length);
1039 : : assert(from != 0);
1040 : : assert(to != 0);
1041 : : sal_Int32 i = rtl_ustr_indexOfStr_WithLength(
1042 : 216421 : str->buffer + *index, str->length - *index, from->buffer, from->length);
1043 [ + + ]: 216421 : if (i == -1) {
1044 : 194862 : rtl_uString_assign(newStr, str);
1045 : : } else {
1046 : : assert(i <= str->length - *index);
1047 : 21559 : i += *index;
1048 : : assert(from->length <= str->length);
1049 [ - + ]: 21559 : if (str->length - from->length > SAL_MAX_INT32 - to->length) {
1050 : 0 : std::abort();
1051 : : }
1052 : 21559 : sal_Int32 n = str->length - from->length + to->length;
1053 : 21559 : rtl_uString_acquire(str); // in case *newStr == str
1054 : 21559 : rtl_uString_new_WithLength(newStr, n);
1055 [ + + ]: 21559 : if (n != 0) {
1056 : 2686 : (*newStr)->length = n;
1057 : : assert(i >= 0 && i < str->length);
1058 : : memcpy(
1059 : 2686 : (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1060 : : memcpy(
1061 : 2686 : (*newStr)->buffer + i, to->buffer,
1062 : 5372 : to->length * sizeof (sal_Unicode));
1063 : : memcpy(
1064 : 2686 : (*newStr)->buffer + i + to->length,
1065 : 2686 : str->buffer + i + from->length,
1066 : 2686 : (str->length - i - from->length) * sizeof (sal_Unicode));
1067 : : }
1068 : 21559 : rtl_uString_release(str);
1069 : : }
1070 : 216421 : *index = i;
1071 : 216421 : }
1072 : :
1073 : 41907 : void rtl_uString_newReplaceFirstAsciiL(
1074 : : rtl_uString ** newStr, rtl_uString * str, char const * from,
1075 : : sal_Int32 fromLength, rtl_uString const * to, sal_Int32 * index)
1076 : : SAL_THROW_EXTERN_C()
1077 : : {
1078 : : assert(str != 0);
1079 : : assert(index != 0);
1080 : : assert(*index >= 0 && *index <= str->length);
1081 : : assert(fromLength >= 0);
1082 : : assert(to != 0);
1083 : : sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
1084 : 41907 : str->buffer + *index, str->length - *index, from, fromLength);
1085 [ + + ]: 41907 : if (i == -1) {
1086 : 24701 : rtl_uString_assign(newStr, str);
1087 : : } else {
1088 : : assert(i <= str->length - *index);
1089 : 17206 : i += *index;
1090 : : assert(fromLength <= str->length);
1091 [ - + ]: 17206 : if (str->length - fromLength > SAL_MAX_INT32 - to->length) {
1092 : 0 : std::abort();
1093 : : }
1094 : 17206 : sal_Int32 n = str->length - fromLength + to->length;
1095 : 17206 : rtl_uString_acquire(str); // in case *newStr == str
1096 [ + - ]: 17206 : if (n != 0) {
1097 : 17206 : rtl_uString_new_WithLength(newStr, n);
1098 : 17206 : (*newStr)->length = n;
1099 : : assert(i >= 0 && i < str->length);
1100 : : memcpy(
1101 : 17206 : (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1102 : : memcpy(
1103 : 17206 : (*newStr)->buffer + i, to->buffer,
1104 : 34412 : to->length * sizeof (sal_Unicode));
1105 : : memcpy(
1106 : 17206 : (*newStr)->buffer + i + to->length,
1107 : 17206 : str->buffer + i + fromLength,
1108 : 17206 : (str->length - i - fromLength) * sizeof (sal_Unicode));
1109 : : }
1110 : 17206 : rtl_uString_release(str);
1111 : : }
1112 : 41907 : *index = i;
1113 : 41907 : }
1114 : :
1115 : 14257 : void rtl_uString_newReplaceFirstAsciiLAsciiL(
1116 : : rtl_uString ** newStr, rtl_uString * str, char const * from,
1117 : : sal_Int32 fromLength, char const * to, sal_Int32 toLength,
1118 : : sal_Int32 * index) SAL_THROW_EXTERN_C()
1119 : : {
1120 : : assert(str != 0);
1121 : : assert(index != 0);
1122 : : assert(*index >= 0 && *index <= str->length);
1123 : : assert(fromLength >= 0);
1124 : : assert(to != 0);
1125 : : assert(toLength >= 0);
1126 : : sal_Int32 i = rtl_ustr_indexOfAscii_WithLength(
1127 : 14257 : str->buffer + *index, str->length - *index, from, fromLength);
1128 [ + + ]: 14257 : if (i == -1) {
1129 : 11975 : rtl_uString_assign(newStr, str);
1130 : : } else {
1131 : : assert(i <= str->length - *index);
1132 : 2282 : i += *index;
1133 : : assert(fromLength <= str->length);
1134 [ - + ]: 2282 : if (str->length - fromLength > SAL_MAX_INT32 - toLength) {
1135 : 0 : std::abort();
1136 : : }
1137 : 2282 : sal_Int32 n = str->length - fromLength + toLength;
1138 : 2282 : rtl_uString_acquire(str); // in case *newStr == str
1139 [ + - ]: 2282 : if (n != 0) {
1140 : 2282 : rtl_uString_new_WithLength(newStr, n);
1141 : 2282 : (*newStr)->length = n;
1142 : : assert(i >= 0 && i < str->length);
1143 : : memcpy(
1144 : 2282 : (*newStr)->buffer, str->buffer, i * sizeof (sal_Unicode));
1145 [ + + ]: 2861 : for (sal_Int32 j = 0; j != toLength; ++j) {
1146 : : assert(static_cast< unsigned char >(to[j]) <= 0x7F);
1147 : 579 : (*newStr)->buffer[i + j] = to[j];
1148 : : }
1149 : : memcpy(
1150 : 2282 : (*newStr)->buffer + i + toLength,
1151 : 2282 : str->buffer + i + fromLength,
1152 : 2282 : (str->length - i - fromLength) * sizeof (sal_Unicode));
1153 : : }
1154 : 2282 : rtl_uString_release(str);
1155 : : }
1156 : 14257 : *index = i;
1157 : 14257 : }
1158 : :
1159 : 194852 : void rtl_uString_newReplaceAll(
1160 : : rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
1161 : : rtl_uString const * to) SAL_THROW_EXTERN_C()
1162 : : {
1163 : : assert(to != 0);
1164 : 194852 : rtl_uString_assign(newStr, str);
1165 : 216396 : for (sal_Int32 i = 0;; i += to->length) {
1166 : 216396 : rtl_uString_newReplaceFirst(newStr, *newStr, from, to, &i);
1167 [ + + ]: 216396 : if (i == -1) {
1168 : 194852 : break;
1169 : : }
1170 : : }
1171 : 194852 : }
1172 : :
1173 : 24691 : void rtl_uString_newReplaceAllAsciiL(
1174 : : rtl_uString ** newStr, rtl_uString * str, char const * from,
1175 : : sal_Int32 fromLength, rtl_uString const * to) SAL_THROW_EXTERN_C()
1176 : : {
1177 : : assert(to != 0);
1178 : 24691 : rtl_uString_assign(newStr, str);
1179 : 41877 : for (sal_Int32 i = 0;; i += to->length) {
1180 : : rtl_uString_newReplaceFirstAsciiL(
1181 : 41877 : newStr, *newStr, from, fromLength, to, &i);
1182 [ + + ]: 41877 : if (i == -1) {
1183 : 24691 : break;
1184 : : }
1185 : : }
1186 : 24691 : }
1187 : :
1188 : 11965 : void rtl_uString_newReplaceAllAsciiLAsciiL(
1189 : : rtl_uString ** newStr, rtl_uString * str, char const * from,
1190 : : sal_Int32 fromLength, char const * to, sal_Int32 toLength)
1191 : : SAL_THROW_EXTERN_C()
1192 : : {
1193 : : assert(toLength >= 0);
1194 : 11965 : rtl_uString_assign(newStr, str);
1195 : 14227 : for (sal_Int32 i = 0;; i += toLength) {
1196 : : rtl_uString_newReplaceFirstAsciiLAsciiL(
1197 : 14227 : newStr, *newStr, from, fromLength, to, toLength, &i);
1198 [ + + ]: 14227 : if (i == -1) {
1199 : 11965 : break;
1200 : : }
1201 : : }
1202 : 11965 : }
1203 : :
1204 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|