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