1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 /* ======================================================================= */
25 /* Internal C-String help functions which could be used without the */
26 /* String-Class */
27 /* ======================================================================= */
28
29 /*
30 inline void rtl_str_ImplCopy( IMPL_RTL_STRCODE* pDest,
31 const IMPL_RTL_STRCODE* pSrc,
32 sal_Int32 nCount )
33 {
34 while ( nCount > 0 )
35 {
36 *pDest = *pSrc;
37 pDest++;
38 pSrc++;
39 nCount--;
40 }
41 }
42 */
43
44 #define rtl_str_ImplCopy( _pDest, _pSrc, _nCount ) \
45 { \
46 IMPL_RTL_STRCODE* __mm_pDest = _pDest; \
47 const IMPL_RTL_STRCODE* __mm_pSrc = _pSrc; \
48 sal_Int32 __mm_nCount = _nCount; \
49 while ( __mm_nCount > 0 ) \
50 { \
51 *__mm_pDest = *__mm_pSrc; \
52 __mm_pDest++; \
53 __mm_pSrc++; \
54 __mm_nCount--; \
55 } \
56 }
57
58 /* ======================================================================= */
59 /* NULL-pointer guards */
60 /* */
61 /* The C-string functions below document (see rtl/string.h, rtl/ustring.h) */
62 /* that their string arguments must be non-NULL, null-terminated strings. */
63 /* Passing NULL is a caller error. In non-product builds (OSL_DEBUG_LEVEL */
64 /* > 0) we diagnose it loudly via OSL_PRECOND and then fall back to defined */
65 /* behaviour so the diagnostic build never dereferences a NULL pointer. */
66 /* */
67 /* In product builds the guards compile away entirely: callers must honour */
68 /* the documented non-NULL contract, and we add zero release-build cost */
69 /* (not even a pointer test) to these hot string primitives. */
70 /* */
71 /* Even in debug, the guards run exactly once, at function entry: they are */
72 /* OUTSIDE the per-character processing loops, so they do not change */
73 /* string-processing throughput. */
74 /* ======================================================================= */
75
76 #define IMPL_RTL_STR_GUARD_MSG \
77 "rtl string function: NULL pointer passed; the documented contract " \
78 "requires a non-NULL, null-terminated string"
79
80 #if OSL_DEBUG_LEVEL > 0
81
82 /* Read-only argument: treat a NULL pointer as the empty string. */
83 static const IMPL_RTL_STRCODE aImplGuardEmptyStr = 0;
84 #define IMPL_RTL_STR_NULL_AS_EMPTY( pStr ) \
85 do { \
86 OSL_PRECOND( (pStr) != NULL, IMPL_RTL_STR_GUARD_MSG ); \
87 if ( !(pStr) ) \
88 (pStr) = &aImplGuardEmptyStr; \
89 } while (0)
90
91 /* Argument that cannot be substituted (returns a value): bail out early. */
92 #define IMPL_RTL_STR_NULL_RETURN( pStr, _ret ) \
93 do { \
94 OSL_PRECOND( (pStr) != NULL, IMPL_RTL_STR_GUARD_MSG ); \
95 if ( !(pStr) ) \
96 return _ret; \
97 } while (0)
98
99 /* Same, for functions returning void. */
100 #define IMPL_RTL_STR_NULL_RETURN_VOID( pStr ) \
101 do { \
102 OSL_PRECOND( (pStr) != NULL, IMPL_RTL_STR_GUARD_MSG ); \
103 if ( !(pStr) ) \
104 return; \
105 } while (0)
106
107 #else /* product build: guards compile away, callers must honour contract */
108
109 #define IMPL_RTL_STR_NULL_AS_EMPTY( pStr ) ((void)0)
110 #define IMPL_RTL_STR_NULL_RETURN( pStr, _ret ) ((void)0)
111 #define IMPL_RTL_STR_NULL_RETURN_VOID( pStr ) ((void)0)
112
113 #endif
114
115 /* ======================================================================= */
116 /* C-String functions which could be used without the String-Class */
117 /* ======================================================================= */
118
getLength(const IMPL_RTL_STRCODE * pStr)119 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( getLength )( const IMPL_RTL_STRCODE* pStr )
120 {
121 const IMPL_RTL_STRCODE* pTempStr = pStr;
122 /* A NULL string has length 0. Guarding getLength here also protects
123 hashCode, lastIndexOfChar, indexOfStr, lastIndexOfStr and trim, which
124 all start by calling getLength and then a length-bounded helper. */
125 IMPL_RTL_STR_NULL_RETURN( pStr, 0 );
126 while( *pTempStr )
127 pTempStr++;
128 return pTempStr-pStr;
129 }
130
131 /* ----------------------------------------------------------------------- */
132
compare(const IMPL_RTL_STRCODE * pStr1,const IMPL_RTL_STRCODE * pStr2)133 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare )( const IMPL_RTL_STRCODE* pStr1,
134 const IMPL_RTL_STRCODE* pStr2 )
135 {
136 sal_Int32 nRet;
137 /* A NULL argument is treated as the empty string; the loop below then
138 yields the correct ordering (empty < any non-empty string). */
139 IMPL_RTL_STR_NULL_AS_EMPTY( pStr1 );
140 IMPL_RTL_STR_NULL_AS_EMPTY( pStr2 );
141 while ( ((nRet = ((sal_Int32)(IMPL_RTL_USTRCODE(*pStr1)))-
142 ((sal_Int32)(IMPL_RTL_USTRCODE(*pStr2)))) == 0) &&
143 *pStr2 )
144 {
145 pStr1++;
146 pStr2++;
147 }
148
149 return nRet;
150 }
151
152 /* ----------------------------------------------------------------------- */
153
compare_WithLength(const IMPL_RTL_STRCODE * pStr1,sal_Int32 nStr1Len,const IMPL_RTL_STRCODE * pStr2,sal_Int32 nStr2Len)154 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
155 sal_Int32 nStr1Len,
156 const IMPL_RTL_STRCODE* pStr2,
157 sal_Int32 nStr2Len )
158 {
159 sal_Int32 nRet = nStr1Len - nStr2Len;
160 int nCount = (nRet <= 0) ? nStr1Len : nStr2Len;
161
162 --pStr1;
163 --pStr2;
164 while( (--nCount >= 0) && (*++pStr1 == *++pStr2) );
165
166 if( nCount >= 0 )
167 nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 )))
168 - ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 )));
169
170 return nRet;
171 }
172
173 /* ----------------------------------------------------------------------- */
174
shortenedCompare_WithLength(const IMPL_RTL_STRCODE * pStr1,sal_Int32 nStr1Len,const IMPL_RTL_STRCODE * pStr2,sal_Int32 nStr2Len,sal_Int32 nShortenedLength)175 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
176 sal_Int32 nStr1Len,
177 const IMPL_RTL_STRCODE* pStr2,
178 sal_Int32 nStr2Len,
179 sal_Int32 nShortenedLength )
180 {
181 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
182 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
183 sal_Int32 nRet;
184 while ( (nShortenedLength > 0) &&
185 (pStr1 < pStr1End) && (pStr2 < pStr2End) )
186 {
187 nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 )))-
188 ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 )));
189 if ( nRet )
190 return nRet;
191
192 nShortenedLength--;
193 pStr1++;
194 pStr2++;
195 }
196
197 if ( nShortenedLength <= 0 )
198 return 0;
199 return nStr1Len - nStr2Len;
200 }
201
202 /* ----------------------------------------------------------------------- */
203
reverseCompare_WithLength(const IMPL_RTL_STRCODE * pStr1,sal_Int32 nStr1Len,const IMPL_RTL_STRCODE * pStr2,sal_Int32 nStr2Len)204 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( reverseCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
205 sal_Int32 nStr1Len,
206 const IMPL_RTL_STRCODE* pStr2,
207 sal_Int32 nStr2Len )
208 {
209 const IMPL_RTL_STRCODE* pStr1Run = pStr1+nStr1Len;
210 const IMPL_RTL_STRCODE* pStr2Run = pStr2+nStr2Len;
211 sal_Int32 nRet;
212 while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
213 {
214 pStr1Run--;
215 pStr2Run--;
216 nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1Run )))-
217 ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2Run )));
218 if ( nRet )
219 return nRet;
220 }
221
222 return nStr1Len - nStr2Len;
223 }
224
225 /* ----------------------------------------------------------------------- */
226
compareIgnoreAsciiCase(const IMPL_RTL_STRCODE * pStr1,const IMPL_RTL_STRCODE * pStr2)227 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase )( const IMPL_RTL_STRCODE* pStr1,
228 const IMPL_RTL_STRCODE* pStr2 )
229 {
230 sal_Int32 nRet;
231 sal_Int32 c1;
232 sal_Int32 c2;
233 /* A NULL argument is treated as the empty string. */
234 IMPL_RTL_STR_NULL_AS_EMPTY( pStr1 );
235 IMPL_RTL_STR_NULL_AS_EMPTY( pStr2 );
236 do
237 {
238 /* If character between 'A' and 'Z', than convert it to lowercase */
239 c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 );
240 c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 );
241 if ( (c1 >= 65) && (c1 <= 90) )
242 c1 += 32;
243 if ( (c2 >= 65) && (c2 <= 90) )
244 c2 += 32;
245 nRet = c1-c2;
246 if ( nRet != 0 )
247 return nRet;
248
249 pStr1++;
250 pStr2++;
251 }
252 while ( c2 );
253
254 return 0;
255 }
256
257 /* ----------------------------------------------------------------------- */
258
compareIgnoreAsciiCase_WithLength(const IMPL_RTL_STRCODE * pStr1,sal_Int32 nStr1Len,const IMPL_RTL_STRCODE * pStr2,sal_Int32 nStr2Len)259 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
260 sal_Int32 nStr1Len,
261 const IMPL_RTL_STRCODE* pStr2,
262 sal_Int32 nStr2Len )
263 {
264 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
265 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
266 sal_Int32 nRet;
267 sal_Int32 c1;
268 sal_Int32 c2;
269 while ( (pStr1 < pStr1End) && (pStr2 < pStr2End) )
270 {
271 /* If character between 'A' and 'Z', than convert it to lowercase */
272 c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 );
273 c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 );
274 if ( (c1 >= 65) && (c1 <= 90) )
275 c1 += 32;
276 if ( (c2 >= 65) && (c2 <= 90) )
277 c2 += 32;
278 nRet = c1-c2;
279 if ( nRet != 0 )
280 return nRet;
281
282 pStr1++;
283 pStr2++;
284 }
285
286 return nStr1Len - nStr2Len;
287 }
288
289 /* ----------------------------------------------------------------------- */
290
shortenedCompareIgnoreAsciiCase_WithLength(const IMPL_RTL_STRCODE * pStr1,sal_Int32 nStr1Len,const IMPL_RTL_STRCODE * pStr2,sal_Int32 nStr2Len,sal_Int32 nShortenedLength)291 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
292 sal_Int32 nStr1Len,
293 const IMPL_RTL_STRCODE* pStr2,
294 sal_Int32 nStr2Len,
295 sal_Int32 nShortenedLength )
296 {
297 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
298 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
299 sal_Int32 nRet;
300 sal_Int32 c1;
301 sal_Int32 c2;
302 while ( (nShortenedLength > 0) &&
303 (pStr1 < pStr1End) && (pStr2 < pStr2End) )
304 {
305 /* If character between 'A' and 'Z', than convert it to lowercase */
306 c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 );
307 c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 );
308 if ( (c1 >= 65) && (c1 <= 90) )
309 c1 += 32;
310 if ( (c2 >= 65) && (c2 <= 90) )
311 c2 += 32;
312 nRet = c1-c2;
313 if ( nRet != 0 )
314 return nRet;
315
316 nShortenedLength--;
317 pStr1++;
318 pStr2++;
319 }
320
321 if ( nShortenedLength <= 0 )
322 return 0;
323 return nStr1Len - nStr2Len;
324 }
325
326 /* ----------------------------------------------------------------------- */
327
hashCode(const IMPL_RTL_STRCODE * pStr)328 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode )( const IMPL_RTL_STRCODE* pStr )
329 {
330 return IMPL_RTL_STRNAME( hashCode_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
331 }
332
333 /* ----------------------------------------------------------------------- */
334
hashCode_WithLength(const IMPL_RTL_STRCODE * pStr,sal_Int32 nLen)335 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode_WithLength )( const IMPL_RTL_STRCODE* pStr,
336 sal_Int32 nLen )
337 {
338 sal_Int32 h = nLen;
339
340 if ( nLen < 256 )
341 {
342 while ( nLen > 0 )
343 {
344 h = (h*37) + IMPL_RTL_USTRCODE( *pStr );
345 pStr++;
346 nLen--;
347 }
348 }
349 else
350 {
351 sal_Int32 nSkip;
352 const IMPL_RTL_STRCODE* pEndStr = pStr+nLen-5;
353
354 /* only sample some characters */
355 /* the first 3, some characters between, and the last 5 */
356 h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
357 pStr++;
358 h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
359 pStr++;
360 h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
361 pStr++;
362
363 if ( nLen < 32 )
364 nSkip = nLen / 4;
365 else
366 nSkip = nLen / 8;
367 nLen -= 8;
368 while ( nLen > 0 )
369 {
370 h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
371 pStr += nSkip;
372 nLen -= nSkip;
373 }
374
375 h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
376 pEndStr++;
377 h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
378 pEndStr++;
379 h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
380 pEndStr++;
381 h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
382 pEndStr++;
383 h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
384 }
385
386 return h;
387 }
388
389 /* ----------------------------------------------------------------------- */
390
indexOfChar(const IMPL_RTL_STRCODE * pStr,IMPL_RTL_STRCODE c)391 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar )( const IMPL_RTL_STRCODE* pStr,
392 IMPL_RTL_STRCODE c )
393 {
394 const IMPL_RTL_STRCODE* pTempStr = pStr;
395 /* Nothing can be found in a NULL (empty) string. */
396 IMPL_RTL_STR_NULL_RETURN( pStr, -1 );
397 while ( *pTempStr )
398 {
399 if ( *pTempStr == c )
400 return pTempStr-pStr;
401
402 pTempStr++;
403 }
404
405 return -1;
406 }
407
408 /* ----------------------------------------------------------------------- */
409
indexOfChar_WithLength(const IMPL_RTL_STRCODE * pStr,sal_Int32 nLen,IMPL_RTL_STRCODE c)410 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
411 sal_Int32 nLen,
412 IMPL_RTL_STRCODE c )
413 {
414 const IMPL_RTL_STRCODE* pTempStr = pStr;
415 while ( nLen > 0 )
416 {
417 if ( *pTempStr == c )
418 return pTempStr-pStr;
419
420 pTempStr++;
421 nLen--;
422 }
423
424 return -1;
425 }
426
427 /* ----------------------------------------------------------------------- */
428
lastIndexOfChar(const IMPL_RTL_STRCODE * pStr,IMPL_RTL_STRCODE c)429 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar )( const IMPL_RTL_STRCODE* pStr,
430 IMPL_RTL_STRCODE c )
431 {
432 return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), c );
433 }
434
435 /* ----------------------------------------------------------------------- */
436
lastIndexOfChar_WithLength(const IMPL_RTL_STRCODE * pStr,sal_Int32 nLen,IMPL_RTL_STRCODE c)437 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
438 sal_Int32 nLen,
439 IMPL_RTL_STRCODE c )
440 {
441 pStr += nLen;
442 while ( nLen > 0 )
443 {
444 nLen--;
445 pStr--;
446
447 if ( *pStr == c )
448 return nLen;
449 }
450
451 return -1;
452 }
453
454 /* ----------------------------------------------------------------------- */
455
indexOfStr(const IMPL_RTL_STRCODE * pStr,const IMPL_RTL_STRCODE * pSubStr)456 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr )( const IMPL_RTL_STRCODE* pStr,
457 const IMPL_RTL_STRCODE* pSubStr )
458 {
459 return IMPL_RTL_STRNAME( indexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
460 pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
461 }
462
463 /* ----------------------------------------------------------------------- */
464
indexOfStr_WithLength(const IMPL_RTL_STRCODE * pStr,sal_Int32 nStrLen,const IMPL_RTL_STRCODE * pSubStr,sal_Int32 nSubLen)465 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
466 sal_Int32 nStrLen,
467 const IMPL_RTL_STRCODE* pSubStr,
468 sal_Int32 nSubLen )
469 {
470 /* faster search for a single character */
471 if ( nSubLen < 2 )
472 {
473 /* an empty SubString is always not foundable */
474 if ( nSubLen == 1 )
475 {
476 IMPL_RTL_STRCODE c = *pSubStr;
477 const IMPL_RTL_STRCODE* pTempStr = pStr;
478 while ( nStrLen > 0 )
479 {
480 if ( *pTempStr == c )
481 return pTempStr-pStr;
482
483 pTempStr++;
484 nStrLen--;
485 }
486 }
487 }
488 else
489 {
490 const IMPL_RTL_STRCODE* pTempStr = pStr;
491 while ( nStrLen > 0 )
492 {
493 if ( *pTempStr == *pSubStr )
494 {
495 /* Compare SubString */
496 if ( nSubLen <= nStrLen )
497 {
498 const IMPL_RTL_STRCODE* pTempStr1 = pTempStr;
499 const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
500 sal_Int32 nTempLen = nSubLen;
501 while ( nTempLen )
502 {
503 if ( *pTempStr1 != *pTempStr2 )
504 break;
505
506 pTempStr1++;
507 pTempStr2++;
508 nTempLen--;
509 }
510
511 if ( !nTempLen )
512 return pTempStr-pStr;
513 }
514 else
515 break;
516 }
517
518 nStrLen--;
519 pTempStr++;
520 }
521 }
522
523 return -1;
524 }
525
526 /* ----------------------------------------------------------------------- */
527
lastIndexOfStr(const IMPL_RTL_STRCODE * pStr,const IMPL_RTL_STRCODE * pSubStr)528 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr )( const IMPL_RTL_STRCODE* pStr,
529 const IMPL_RTL_STRCODE* pSubStr )
530 {
531 return IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
532 pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
533 }
534
535 /* ----------------------------------------------------------------------- */
536
lastIndexOfStr_WithLength(const IMPL_RTL_STRCODE * pStr,sal_Int32 nStrLen,const IMPL_RTL_STRCODE * pSubStr,sal_Int32 nSubLen)537 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
538 sal_Int32 nStrLen,
539 const IMPL_RTL_STRCODE* pSubStr,
540 sal_Int32 nSubLen )
541 {
542 /* faster search for a single character */
543 if ( nSubLen < 2 )
544 {
545 /* an empty SubString is always not foundable */
546 if ( nSubLen == 1 )
547 {
548 IMPL_RTL_STRCODE c = *pSubStr;
549 pStr += nStrLen;
550 while ( nStrLen > 0 )
551 {
552 nStrLen--;
553 pStr--;
554
555 if ( *pStr == c )
556 return nStrLen;
557 }
558 }
559 }
560 else
561 {
562 pStr += nStrLen;
563 nStrLen -= nSubLen;
564 pStr -= nSubLen;
565 while ( nStrLen >= 0 )
566 {
567 const IMPL_RTL_STRCODE* pTempStr1 = pStr;
568 const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
569 sal_Int32 nTempLen = nSubLen;
570 while ( nTempLen )
571 {
572 if ( *pTempStr1 != *pTempStr2 )
573 break;
574
575 pTempStr1++;
576 pTempStr2++;
577 nTempLen--;
578 }
579
580 if ( !nTempLen )
581 return nStrLen;
582
583 nStrLen--;
584 pStr--;
585 }
586 }
587
588 return -1;
589 }
590
591 /* ----------------------------------------------------------------------- */
592
replaceChar(IMPL_RTL_STRCODE * pStr,IMPL_RTL_STRCODE cOld,IMPL_RTL_STRCODE cNew)593 void SAL_CALL IMPL_RTL_STRNAME( replaceChar )( IMPL_RTL_STRCODE* pStr,
594 IMPL_RTL_STRCODE cOld,
595 IMPL_RTL_STRCODE cNew )
596 {
597 /* Nothing to replace in a NULL (empty) string. */
598 IMPL_RTL_STR_NULL_RETURN_VOID( pStr );
599 while ( *pStr )
600 {
601 if ( *pStr == cOld )
602 *pStr = cNew;
603
604 pStr++;
605 }
606 }
607
608 /* ----------------------------------------------------------------------- */
609
replaceChar_WithLength(IMPL_RTL_STRCODE * pStr,sal_Int32 nLen,IMPL_RTL_STRCODE cOld,IMPL_RTL_STRCODE cNew)610 void SAL_CALL IMPL_RTL_STRNAME( replaceChar_WithLength )( IMPL_RTL_STRCODE* pStr,
611 sal_Int32 nLen,
612 IMPL_RTL_STRCODE cOld,
613 IMPL_RTL_STRCODE cNew )
614 {
615 while ( nLen > 0 )
616 {
617 if ( *pStr == cOld )
618 *pStr = cNew;
619
620 pStr++;
621 nLen--;
622 }
623 }
624
625 /* ----------------------------------------------------------------------- */
626
toAsciiLowerCase(IMPL_RTL_STRCODE * pStr)627 void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase )( IMPL_RTL_STRCODE* pStr )
628 {
629 /* Nothing to convert in a NULL (empty) string. */
630 IMPL_RTL_STR_NULL_RETURN_VOID( pStr );
631 while ( *pStr )
632 {
633 /* Between A-Z (65-90), than to lowercase (+32) */
634 if ( (*pStr >= 65) && (*pStr <= 90) )
635 *pStr += 32;
636
637 pStr++;
638 }
639 }
640
641 /* ----------------------------------------------------------------------- */
642
toAsciiLowerCase_WithLength(IMPL_RTL_STRCODE * pStr,sal_Int32 nLen)643 void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength )( IMPL_RTL_STRCODE* pStr,
644 sal_Int32 nLen )
645 {
646 while ( nLen > 0 )
647 {
648 /* Between A-Z (65-90), than to lowercase (+32) */
649 if ( (*pStr >= 65) && (*pStr <= 90) )
650 *pStr += 32;
651
652 pStr++;
653 nLen--;
654 }
655 }
656
657 /* ----------------------------------------------------------------------- */
658
toAsciiUpperCase(IMPL_RTL_STRCODE * pStr)659 void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase )( IMPL_RTL_STRCODE* pStr )
660 {
661 /* Nothing to convert in a NULL (empty) string. */
662 IMPL_RTL_STR_NULL_RETURN_VOID( pStr );
663 while ( *pStr )
664 {
665 /* Between a-z (97-122), than to uppercase (-32) */
666 if ( (*pStr >= 97) && (*pStr <= 122) )
667 *pStr -= 32;
668
669 pStr++;
670 }
671 }
672
673 /* ----------------------------------------------------------------------- */
674
toAsciiUpperCase_WithLength(IMPL_RTL_STRCODE * pStr,sal_Int32 nLen)675 void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength )( IMPL_RTL_STRCODE* pStr,
676 sal_Int32 nLen )
677 {
678 while ( nLen > 0 )
679 {
680 /* Between a-z (97-122), than to uppercase (-32) */
681 if ( (*pStr >= 97) && (*pStr <= 122) )
682 *pStr -= 32;
683
684 pStr++;
685 nLen--;
686 }
687 }
688
689 /* ----------------------------------------------------------------------- */
690
trim(IMPL_RTL_STRCODE * pStr)691 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim )( IMPL_RTL_STRCODE* pStr )
692 {
693 return IMPL_RTL_STRNAME( trim_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
694 }
695
696 /* ----------------------------------------------------------------------- */
697
trim_WithLength(IMPL_RTL_STRCODE * pStr,sal_Int32 nLen)698 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim_WithLength )( IMPL_RTL_STRCODE* pStr, sal_Int32 nLen )
699 {
700 sal_Int32 nPreSpaces = 0;
701 sal_Int32 nPostSpaces = 0;
702 sal_Int32 nIndex = nLen-1;
703
704 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nPreSpaces)) ) )
705 nPreSpaces++;
706
707 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nIndex)) ) )
708 {
709 nPostSpaces++;
710 nIndex--;
711 }
712
713 if ( nPostSpaces )
714 {
715 nLen -= nPostSpaces;
716 *(pStr+nLen) = 0;
717 }
718
719 if ( nPreSpaces )
720 {
721 IMPL_RTL_STRCODE* pNewStr = pStr+nPreSpaces;
722
723 nLen -= nPreSpaces;
724 nIndex = nLen;
725
726 while ( nIndex )
727 {
728 *pStr = *pNewStr;
729 pStr++;
730 pNewStr++;
731 nIndex--;
732 }
733 *pStr = 0;
734 }
735
736 return nLen;
737 }
738
739 /* ----------------------------------------------------------------------- */
740
valueOfBoolean(IMPL_RTL_STRCODE * pStr,sal_Bool b)741 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfBoolean )( IMPL_RTL_STRCODE* pStr, sal_Bool b )
742 {
743 if ( b )
744 {
745 *pStr = 't';
746 pStr++;
747 *pStr = 'r';
748 pStr++;
749 *pStr = 'u';
750 pStr++;
751 *pStr = 'e';
752 pStr++;
753 *pStr = 0;
754 return 4;
755 }
756 else
757 {
758 *pStr = 'f';
759 pStr++;
760 *pStr = 'a';
761 pStr++;
762 *pStr = 'l';
763 pStr++;
764 *pStr = 's';
765 pStr++;
766 *pStr = 'e';
767 pStr++;
768 *pStr = 0;
769 return 5;
770 }
771 }
772
773 /* ----------------------------------------------------------------------- */
774
valueOfChar(IMPL_RTL_STRCODE * pStr,IMPL_RTL_STRCODE c)775 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfChar )( IMPL_RTL_STRCODE* pStr,
776 IMPL_RTL_STRCODE c )
777 {
778 /* The caller must supply a writable buffer; on NULL write nothing. */
779 IMPL_RTL_STR_NULL_RETURN( pStr, 0 );
780 *pStr++ = c;
781 *pStr = 0;
782 return 1;
783 }
784
785 /* ----------------------------------------------------------------------- */
786
valueOfInt32(IMPL_RTL_STRCODE * pStr,sal_Int32 n,sal_Int16 nRadix)787 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt32 )( IMPL_RTL_STRCODE* pStr,
788 sal_Int32 n,
789 sal_Int16 nRadix )
790 {
791 sal_Char aBuf[RTL_STR_MAX_VALUEOFINT32];
792 sal_Char* pBuf = aBuf;
793 sal_Int32 nLen = 0;
794 sal_uInt32 nValue;
795
796 /* Radix must be valid */
797 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
798 nRadix = 10;
799
800 /* is value negativ */
801 if ( n < 0 )
802 {
803 *pStr = '-';
804 pStr++;
805 nLen++;
806 nValue = -n; /* FIXME this code is not portable for n == -2147483648
807 (smallest negative value for sal_Int32) */
808 }
809 else
810 nValue = n;
811
812 /* create a recursive buffer with all values, except the last one */
813 do
814 {
815 sal_Char nDigit = (sal_Char)(nValue % nRadix);
816 nValue /= nRadix;
817 if ( nDigit > 9 )
818 *pBuf = (nDigit-10) + 'a';
819 else
820 *pBuf = (nDigit + '0' );
821 pBuf++;
822 }
823 while ( nValue > 0 );
824
825 /* copy the values in the right direction into the destination buffer */
826 do
827 {
828 pBuf--;
829 *pStr = *pBuf;
830 pStr++;
831 nLen++;
832 }
833 while ( pBuf != aBuf );
834 *pStr = 0;
835
836 return nLen;
837 }
838
839 /* ----------------------------------------------------------------------- */
840
valueOfInt64(IMPL_RTL_STRCODE * pStr,sal_Int64 n,sal_Int16 nRadix)841 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt64 )( IMPL_RTL_STRCODE* pStr,
842 sal_Int64 n,
843 sal_Int16 nRadix )
844 {
845 sal_Char aBuf[RTL_STR_MAX_VALUEOFINT64];
846 sal_Char* pBuf = aBuf;
847 sal_Int32 nLen = 0;
848 sal_uInt64 nValue;
849
850 /* Radix must be valid */
851 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
852 nRadix = 10;
853
854 /* is value negativ */
855 if ( n < 0 )
856 {
857 *pStr = '-';
858 pStr++;
859 nLen++;
860 nValue = -n; /* FIXME this code is not portable for
861 n == -9223372036854775808 (smallest negative value for
862 sal_Int64) */
863 }
864 else
865 nValue = n;
866
867 /* create a recursive buffer with all values, except the last one */
868 do
869 {
870 sal_Char nDigit = (sal_Char)(nValue % nRadix);
871 nValue /= nRadix;
872 if ( nDigit > 9 )
873 *pBuf = (nDigit-10) + 'a';
874 else
875 *pBuf = (nDigit + '0' );
876 pBuf++;
877 }
878 while ( nValue > 0 );
879
880 /* copy the values in the right direction into the destination buffer */
881 do
882 {
883 pBuf--;
884 *pStr = *pBuf;
885 pStr++;
886 nLen++;
887 }
888 while ( pBuf != aBuf );
889 *pStr = 0;
890
891 return nLen;
892 }
893
894 /* ----------------------------------------------------------------------- */
895
toBoolean(const IMPL_RTL_STRCODE * pStr)896 sal_Bool SAL_CALL IMPL_RTL_STRNAME( toBoolean )( const IMPL_RTL_STRCODE* pStr )
897 {
898 if ( *pStr == '1' )
899 return sal_True;
900
901 if ( (*pStr == 'T') || (*pStr == 't') )
902 {
903 pStr++;
904 if ( (*pStr == 'R') || (*pStr == 'r') )
905 {
906 pStr++;
907 if ( (*pStr == 'U') || (*pStr == 'u') )
908 {
909 pStr++;
910 if ( (*pStr == 'E') || (*pStr == 'e') )
911 return sal_True;
912 }
913 }
914 }
915
916 return sal_False;
917 }
918
919 /* ----------------------------------------------------------------------- */
920
toInt32(const IMPL_RTL_STRCODE * pStr,sal_Int16 nRadix)921 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr,
922 sal_Int16 nRadix )
923 {
924 sal_Bool bNeg;
925 sal_Int16 nDigit;
926 sal_Int32 n = 0;
927
928 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
929 nRadix = 10;
930
931 /* Skip whitespaces */
932 while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
933 pStr++;
934
935 if ( *pStr == '-' )
936 {
937 bNeg = sal_True;
938 pStr++;
939 }
940 else
941 {
942 if ( *pStr == '+' )
943 pStr++;
944 bNeg = sal_False;
945 }
946
947 while ( *pStr )
948 {
949 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
950 if ( nDigit < 0 )
951 break;
952
953 n *= nRadix;
954 n += nDigit;
955
956 pStr++;
957 }
958
959 if ( bNeg )
960 return -n;
961 else
962 return n;
963 }
964
965 /* ----------------------------------------------------------------------- */
966
toInt64(const IMPL_RTL_STRCODE * pStr,sal_Int16 nRadix)967 sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr,
968 sal_Int16 nRadix )
969 {
970 sal_Bool bNeg;
971 sal_Int16 nDigit;
972 sal_Int64 n = 0;
973
974 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
975 nRadix = 10;
976
977 /* Skip whitespaces */
978 while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
979 pStr++;
980
981 if ( *pStr == '-' )
982 {
983 bNeg = sal_True;
984 pStr++;
985 }
986 else
987 {
988 if ( *pStr == '+' )
989 pStr++;
990 bNeg = sal_False;
991 }
992
993 while ( *pStr )
994 {
995 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
996 if ( nDigit < 0 )
997 break;
998
999 n *= nRadix;
1000 n += nDigit;
1001
1002 pStr++;
1003 }
1004
1005 if ( bNeg )
1006 return -n;
1007 else
1008 return n;
1009 }
1010
1011 /* ======================================================================= */
1012 /* Internal String-Class help functions */
1013 /* ======================================================================= */
1014
ImplAlloc(sal_Int32 nLen)1015 static IMPL_RTL_STRINGDATA* IMPL_RTL_STRINGNAME( ImplAlloc )( sal_Int32 nLen )
1016 {
1017 IMPL_RTL_STRINGDATA * pData
1018 = (SAL_INT_CAST(sal_uInt32, nLen)
1019 <= ((SAL_MAX_UINT32 - sizeof (IMPL_RTL_STRINGDATA))
1020 / sizeof (IMPL_RTL_STRCODE)))
1021 ? (IMPL_RTL_STRINGDATA *) rtl_allocateMemory(
1022 sizeof (IMPL_RTL_STRINGDATA) + nLen * sizeof (IMPL_RTL_STRCODE))
1023 : NULL;
1024 if (pData != NULL) {
1025 pData->refCount = 1;
1026 pData->length = nLen;
1027 pData->buffer[nLen] = 0;
1028 }
1029 return pData;
1030 }
1031
1032 /* ----------------------------------------------------------------------- */
1033
ImplNewCopy(IMPL_RTL_STRINGDATA ** ppThis,IMPL_RTL_STRINGDATA * pStr,sal_Int32 nCount)1034 static IMPL_RTL_STRCODE* IMPL_RTL_STRINGNAME( ImplNewCopy )( IMPL_RTL_STRINGDATA** ppThis,
1035 IMPL_RTL_STRINGDATA* pStr,
1036 sal_Int32 nCount )
1037 {
1038 IMPL_RTL_STRCODE* pDest;
1039 const IMPL_RTL_STRCODE* pSrc;
1040 IMPL_RTL_STRINGDATA* pData = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1041 OSL_ASSERT(pData != NULL);
1042
1043 pDest = pData->buffer;
1044 pSrc = pStr->buffer;
1045 while ( nCount > 0 )
1046 {
1047 *pDest = *pSrc;
1048 pDest++;
1049 pSrc++;
1050 nCount--;
1051 }
1052
1053 *ppThis = pData;
1054 return pDest;
1055 }
1056
1057 /* ======================================================================= */
1058 /* String-Class functions */
1059 /* ======================================================================= */
1060
1061 #define IMPL_RTL_AQUIRE( pThis ) \
1062 { \
1063 if (!SAL_STRING_IS_STATIC (pThis)) \
1064 osl_incrementInterlockedCount( &((pThis)->refCount) ); \
1065 }
1066
1067 /* ----------------------------------------------------------------------- */
1068
acquire(IMPL_RTL_STRINGDATA * pThis)1069 void SAL_CALL IMPL_RTL_STRINGNAME( acquire )( IMPL_RTL_STRINGDATA* pThis )
1070 {
1071 IMPL_RTL_AQUIRE( pThis );
1072 }
1073
1074 /* ----------------------------------------------------------------------- */
1075
release(IMPL_RTL_STRINGDATA * pThis)1076 void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis )
1077 {
1078 if (SAL_STRING_IS_STATIC (pThis))
1079 return;
1080
1081 /* OString doesn't have an 'intern' */
1082 #ifdef IMPL_RTL_INTERN
1083 if (SAL_STRING_IS_INTERN (pThis))
1084 {
1085 internRelease (pThis);
1086 return;
1087 }
1088 #endif
1089
1090 if ( pThis->refCount == 1 ||
1091 !osl_decrementInterlockedCount( &(pThis->refCount) ) )
1092 {
1093 rtl_freeMemory( pThis );
1094 }
1095 }
1096
1097 /* ----------------------------------------------------------------------- */
1098
new(IMPL_RTL_STRINGDATA ** ppThis)1099 void SAL_CALL IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA** ppThis )
1100 {
1101 if ( *ppThis)
1102 IMPL_RTL_STRINGNAME( release )( *ppThis );
1103
1104 *ppThis = (IMPL_RTL_STRINGDATA*) (&IMPL_RTL_EMPTYSTRING);
1105 IMPL_RTL_AQUIRE( *ppThis );
1106 }
1107
1108 /* ----------------------------------------------------------------------- */
1109
new_WithLength(IMPL_RTL_STRINGDATA ** ppThis,sal_Int32 nLen)1110 void SAL_CALL IMPL_RTL_STRINGNAME( new_WithLength )( IMPL_RTL_STRINGDATA** ppThis, sal_Int32 nLen )
1111 {
1112 if ( nLen <= 0 )
1113 IMPL_RTL_STRINGNAME( new )( ppThis );
1114 else
1115 {
1116 if ( *ppThis)
1117 IMPL_RTL_STRINGNAME( release )( *ppThis );
1118
1119 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1120 OSL_ASSERT(*ppThis != NULL);
1121 (*ppThis)->length = 0;
1122
1123 {
1124 IMPL_RTL_STRCODE* pTempStr = (*ppThis)->buffer;
1125 while ( nLen >= 0 )
1126 {
1127 *pTempStr = 0;
1128 pTempStr++;
1129 nLen--;
1130 }
1131 }
1132 }
1133 }
1134
1135 /* ----------------------------------------------------------------------- */
1136
newFromString(IMPL_RTL_STRINGDATA ** ppThis,const IMPL_RTL_STRINGDATA * pStr)1137 void SAL_CALL IMPL_RTL_STRINGNAME( newFromString )( IMPL_RTL_STRINGDATA** ppThis,
1138 const IMPL_RTL_STRINGDATA* pStr )
1139 {
1140 IMPL_RTL_STRINGDATA* pOrg;
1141
1142 if ( !pStr->length )
1143 {
1144 IMPL_RTL_STRINGNAME( new )( ppThis );
1145 return;
1146 }
1147
1148 pOrg = *ppThis;
1149 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1150 OSL_ASSERT(*ppThis != NULL);
1151 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer, pStr->length );
1152
1153 /* must be done at least, if pStr == *ppThis */
1154 if ( pOrg )
1155 IMPL_RTL_STRINGNAME( release )( pOrg );
1156 }
1157
1158 /* ----------------------------------------------------------------------- */
1159
newFromStr(IMPL_RTL_STRINGDATA ** ppThis,const IMPL_RTL_STRCODE * pCharStr)1160 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr )( IMPL_RTL_STRINGDATA** ppThis,
1161 const IMPL_RTL_STRCODE* pCharStr )
1162 {
1163 IMPL_RTL_STRCODE* pBuffer;
1164 IMPL_RTL_STRINGDATA* pOrg;
1165 sal_Int32 nLen;
1166
1167 if ( pCharStr )
1168 {
1169 const IMPL_RTL_STRCODE* pTempStr = pCharStr;
1170 while( *pTempStr )
1171 pTempStr++;
1172 nLen = pTempStr-pCharStr;
1173 }
1174 else
1175 nLen = 0;
1176
1177 if ( !nLen )
1178 {
1179 IMPL_RTL_STRINGNAME( new )( ppThis );
1180 return;
1181 }
1182
1183 pOrg = *ppThis;
1184 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1185 OSL_ASSERT(*ppThis != NULL);
1186 pBuffer = (*ppThis)->buffer;
1187 do
1188 {
1189 *pBuffer = *pCharStr;
1190 pBuffer++;
1191 pCharStr++;
1192 }
1193 while ( *pCharStr );
1194
1195 /* must be done at least, if pCharStr == *ppThis */
1196 if ( pOrg )
1197 IMPL_RTL_STRINGNAME( release )( pOrg );
1198 }
1199
1200 /* ----------------------------------------------------------------------- */
1201
newFromStr_WithLength(IMPL_RTL_STRINGDATA ** ppThis,const IMPL_RTL_STRCODE * pCharStr,sal_Int32 nLen)1202 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA** ppThis,
1203 const IMPL_RTL_STRCODE* pCharStr,
1204 sal_Int32 nLen )
1205 {
1206 IMPL_RTL_STRINGDATA* pOrg;
1207
1208 if ( !pCharStr || (nLen <= 0) )
1209 {
1210 IMPL_RTL_STRINGNAME( new )( ppThis );
1211 return;
1212 }
1213
1214 pOrg = *ppThis;
1215 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1216 OSL_ASSERT(*ppThis != NULL);
1217 rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
1218
1219 /* must be done at least, if pCharStr == *ppThis */
1220 if ( pOrg )
1221 IMPL_RTL_STRINGNAME( release )( pOrg );
1222 }
1223
1224 /* ----------------------------------------------------------------------- */
1225
assign(IMPL_RTL_STRINGDATA ** ppThis,IMPL_RTL_STRINGDATA * pStr)1226 void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis,
1227 IMPL_RTL_STRINGDATA* pStr )
1228 {
1229 /* must be done at first, if pStr == *ppThis */
1230 IMPL_RTL_AQUIRE( pStr );
1231
1232 if ( *ppThis )
1233 IMPL_RTL_STRINGNAME( release )( *ppThis );
1234
1235 *ppThis = pStr;
1236 }
1237
1238 /* ----------------------------------------------------------------------- */
1239
getLength(const IMPL_RTL_STRINGDATA * pThis)1240 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getLength )( const IMPL_RTL_STRINGDATA* pThis )
1241 {
1242 return pThis->length;
1243 }
1244
1245 /* ----------------------------------------------------------------------- */
1246
getStr(IMPL_RTL_STRINGDATA * pThis)1247 IMPL_RTL_STRCODE* SAL_CALL IMPL_RTL_STRINGNAME( getStr )( IMPL_RTL_STRINGDATA * pThis )
1248 {
1249 return pThis->buffer;
1250 }
1251
1252 /* ----------------------------------------------------------------------- */
1253
newConcat(IMPL_RTL_STRINGDATA ** ppThis,IMPL_RTL_STRINGDATA * pLeft,IMPL_RTL_STRINGDATA * pRight)1254 void SAL_CALL IMPL_RTL_STRINGNAME( newConcat )( IMPL_RTL_STRINGDATA** ppThis,
1255 IMPL_RTL_STRINGDATA* pLeft,
1256 IMPL_RTL_STRINGDATA* pRight )
1257 {
1258 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1259
1260 /* Test for 0-Pointer - if not, change newReplaceStrAt! */
1261 if ( !pRight || !pRight->length )
1262 {
1263 *ppThis = pLeft;
1264 IMPL_RTL_AQUIRE( pLeft );
1265 }
1266 else if ( !pLeft || !pLeft->length )
1267 {
1268 *ppThis = pRight;
1269 IMPL_RTL_AQUIRE( pRight );
1270 }
1271 else
1272 {
1273 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( pLeft->length + pRight->length );
1274 OSL_ASSERT(pTempStr != NULL);
1275 rtl_str_ImplCopy( pTempStr->buffer, pLeft->buffer, pLeft->length );
1276 rtl_str_ImplCopy( pTempStr->buffer+pLeft->length, pRight->buffer, pRight->length );
1277 *ppThis = pTempStr;
1278 }
1279
1280 /* must be done at least, if left or right == *ppThis */
1281 if ( pOrg )
1282 IMPL_RTL_STRINGNAME( release )( pOrg );
1283 }
1284
1285 /* ----------------------------------------------------------------------- */
1286
newReplaceStrAt(IMPL_RTL_STRINGDATA ** ppThis,IMPL_RTL_STRINGDATA * pStr,sal_Int32 nIndex,sal_Int32 nCount,IMPL_RTL_STRINGDATA * pNewSubStr)1287 void SAL_CALL IMPL_RTL_STRINGNAME( newReplaceStrAt )( IMPL_RTL_STRINGDATA** ppThis,
1288 IMPL_RTL_STRINGDATA* pStr,
1289 sal_Int32 nIndex,
1290 sal_Int32 nCount,
1291 IMPL_RTL_STRINGDATA* pNewSubStr )
1292 {
1293 /* Append? */
1294 if ( nIndex >= pStr->length )
1295 {
1296 /* newConcat test, if pNewSubStr is 0 */
1297 IMPL_RTL_STRINGNAME( newConcat )( ppThis, pStr, pNewSubStr );
1298 return;
1299 }
1300
1301 /* negativ index? */
1302 if ( nIndex < 0 )
1303 {
1304 nCount -= nIndex;
1305 nIndex = 0;
1306 }
1307
1308 /* not more than the String length could be deleted */
1309 if ( nCount >= pStr->length-nIndex )
1310 {
1311 nCount = pStr->length-nIndex;
1312
1313 /* Assign of NewSubStr? */
1314 if ( !nIndex && (nCount >= pStr->length) )
1315 {
1316 if ( !pNewSubStr )
1317 IMPL_RTL_STRINGNAME( new )( ppThis );
1318 else
1319 IMPL_RTL_STRINGNAME( assign )( ppThis, pNewSubStr );
1320 return;
1321 }
1322 }
1323
1324 /* Assign of Str? */
1325 if ( !nCount && (!pNewSubStr || !pNewSubStr->length) )
1326 {
1327 IMPL_RTL_STRINGNAME( assign )( ppThis, pStr );
1328 return;
1329 }
1330
1331 {
1332 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1333 IMPL_RTL_STRCODE* pBuffer;
1334 sal_Int32 nNewLen;
1335
1336 /* Calculate length of the new string */
1337 nNewLen = pStr->length-nCount;
1338 if ( pNewSubStr )
1339 nNewLen += pNewSubStr->length;
1340
1341 /* Alloc New Buffer */
1342 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
1343 OSL_ASSERT(*ppThis != NULL);
1344 pBuffer = (*ppThis)->buffer;
1345 if ( nIndex )
1346 {
1347 rtl_str_ImplCopy( pBuffer, pStr->buffer, nIndex );
1348 pBuffer += nIndex;
1349 }
1350 if ( pNewSubStr && pNewSubStr->length )
1351 {
1352 rtl_str_ImplCopy( pBuffer, pNewSubStr->buffer, pNewSubStr->length );
1353 pBuffer += pNewSubStr->length;
1354 }
1355 rtl_str_ImplCopy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount );
1356
1357 /* must be done at least, if pStr or pNewSubStr == *ppThis */
1358 if ( pOrg )
1359 IMPL_RTL_STRINGNAME( release )( pOrg );
1360 }
1361 }
1362
1363 /* ----------------------------------------------------------------------- */
1364
newReplace(IMPL_RTL_STRINGDATA ** ppThis,IMPL_RTL_STRINGDATA * pStr,IMPL_RTL_STRCODE cOld,IMPL_RTL_STRCODE cNew)1365 void SAL_CALL IMPL_RTL_STRINGNAME( newReplace )( IMPL_RTL_STRINGDATA** ppThis,
1366 IMPL_RTL_STRINGDATA* pStr,
1367 IMPL_RTL_STRCODE cOld,
1368 IMPL_RTL_STRCODE cNew )
1369 {
1370 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1371 int bChanged = 0;
1372 sal_Int32 nLen = pStr->length;
1373 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1374
1375 while ( nLen > 0 )
1376 {
1377 if ( *pCharStr == cOld )
1378 {
1379 /* Copy String */
1380 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1381
1382 /* replace/copy rest of the string */
1383 if ( pNewCharStr )
1384 {
1385 *pNewCharStr = cNew;
1386 pNewCharStr++;
1387 pCharStr++;
1388 nLen--;
1389
1390 while ( nLen > 0 )
1391 {
1392 if ( *pCharStr == cOld )
1393 *pNewCharStr = cNew;
1394 else
1395 *pNewCharStr = *pCharStr;
1396
1397 pNewCharStr++;
1398 pCharStr++;
1399 nLen--;
1400 }
1401 }
1402
1403 bChanged = 1;
1404 break;
1405 }
1406
1407 pCharStr++;
1408 nLen--;
1409 }
1410
1411 if ( !bChanged )
1412 {
1413 *ppThis = pStr;
1414 IMPL_RTL_AQUIRE( pStr );
1415 }
1416
1417 /* must be done at least, if pStr == *ppThis */
1418 if ( pOrg )
1419 IMPL_RTL_STRINGNAME( release )( pOrg );
1420 }
1421
1422 /* ----------------------------------------------------------------------- */
1423
newToAsciiLowerCase(IMPL_RTL_STRINGDATA ** ppThis,IMPL_RTL_STRINGDATA * pStr)1424 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiLowerCase )( IMPL_RTL_STRINGDATA** ppThis,
1425 IMPL_RTL_STRINGDATA* pStr )
1426 {
1427 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1428 int bChanged = 0;
1429 sal_Int32 nLen = pStr->length;
1430 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1431
1432 while ( nLen > 0 )
1433 {
1434 /* Between A-Z (65-90), than to lowercase (+32) */
1435 if ( (*pCharStr >= 65) && (*pCharStr <= 90) )
1436 {
1437 /* Copy String */
1438 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1439
1440 /* replace/copy rest of the string */
1441 if ( pNewCharStr )
1442 {
1443 /* to lowercase (+32) */
1444 *pNewCharStr = *pCharStr+32;
1445 pNewCharStr++;
1446 pCharStr++;
1447 nLen--;
1448
1449 while ( nLen > 0 )
1450 {
1451 /* Between A-Z (65-90), than to lowercase (+32) */
1452 if ( (*pCharStr >= 65) && (*pCharStr <= 90) )
1453 *pNewCharStr = *pCharStr+32;
1454 else
1455 *pNewCharStr = *pCharStr;
1456
1457 pNewCharStr++;
1458 pCharStr++;
1459 nLen--;
1460 }
1461 }
1462
1463 bChanged = 1;
1464 break;
1465 }
1466
1467 pCharStr++;
1468 nLen--;
1469 }
1470
1471 if ( !bChanged )
1472 {
1473 *ppThis = pStr;
1474 IMPL_RTL_AQUIRE( pStr );
1475 }
1476
1477 /* must be done at least, if pStr == *ppThis */
1478 if ( pOrg )
1479 IMPL_RTL_STRINGNAME( release )( pOrg );
1480 }
1481
1482 /* ----------------------------------------------------------------------- */
1483
newToAsciiUpperCase(IMPL_RTL_STRINGDATA ** ppThis,IMPL_RTL_STRINGDATA * pStr)1484 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiUpperCase )( IMPL_RTL_STRINGDATA** ppThis,
1485 IMPL_RTL_STRINGDATA* pStr )
1486 {
1487 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1488 int bChanged = 0;
1489 sal_Int32 nLen = pStr->length;
1490 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1491
1492 while ( nLen > 0 )
1493 {
1494 /* Between a-z (97-122), than to uppercase (-32) */
1495 if ( (*pCharStr >= 97) && (*pCharStr <= 122) )
1496 {
1497 /* Copy String */
1498 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1499
1500 /* replace/copy rest of the string */
1501 if ( pNewCharStr )
1502 {
1503 /* to uppercase (-32) */
1504 *pNewCharStr = *pCharStr-32;
1505 pNewCharStr++;
1506 pCharStr++;
1507 nLen--;
1508
1509 while ( nLen > 0 )
1510 {
1511 /* Between a-z (97-122), than to uppercase (-32) */
1512 if ( (*pCharStr >= 97) && (*pCharStr <= 122) )
1513 *pNewCharStr = *pCharStr-32;
1514 else
1515 *pNewCharStr = *pCharStr;
1516
1517 pNewCharStr++;
1518 pCharStr++;
1519 nLen--;
1520 }
1521 }
1522
1523 bChanged = 1;
1524 break;
1525 }
1526
1527 pCharStr++;
1528 nLen--;
1529 }
1530
1531 if ( !bChanged )
1532 {
1533 *ppThis = pStr;
1534 IMPL_RTL_AQUIRE( pStr );
1535 }
1536
1537 /* must be done at least, if pStr == *ppThis */
1538 if ( pOrg )
1539 IMPL_RTL_STRINGNAME( release )( pOrg );
1540 }
1541
1542 /* ----------------------------------------------------------------------- */
1543
newTrim(IMPL_RTL_STRINGDATA ** ppThis,IMPL_RTL_STRINGDATA * pStr)1544 void SAL_CALL IMPL_RTL_STRINGNAME( newTrim )( IMPL_RTL_STRINGDATA** ppThis,
1545 IMPL_RTL_STRINGDATA* pStr )
1546 {
1547 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1548 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1549 sal_Int32 nPreSpaces = 0;
1550 sal_Int32 nPostSpaces = 0;
1551 sal_Int32 nLen = pStr->length;
1552 sal_Int32 nIndex = nLen-1;
1553
1554 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nPreSpaces)) ) )
1555 nPreSpaces++;
1556
1557 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nIndex)) ) )
1558 {
1559 nPostSpaces++;
1560 nIndex--;
1561 }
1562
1563 if ( !nPreSpaces && !nPostSpaces )
1564 {
1565 *ppThis = pStr;
1566 IMPL_RTL_AQUIRE( pStr );
1567 }
1568 else
1569 {
1570 nLen -= nPostSpaces+nPreSpaces;
1571 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1572 OSL_ASSERT(*ppThis != NULL);
1573 if ( *ppThis )
1574 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer+nPreSpaces, nLen );
1575 }
1576
1577 /* must be done at least, if pStr == *ppThis */
1578 if ( pOrg )
1579 IMPL_RTL_STRINGNAME( release )( pOrg );
1580 }
1581
1582 /* ----------------------------------------------------------------------- */
1583
getToken(IMPL_RTL_STRINGDATA ** ppThis,IMPL_RTL_STRINGDATA * pStr,sal_Int32 nToken,IMPL_RTL_STRCODE cTok,sal_Int32 nIndex)1584 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getToken )( IMPL_RTL_STRINGDATA** ppThis,
1585 IMPL_RTL_STRINGDATA* pStr,
1586 sal_Int32 nToken,
1587 IMPL_RTL_STRCODE cTok,
1588 sal_Int32 nIndex )
1589 {
1590 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1591 const IMPL_RTL_STRCODE* pCharStrStart;
1592 const IMPL_RTL_STRCODE* pOrgCharStr;
1593 sal_Int32 nLen = pStr->length-nIndex;
1594 sal_Int32 nTokCount = 0;
1595
1596 // Set ppThis to an empty string and return -1 if either nToken or nIndex is
1597 // negative:
1598 if (nIndex < 0) {
1599 nToken = -1;
1600 }
1601
1602 pCharStr += nIndex;
1603 pOrgCharStr = pCharStr;
1604 pCharStrStart = pCharStr;
1605 while ( nLen > 0 )
1606 {
1607 if ( *pCharStr == cTok )
1608 {
1609 nTokCount++;
1610
1611 if ( nTokCount == nToken )
1612 pCharStrStart = pCharStr+1;
1613 else
1614 {
1615 if ( nTokCount > nToken )
1616 break;
1617 }
1618 }
1619
1620 pCharStr++;
1621 nLen--;
1622 }
1623
1624 if ( (nToken < 0) || (nTokCount < nToken) || (pCharStr == pCharStrStart) )
1625 {
1626 IMPL_RTL_STRINGNAME( new )( ppThis );
1627 if( (nToken < 0) || (nTokCount < nToken ) )
1628 return -1;
1629 else if( nLen > 0 )
1630 return nIndex+(pCharStr-pOrgCharStr)+1;
1631 else return -1;
1632 }
1633 else
1634 {
1635 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pCharStrStart, pCharStr-pCharStrStart );
1636 if ( nLen )
1637 return nIndex+(pCharStr-pOrgCharStr)+1;
1638 else
1639 return -1;
1640 }
1641 }
1642