update credits
[LibreOffice.git] / sal / rtl / strtmpl.cxx
blob47bbc9b4a4c40969003e36c5d309a1ff8d3446c5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 /* ======================================================================= */
21 /* Internal C-String help functions which could be used without the */
22 /* String-Class */
23 /* ======================================================================= */
25 #include <string.h>
26 #include <sal/log.hxx>
27 #include <limits>
28 #include <boost/static_assert.hpp>
31 inline void rtl_str_ImplCopy( IMPL_RTL_STRCODE* pDest,
32 const IMPL_RTL_STRCODE* pSrc,
33 sal_Int32 nCount )
35 while ( nCount > 0 )
37 *pDest = *pSrc;
38 pDest++;
39 pSrc++;
40 nCount--;
45 #define rtl_str_ImplCopy( _pDest, _pSrc, _nCount ) \
46 { \
47 IMPL_RTL_STRCODE* __mm_pDest = _pDest; \
48 const IMPL_RTL_STRCODE* __mm_pSrc = _pSrc; \
49 sal_Int32 __mm_nCount = _nCount; \
50 while ( __mm_nCount > 0 ) \
51 { \
52 *__mm_pDest = *__mm_pSrc; \
53 __mm_pDest++; \
54 __mm_pSrc++; \
55 __mm_nCount--; \
56 } \
59 /* ======================================================================= */
60 /* C-String functions which could be used without the String-Class */
61 /* ======================================================================= */
63 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( getLength )( const IMPL_RTL_STRCODE* pStr )
64 SAL_THROW_EXTERN_C()
66 const IMPL_RTL_STRCODE* pTempStr = pStr;
67 while( *pTempStr )
68 pTempStr++;
69 return pTempStr-pStr;
72 /* ----------------------------------------------------------------------- */
74 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare )( const IMPL_RTL_STRCODE* pStr1,
75 const IMPL_RTL_STRCODE* pStr2 )
76 SAL_THROW_EXTERN_C()
78 sal_Int32 nRet;
79 while ( ((nRet = ((sal_Int32)(IMPL_RTL_USTRCODE(*pStr1)))-
80 ((sal_Int32)(IMPL_RTL_USTRCODE(*pStr2)))) == 0) &&
81 *pStr2 )
83 pStr1++;
84 pStr2++;
87 return nRet;
90 /* ----------------------------------------------------------------------- */
92 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
93 sal_Int32 nStr1Len,
94 const IMPL_RTL_STRCODE* pStr2,
95 sal_Int32 nStr2Len )
96 SAL_THROW_EXTERN_C()
98 sal_Int32 nRet = nStr1Len - nStr2Len;
99 int nCount = (nRet <= 0) ? nStr1Len : nStr2Len;
101 --pStr1;
102 --pStr2;
103 while( (--nCount >= 0) && (*++pStr1 == *++pStr2) ) ;
105 if( nCount >= 0 )
106 nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 )))
107 - ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 )));
109 return nRet;
112 /* ----------------------------------------------------------------------- */
114 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
115 sal_Int32 nStr1Len,
116 const IMPL_RTL_STRCODE* pStr2,
117 sal_Int32 nStr2Len,
118 sal_Int32 nShortenedLength )
119 SAL_THROW_EXTERN_C()
121 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
122 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
123 sal_Int32 nRet;
124 while ( (nShortenedLength > 0) &&
125 (pStr1 < pStr1End) && (pStr2 < pStr2End) )
127 nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 )))-
128 ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 )));
129 if ( nRet )
130 return nRet;
132 nShortenedLength--;
133 pStr1++;
134 pStr2++;
137 if ( nShortenedLength <= 0 )
138 return 0;
139 return nStr1Len - nStr2Len;
142 /* ----------------------------------------------------------------------- */
144 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( reverseCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
145 sal_Int32 nStr1Len,
146 const IMPL_RTL_STRCODE* pStr2,
147 sal_Int32 nStr2Len )
148 SAL_THROW_EXTERN_C()
150 const IMPL_RTL_STRCODE* pStr1Run = pStr1+nStr1Len;
151 const IMPL_RTL_STRCODE* pStr2Run = pStr2+nStr2Len;
152 sal_Int32 nRet;
153 while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
155 pStr1Run--;
156 pStr2Run--;
157 nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1Run )))-
158 ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2Run )));
159 if ( nRet )
160 return nRet;
163 return nStr1Len - nStr2Len;
166 /* ----------------------------------------------------------------------- */
168 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase )( const IMPL_RTL_STRCODE* pStr1,
169 const IMPL_RTL_STRCODE* pStr2 )
170 SAL_THROW_EXTERN_C()
172 sal_Int32 nRet;
173 sal_Int32 c1;
174 sal_Int32 c2;
177 /* If character between 'A' and 'Z', than convert it to lowercase */
178 c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 );
179 c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 );
180 if ( (c1 >= 65) && (c1 <= 90) )
181 c1 += 32;
182 if ( (c2 >= 65) && (c2 <= 90) )
183 c2 += 32;
184 nRet = c1-c2;
185 if ( nRet != 0 )
186 return nRet;
188 pStr1++;
189 pStr2++;
191 while ( c2 );
193 return 0;
196 /* ----------------------------------------------------------------------- */
198 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
199 sal_Int32 nStr1Len,
200 const IMPL_RTL_STRCODE* pStr2,
201 sal_Int32 nStr2Len )
202 SAL_THROW_EXTERN_C()
204 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
205 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
206 sal_Int32 nRet;
207 sal_Int32 c1;
208 sal_Int32 c2;
209 while ( (pStr1 < pStr1End) && (pStr2 < pStr2End) )
211 /* If character between 'A' and 'Z', than convert it to lowercase */
212 c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 );
213 c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 );
214 if ( (c1 >= 65) && (c1 <= 90) )
215 c1 += 32;
216 if ( (c2 >= 65) && (c2 <= 90) )
217 c2 += 32;
218 nRet = c1-c2;
219 if ( nRet != 0 )
220 return nRet;
222 pStr1++;
223 pStr2++;
226 return nStr1Len - nStr2Len;
229 /* ----------------------------------------------------------------------- */
231 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
232 sal_Int32 nStr1Len,
233 const IMPL_RTL_STRCODE* pStr2,
234 sal_Int32 nStr2Len,
235 sal_Int32 nShortenedLength )
236 SAL_THROW_EXTERN_C()
238 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
239 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
240 sal_Int32 nRet;
241 sal_Int32 c1;
242 sal_Int32 c2;
243 while ( (nShortenedLength > 0) &&
244 (pStr1 < pStr1End) && (pStr2 < pStr2End) )
246 /* If character between 'A' and 'Z', than convert it to lowercase */
247 c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 );
248 c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 );
249 if ( (c1 >= 65) && (c1 <= 90) )
250 c1 += 32;
251 if ( (c2 >= 65) && (c2 <= 90) )
252 c2 += 32;
253 nRet = c1-c2;
254 if ( nRet != 0 )
255 return nRet;
257 nShortenedLength--;
258 pStr1++;
259 pStr2++;
262 if ( nShortenedLength <= 0 )
263 return 0;
264 return nStr1Len - nStr2Len;
267 /* ----------------------------------------------------------------------- */
269 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode )( const IMPL_RTL_STRCODE* pStr )
270 SAL_THROW_EXTERN_C()
272 return IMPL_RTL_STRNAME( hashCode_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
275 /* ----------------------------------------------------------------------- */
277 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode_WithLength )( const IMPL_RTL_STRCODE* pStr,
278 sal_Int32 nLen )
279 SAL_THROW_EXTERN_C()
281 sal_Int32 h = nLen;
283 if ( nLen < 256 )
285 while ( nLen > 0 )
287 h = (h*37) + IMPL_RTL_USTRCODE( *pStr );
288 pStr++;
289 nLen--;
292 else
294 sal_Int32 nSkip;
295 const IMPL_RTL_STRCODE* pEndStr = pStr+nLen-5;
297 /* only sample some characters */
298 /* the first 3, some characters between, and the last 5 */
299 h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
300 pStr++;
301 h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
302 pStr++;
303 h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
304 pStr++;
306 nSkip = nLen / 8;
307 nLen -= 8;
308 while ( nLen > 0 )
310 h = (h*39) + IMPL_RTL_USTRCODE( *pStr );
311 pStr += nSkip;
312 nLen -= nSkip;
315 h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
316 pEndStr++;
317 h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
318 pEndStr++;
319 h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
320 pEndStr++;
321 h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
322 pEndStr++;
323 h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr );
326 return h;
329 /* ----------------------------------------------------------------------- */
331 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar )( const IMPL_RTL_STRCODE* pStr,
332 IMPL_RTL_STRCODE c )
333 SAL_THROW_EXTERN_C()
335 const IMPL_RTL_STRCODE* pTempStr = pStr;
336 while ( *pTempStr )
338 if ( *pTempStr == c )
339 return pTempStr-pStr;
341 pTempStr++;
344 return -1;
347 /* ----------------------------------------------------------------------- */
349 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
350 sal_Int32 nLen,
351 IMPL_RTL_STRCODE c )
352 SAL_THROW_EXTERN_C()
354 const IMPL_RTL_STRCODE* pTempStr = pStr;
355 while ( nLen > 0 )
357 if ( *pTempStr == c )
358 return pTempStr-pStr;
360 pTempStr++;
361 nLen--;
364 return -1;
367 /* ----------------------------------------------------------------------- */
369 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar )( const IMPL_RTL_STRCODE* pStr,
370 IMPL_RTL_STRCODE c )
371 SAL_THROW_EXTERN_C()
373 return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), c );
376 /* ----------------------------------------------------------------------- */
378 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
379 sal_Int32 nLen,
380 IMPL_RTL_STRCODE c )
381 SAL_THROW_EXTERN_C()
383 pStr += nLen;
384 while ( nLen > 0 )
386 nLen--;
387 pStr--;
389 if ( *pStr == c )
390 return nLen;
393 return -1;
396 /* ----------------------------------------------------------------------- */
398 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr )( const IMPL_RTL_STRCODE* pStr,
399 const IMPL_RTL_STRCODE* pSubStr )
400 SAL_THROW_EXTERN_C()
402 return IMPL_RTL_STRNAME( indexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
403 pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
406 /* ----------------------------------------------------------------------- */
408 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
409 sal_Int32 nStrLen,
410 const IMPL_RTL_STRCODE* pSubStr,
411 sal_Int32 nSubLen )
412 SAL_THROW_EXTERN_C()
414 /* faster search for a single character */
415 if ( nSubLen < 2 )
417 /* an empty SubString is always not foundable */
418 if ( nSubLen == 1 )
420 IMPL_RTL_STRCODE c = *pSubStr;
421 const IMPL_RTL_STRCODE* pTempStr = pStr;
422 while ( nStrLen > 0 )
424 if ( *pTempStr == c )
425 return pTempStr-pStr;
427 pTempStr++;
428 nStrLen--;
432 else
434 const IMPL_RTL_STRCODE* pTempStr = pStr;
435 while ( nStrLen > 0 )
437 if ( *pTempStr == *pSubStr )
439 /* Compare SubString */
440 if ( nSubLen <= nStrLen )
442 const IMPL_RTL_STRCODE* pTempStr1 = pTempStr;
443 const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
444 sal_Int32 nTempLen = nSubLen;
445 while ( nTempLen )
447 if ( *pTempStr1 != *pTempStr2 )
448 break;
450 pTempStr1++;
451 pTempStr2++;
452 nTempLen--;
455 if ( !nTempLen )
456 return pTempStr-pStr;
458 else
459 break;
462 nStrLen--;
463 pTempStr++;
467 return -1;
470 /* ----------------------------------------------------------------------- */
472 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr )( const IMPL_RTL_STRCODE* pStr,
473 const IMPL_RTL_STRCODE* pSubStr )
474 SAL_THROW_EXTERN_C()
476 return IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
477 pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
480 /* ----------------------------------------------------------------------- */
482 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
483 sal_Int32 nStrLen,
484 const IMPL_RTL_STRCODE* pSubStr,
485 sal_Int32 nSubLen )
486 SAL_THROW_EXTERN_C()
488 /* faster search for a single character */
489 if ( nSubLen < 2 )
491 /* an empty SubString is always not foundable */
492 if ( nSubLen == 1 )
494 IMPL_RTL_STRCODE c = *pSubStr;
495 pStr += nStrLen;
496 while ( nStrLen > 0 )
498 nStrLen--;
499 pStr--;
501 if ( *pStr == c )
502 return nStrLen;
506 else
508 pStr += nStrLen;
509 nStrLen -= nSubLen;
510 pStr -= nSubLen;
511 while ( nStrLen >= 0 )
513 const IMPL_RTL_STRCODE* pTempStr1 = pStr;
514 const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
515 sal_Int32 nTempLen = nSubLen;
516 while ( nTempLen )
518 if ( *pTempStr1 != *pTempStr2 )
519 break;
521 pTempStr1++;
522 pTempStr2++;
523 nTempLen--;
526 if ( !nTempLen )
527 return nStrLen;
529 nStrLen--;
530 pStr--;
534 return -1;
537 /* ----------------------------------------------------------------------- */
539 void SAL_CALL IMPL_RTL_STRNAME( replaceChar )( IMPL_RTL_STRCODE* pStr,
540 IMPL_RTL_STRCODE cOld,
541 IMPL_RTL_STRCODE cNew )
542 SAL_THROW_EXTERN_C()
544 while ( *pStr )
546 if ( *pStr == cOld )
547 *pStr = cNew;
549 pStr++;
553 /* ----------------------------------------------------------------------- */
555 void SAL_CALL IMPL_RTL_STRNAME( replaceChar_WithLength )( IMPL_RTL_STRCODE* pStr,
556 sal_Int32 nLen,
557 IMPL_RTL_STRCODE cOld,
558 IMPL_RTL_STRCODE cNew )
559 SAL_THROW_EXTERN_C()
561 while ( nLen > 0 )
563 if ( *pStr == cOld )
564 *pStr = cNew;
566 pStr++;
567 nLen--;
571 /* ----------------------------------------------------------------------- */
573 void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase )( IMPL_RTL_STRCODE* pStr )
574 SAL_THROW_EXTERN_C()
576 while ( *pStr )
578 /* Between A-Z (65-90), than to lowercase (+32) */
579 if ( (*pStr >= 65) && (*pStr <= 90) )
580 *pStr += 32;
582 pStr++;
586 /* ----------------------------------------------------------------------- */
588 void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength )( IMPL_RTL_STRCODE* pStr,
589 sal_Int32 nLen )
590 SAL_THROW_EXTERN_C()
592 while ( nLen > 0 )
594 /* Between A-Z (65-90), than to lowercase (+32) */
595 if ( (*pStr >= 65) && (*pStr <= 90) )
596 *pStr += 32;
598 pStr++;
599 nLen--;
603 /* ----------------------------------------------------------------------- */
605 void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase )( IMPL_RTL_STRCODE* pStr )
606 SAL_THROW_EXTERN_C()
608 while ( *pStr )
610 /* Between a-z (97-122), than to uppercase (-32) */
611 if ( (*pStr >= 97) && (*pStr <= 122) )
612 *pStr -= 32;
614 pStr++;
618 /* ----------------------------------------------------------------------- */
620 void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength )( IMPL_RTL_STRCODE* pStr,
621 sal_Int32 nLen )
622 SAL_THROW_EXTERN_C()
624 while ( nLen > 0 )
626 /* Between a-z (97-122), than to uppercase (-32) */
627 if ( (*pStr >= 97) && (*pStr <= 122) )
628 *pStr -= 32;
630 pStr++;
631 nLen--;
635 /* ----------------------------------------------------------------------- */
637 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim )( IMPL_RTL_STRCODE* pStr )
638 SAL_THROW_EXTERN_C()
640 return IMPL_RTL_STRNAME( trim_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
643 /* ----------------------------------------------------------------------- */
645 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim_WithLength )( IMPL_RTL_STRCODE* pStr, sal_Int32 nLen )
646 SAL_THROW_EXTERN_C()
648 sal_Int32 nPreSpaces = 0;
649 sal_Int32 nPostSpaces = 0;
650 sal_Int32 nIndex = nLen-1;
652 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nPreSpaces)) ) )
653 nPreSpaces++;
655 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nIndex)) ) )
657 nPostSpaces++;
658 nIndex--;
661 if ( nPostSpaces )
663 nLen -= nPostSpaces;
664 *(pStr+nLen) = 0;
667 if ( nPreSpaces )
669 IMPL_RTL_STRCODE* pNewStr = pStr+nPreSpaces;
671 nLen -= nPreSpaces;
672 nIndex = nLen;
674 while ( nIndex )
676 *pStr = *pNewStr;
677 pStr++;
678 pNewStr++;
679 nIndex--;
681 *pStr = 0;
684 return nLen;
687 /* ----------------------------------------------------------------------- */
689 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfBoolean )( IMPL_RTL_STRCODE* pStr, sal_Bool b )
690 SAL_THROW_EXTERN_C()
692 if ( b )
694 *pStr = 't';
695 pStr++;
696 *pStr = 'r';
697 pStr++;
698 *pStr = 'u';
699 pStr++;
700 *pStr = 'e';
701 pStr++;
702 *pStr = 0;
703 return 4;
705 else
707 *pStr = 'f';
708 pStr++;
709 *pStr = 'a';
710 pStr++;
711 *pStr = 'l';
712 pStr++;
713 *pStr = 's';
714 pStr++;
715 *pStr = 'e';
716 pStr++;
717 *pStr = 0;
718 return 5;
722 /* ----------------------------------------------------------------------- */
724 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfChar )( IMPL_RTL_STRCODE* pStr,
725 IMPL_RTL_STRCODE c )
726 SAL_THROW_EXTERN_C()
728 *pStr++ = c;
729 *pStr = 0;
730 return 1;
733 /* ----------------------------------------------------------------------- */
735 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt32 )( IMPL_RTL_STRCODE* pStr,
736 sal_Int32 n,
737 sal_Int16 nRadix )
738 SAL_THROW_EXTERN_C()
740 sal_Char aBuf[RTL_STR_MAX_VALUEOFINT32];
741 sal_Char* pBuf = aBuf;
742 sal_Int32 nLen = 0;
743 sal_uInt32 nValue;
745 /* Radix must be valid */
746 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
747 nRadix = 10;
749 /* is value negativ */
750 if ( n < 0 )
752 *pStr = '-';
753 pStr++;
754 nLen++;
755 nValue = -n; /* FIXME this code is not portable for n == -2147483648
756 (smallest negative value for sal_Int32) */
758 else
759 nValue = n;
761 /* create a recursive buffer with all values, except the last one */
764 sal_Char nDigit = (sal_Char)(nValue % nRadix);
765 nValue /= nRadix;
766 if ( nDigit > 9 )
767 *pBuf = (nDigit-10) + 'a';
768 else
769 *pBuf = (nDigit + '0' );
770 pBuf++;
772 while ( nValue > 0 );
774 /* copy the values in the right direction into the destination buffer */
777 pBuf--;
778 *pStr = *pBuf;
779 pStr++;
780 nLen++;
782 while ( pBuf != aBuf );
783 *pStr = 0;
785 return nLen;
788 /* ----------------------------------------------------------------------- */
790 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt64 )( IMPL_RTL_STRCODE* pStr,
791 sal_Int64 n,
792 sal_Int16 nRadix )
793 SAL_THROW_EXTERN_C()
795 sal_Char aBuf[RTL_STR_MAX_VALUEOFINT64];
796 sal_Char* pBuf = aBuf;
797 sal_Int32 nLen = 0;
798 sal_uInt64 nValue;
800 /* Radix must be valid */
801 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
802 nRadix = 10;
804 /* is value negativ */
805 if ( n < 0 )
807 *pStr = '-';
808 pStr++;
809 nLen++;
810 nValue = -n; /* FIXME this code is not portable for
811 n == -9223372036854775808 (smallest negative value for
812 sal_Int64) */
814 else
815 nValue = n;
817 /* create a recursive buffer with all values, except the last one */
820 sal_Char nDigit = (sal_Char)(nValue % nRadix);
821 nValue /= nRadix;
822 if ( nDigit > 9 )
823 *pBuf = (nDigit-10) + 'a';
824 else
825 *pBuf = (nDigit + '0' );
826 pBuf++;
828 while ( nValue > 0 );
830 /* copy the values in the right direction into the destination buffer */
833 pBuf--;
834 *pStr = *pBuf;
835 pStr++;
836 nLen++;
838 while ( pBuf != aBuf );
839 *pStr = 0;
841 return nLen;
844 /* ----------------------------------------------------------------------- */
846 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfUInt64 )( IMPL_RTL_STRCODE* pStr,
847 sal_uInt64 n,
848 sal_Int16 nRadix )
849 SAL_THROW_EXTERN_C()
851 sal_Char aBuf[RTL_STR_MAX_VALUEOFUINT64];
852 sal_Char* pBuf = aBuf;
853 sal_Int32 nLen = 0;
854 sal_uInt64 nValue;
856 /* Radix must be valid */
857 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
858 nRadix = 10;
860 nValue = n;
862 /* create a recursive buffer with all values, except the last one */
865 sal_Char nDigit = (sal_Char)(nValue % nRadix);
866 nValue /= nRadix;
867 if ( nDigit > 9 )
868 *pBuf = (nDigit-10) + 'a';
869 else
870 *pBuf = (nDigit + '0' );
871 pBuf++;
873 while ( nValue > 0 );
875 /* copy the values in the right direction into the destination buffer */
878 pBuf--;
879 *pStr = *pBuf;
880 pStr++;
881 nLen++;
883 while ( pBuf != aBuf );
884 *pStr = 0;
886 return nLen;
889 /* ----------------------------------------------------------------------- */
891 sal_Bool SAL_CALL IMPL_RTL_STRNAME( toBoolean )( const IMPL_RTL_STRCODE* pStr )
892 SAL_THROW_EXTERN_C()
894 if ( *pStr == '1' )
895 return sal_True;
897 if ( (*pStr == 'T') || (*pStr == 't') )
899 pStr++;
900 if ( (*pStr == 'R') || (*pStr == 'r') )
902 pStr++;
903 if ( (*pStr == 'U') || (*pStr == 'u') )
905 pStr++;
906 if ( (*pStr == 'E') || (*pStr == 'e') )
907 return sal_True;
912 return sal_False;
915 /* ----------------------------------------------------------------------- */
916 namespace {
917 template <typename T> static inline T IMPL_RTL_STRNAME( toInt )( const IMPL_RTL_STRCODE* pStr,
918 sal_Int16 nRadix )
920 BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_signed);
921 sal_Bool bNeg;
922 sal_Int16 nDigit;
923 T n = 0;
925 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
926 nRadix = 10;
928 /* Skip whitespaces */
929 while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
930 pStr++;
932 if ( *pStr == '-' )
934 bNeg = sal_True;
935 pStr++;
937 else
939 if ( *pStr == '+' )
940 pStr++;
941 bNeg = sal_False;
944 while ( *pStr )
946 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
947 if ( nDigit < 0 )
948 break;
950 n *= nRadix;
951 n += nDigit;
953 pStr++;
956 if ( bNeg )
957 return -n;
958 else
959 return n;
963 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr,
964 sal_Int16 nRadix )
965 SAL_THROW_EXTERN_C()
967 return IMPL_RTL_STRNAME( toInt )<sal_Int32>(pStr, nRadix);
970 sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr,
971 sal_Int16 nRadix )
972 SAL_THROW_EXTERN_C()
974 return IMPL_RTL_STRNAME( toInt )<sal_Int64>(pStr, nRadix);
977 /* ----------------------------------------------------------------------- */
979 sal_uInt64 SAL_CALL IMPL_RTL_STRNAME( toUInt64 )( const IMPL_RTL_STRCODE* pStr,
980 sal_Int16 nRadix )
981 SAL_THROW_EXTERN_C()
983 sal_Int16 nDigit;
984 sal_uInt64 n = 0;
986 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
987 nRadix = 10;
989 /* Skip whitespaces */
990 while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
991 ++pStr;
993 // skip optional explicit sign
994 if ( *pStr == '+' )
995 ++pStr;
997 const sal_uInt64 nDiv = SAL_MAX_UINT64/nRadix;
998 const sal_Int16 nMod = SAL_MAX_UINT64%nRadix;
999 while ( *pStr )
1001 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
1002 if ( nDigit < 0 )
1003 break;
1004 if( ( nMod < nDigit ? nDiv-1 : nDiv ) < n )
1005 return 0;
1007 n *= nRadix;
1008 n += nDigit;
1010 ++pStr;
1013 return n;
1016 /* ======================================================================= */
1017 /* Internal String-Class help functions */
1018 /* ======================================================================= */
1020 static IMPL_RTL_STRINGDATA* IMPL_RTL_STRINGNAME( ImplAlloc )( sal_Int32 nLen )
1022 IMPL_RTL_STRINGDATA * pData
1023 = (sal::static_int_cast< sal_uInt32 >(nLen)
1024 <= ((SAL_MAX_UINT32 - sizeof (IMPL_RTL_STRINGDATA))
1025 / sizeof (IMPL_RTL_STRCODE)))
1026 ? (IMPL_RTL_STRINGDATA *) rtl_allocateMemory(
1027 sizeof (IMPL_RTL_STRINGDATA) + nLen * sizeof (IMPL_RTL_STRCODE))
1028 : NULL;
1029 if (pData != NULL) {
1030 pData->refCount = 1;
1031 pData->length = nLen;
1032 pData->buffer[nLen] = 0;
1034 return pData;
1037 /* ----------------------------------------------------------------------- */
1039 static IMPL_RTL_STRCODE* IMPL_RTL_STRINGNAME( ImplNewCopy )( IMPL_RTL_STRINGDATA** ppThis,
1040 IMPL_RTL_STRINGDATA* pStr,
1041 sal_Int32 nCount )
1043 IMPL_RTL_STRCODE* pDest;
1044 const IMPL_RTL_STRCODE* pSrc;
1045 IMPL_RTL_STRINGDATA* pData = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1046 OSL_ASSERT(pData != NULL);
1048 pDest = pData->buffer;
1049 pSrc = pStr->buffer;
1050 while ( nCount > 0 )
1052 *pDest = *pSrc;
1053 pDest++;
1054 pSrc++;
1055 nCount--;
1058 *ppThis = pData;
1060 RTL_LOG_STRING_NEW( pData );
1061 return pDest;
1064 /* ======================================================================= */
1065 /* String-Class functions */
1066 /* ======================================================================= */
1068 #define IMPL_RTL_AQUIRE( pThis ) \
1070 if (!SAL_STRING_IS_STATIC (pThis)) \
1071 osl_atomic_increment( &((pThis)->refCount) ); \
1074 /* ----------------------------------------------------------------------- */
1076 void SAL_CALL IMPL_RTL_STRINGNAME( acquire )( IMPL_RTL_STRINGDATA* pThis )
1077 SAL_THROW_EXTERN_C()
1079 IMPL_RTL_AQUIRE( pThis );
1082 /* ----------------------------------------------------------------------- */
1084 void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis )
1085 SAL_THROW_EXTERN_C()
1087 if (SAL_STRING_IS_STATIC (pThis))
1088 return;
1090 /* OString doesn't have an 'intern' */
1091 #ifdef IMPL_RTL_INTERN
1092 if (SAL_STRING_IS_INTERN (pThis))
1094 internRelease (pThis);
1095 return;
1097 #endif
1099 if ( !osl_atomic_decrement( &(pThis->refCount) ) )
1101 RTL_LOG_STRING_DELETE( pThis );
1102 rtl_freeMemory( pThis );
1106 /* ----------------------------------------------------------------------- */
1108 void SAL_CALL IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA** ppThis )
1109 SAL_THROW_EXTERN_C()
1111 if ( *ppThis)
1112 IMPL_RTL_STRINGNAME( release )( *ppThis );
1114 *ppThis = (IMPL_RTL_STRINGDATA*) (&IMPL_RTL_EMPTYSTRING);
1117 /* ----------------------------------------------------------------------- */
1119 IMPL_RTL_STRINGDATA* SAL_CALL IMPL_RTL_STRINGNAME( alloc )( sal_Int32 nLen )
1120 SAL_THROW_EXTERN_C()
1122 if ( nLen < 0 )
1123 return NULL;
1124 else
1125 return IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1128 /* ----------------------------------------------------------------------- */
1130 void SAL_CALL IMPL_RTL_STRINGNAME( new_WithLength )( IMPL_RTL_STRINGDATA** ppThis, sal_Int32 nLen )
1131 SAL_THROW_EXTERN_C()
1133 if ( nLen <= 0 )
1134 IMPL_RTL_STRINGNAME( new )( ppThis );
1135 else
1137 if ( *ppThis)
1138 IMPL_RTL_STRINGNAME( release )( *ppThis );
1140 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1141 OSL_ASSERT(*ppThis != NULL);
1142 (*ppThis)->length = 0;
1144 IMPL_RTL_STRCODE* pTempStr = (*ppThis)->buffer;
1145 memset(pTempStr, 0, nLen*sizeof(IMPL_RTL_STRCODE));
1149 /* ----------------------------------------------------------------------- */
1151 void SAL_CALL IMPL_RTL_STRINGNAME( newFromString )( IMPL_RTL_STRINGDATA** ppThis,
1152 const IMPL_RTL_STRINGDATA* pStr )
1153 SAL_THROW_EXTERN_C()
1155 IMPL_RTL_STRINGDATA* pOrg;
1157 if ( !pStr->length )
1159 IMPL_RTL_STRINGNAME( new )( ppThis );
1160 return;
1163 pOrg = *ppThis;
1164 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1165 OSL_ASSERT(*ppThis != NULL);
1166 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer, pStr->length );
1167 RTL_LOG_STRING_NEW( *ppThis );
1169 /* must be done last, if pStr == *ppThis */
1170 if ( pOrg )
1171 IMPL_RTL_STRINGNAME( release )( pOrg );
1174 /* ----------------------------------------------------------------------- */
1176 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr )( IMPL_RTL_STRINGDATA** ppThis,
1177 const IMPL_RTL_STRCODE* pCharStr )
1178 SAL_THROW_EXTERN_C()
1180 IMPL_RTL_STRCODE* pBuffer;
1181 IMPL_RTL_STRINGDATA* pOrg;
1182 sal_Int32 nLen;
1184 if ( pCharStr )
1186 const IMPL_RTL_STRCODE* pTempStr = pCharStr;
1187 while( *pTempStr )
1188 pTempStr++;
1189 nLen = pTempStr-pCharStr;
1191 else
1192 nLen = 0;
1194 if ( !nLen )
1196 IMPL_RTL_STRINGNAME( new )( ppThis );
1197 return;
1200 pOrg = *ppThis;
1201 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1202 OSL_ASSERT(*ppThis != NULL);
1203 pBuffer = (*ppThis)->buffer;
1206 *pBuffer = *pCharStr;
1207 pBuffer++;
1208 pCharStr++;
1210 while ( *pCharStr );
1212 RTL_LOG_STRING_NEW( *ppThis );
1214 /* must be done last, if pCharStr == *ppThis */
1215 if ( pOrg )
1216 IMPL_RTL_STRINGNAME( release )( pOrg );
1219 /* ----------------------------------------------------------------------- */
1221 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA** ppThis,
1222 const IMPL_RTL_STRCODE* pCharStr,
1223 sal_Int32 nLen )
1224 SAL_THROW_EXTERN_C()
1226 IMPL_RTL_STRINGDATA* pOrg;
1228 if ( !pCharStr || (nLen <= 0) )
1230 IMPL_RTL_STRINGNAME( new )( ppThis );
1231 return;
1234 pOrg = *ppThis;
1235 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1236 OSL_ASSERT(*ppThis != NULL);
1237 rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
1239 RTL_LOG_STRING_NEW( *ppThis );
1241 /* must be done last, if pCharStr == *ppThis */
1242 if ( pOrg )
1243 IMPL_RTL_STRINGNAME( release )( pOrg );
1246 /* ----------------------------------------------------------------------- */
1248 void SAL_CALL IMPL_RTL_STRINGNAME( newFromSubString )( IMPL_RTL_STRINGDATA** ppThis,
1249 const IMPL_RTL_STRINGDATA* pFrom,
1250 sal_Int32 beginIndex,
1251 sal_Int32 count )
1252 SAL_THROW_EXTERN_C()
1254 if ( beginIndex == 0 && count == pFrom->length )
1256 IMPL_RTL_STRINGNAME( assign )( ppThis, const_cast< IMPL_RTL_STRINGDATA * >( pFrom ) );
1257 return;
1259 if ( count < 0 || beginIndex < 0 || beginIndex + count > pFrom->length )
1261 assert(false); // fail fast at least in debug builds
1262 IMPL_RTL_STRINGNAME( newFromLiteral )( ppThis, "!!br0ken!!", 10, 0 );
1263 return;
1266 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pFrom->buffer + beginIndex, count );
1269 /* ----------------------------------------------------------------------- */
1271 // Used when creating from string literals.
1272 void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral )( IMPL_RTL_STRINGDATA** ppThis,
1273 const sal_Char* pCharStr,
1274 sal_Int32 nLen,
1275 sal_Int32 allocExtra )
1276 SAL_THROW_EXTERN_C()
1278 if ( nLen + allocExtra == 0 )
1280 IMPL_RTL_STRINGNAME( new )( ppThis );
1281 return;
1284 if ( *ppThis )
1285 IMPL_RTL_STRINGNAME( release )( *ppThis );
1287 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen + allocExtra );
1288 assert( *ppThis != NULL );
1289 if ( (*ppThis) )
1291 (*ppThis)->length = nLen; // fix after possible allocExtra != 0
1292 (*ppThis)->buffer[nLen] = 0;
1293 IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer;
1294 sal_Int32 nCount;
1295 for( nCount = nLen; nCount > 0; --nCount )
1297 /* Check ASCII range */
1298 SAL_WARN_IF( ((unsigned char)*pCharStr) > 127, "rtl.string",
1299 "rtl_uString_newFromLiteral - Found char > 127" );
1300 SAL_WARN_IF( ((unsigned char)*pCharStr) == '\0', "rtl.string",
1301 "rtl_uString_newFromLiteral - Found embedded \\0 character" );
1303 *pBuffer = *pCharStr;
1304 pBuffer++;
1305 pCharStr++;
1309 RTL_LOG_STRING_NEW( *ppThis );
1312 /* ----------------------------------------------------------------------- */
1314 void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis,
1315 IMPL_RTL_STRINGDATA* pStr )
1316 SAL_THROW_EXTERN_C()
1318 /* must be done at first, if pStr == *ppThis */
1319 IMPL_RTL_AQUIRE( pStr );
1321 if ( *ppThis )
1322 IMPL_RTL_STRINGNAME( release )( *ppThis );
1324 *ppThis = pStr;
1327 /* ----------------------------------------------------------------------- */
1329 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getLength )( const IMPL_RTL_STRINGDATA* pThis )
1330 SAL_THROW_EXTERN_C()
1332 return pThis->length;
1335 /* ----------------------------------------------------------------------- */
1337 IMPL_RTL_STRCODE* SAL_CALL IMPL_RTL_STRINGNAME( getStr )( IMPL_RTL_STRINGDATA * pThis )
1338 SAL_THROW_EXTERN_C()
1340 return pThis->buffer;
1343 /* ----------------------------------------------------------------------- */
1345 void SAL_CALL IMPL_RTL_STRINGNAME( newConcat )( IMPL_RTL_STRINGDATA** ppThis,
1346 IMPL_RTL_STRINGDATA* pLeft,
1347 IMPL_RTL_STRINGDATA* pRight )
1348 SAL_THROW_EXTERN_C()
1350 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1352 /* Test for 0-Pointer - if not, change newReplaceStrAt! */
1353 if ( !pRight || !pRight->length )
1355 *ppThis = pLeft;
1356 IMPL_RTL_AQUIRE( pLeft );
1358 else if ( !pLeft || !pLeft->length )
1360 *ppThis = pRight;
1361 IMPL_RTL_AQUIRE( pRight );
1363 else
1365 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( pLeft->length + pRight->length );
1366 OSL_ASSERT(pTempStr != NULL);
1367 rtl_str_ImplCopy( pTempStr->buffer, pLeft->buffer, pLeft->length );
1368 rtl_str_ImplCopy( pTempStr->buffer+pLeft->length, pRight->buffer, pRight->length );
1369 *ppThis = pTempStr;
1371 RTL_LOG_STRING_NEW( *ppThis );
1374 /* must be done last, if left or right == *ppThis */
1375 if ( pOrg )
1376 IMPL_RTL_STRINGNAME( release )( pOrg );
1379 /* ----------------------------------------------------------------------- */
1381 void SAL_CALL IMPL_RTL_STRINGNAME( ensureCapacity )( IMPL_RTL_STRINGDATA** ppThis,
1382 sal_Int32 size )
1383 SAL_THROW_EXTERN_C()
1385 IMPL_RTL_STRINGDATA* const pOrg = *ppThis;
1386 if ( pOrg->refCount == 1 && pOrg->length >= size )
1387 return;
1388 assert( pOrg->length <= size ); // do not truncate
1389 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( size );
1390 rtl_str_ImplCopy( pTempStr->buffer, pOrg->buffer, pOrg->length );
1391 // right now the length is still the same as of the original
1392 pTempStr->length = pOrg->length;
1393 pTempStr->buffer[ pOrg->length ] = '\0';
1394 *ppThis = pTempStr;
1395 RTL_LOG_STRING_NEW( *ppThis );
1397 /* must be done last, if pStr == *ppThis */
1398 if ( pOrg )
1399 IMPL_RTL_STRINGNAME( release )( pOrg );
1402 /* ----------------------------------------------------------------------- */
1404 void SAL_CALL IMPL_RTL_STRINGNAME( newReplaceStrAt )( IMPL_RTL_STRINGDATA** ppThis,
1405 IMPL_RTL_STRINGDATA* pStr,
1406 sal_Int32 nIndex,
1407 sal_Int32 nCount,
1408 IMPL_RTL_STRINGDATA* pNewSubStr )
1409 SAL_THROW_EXTERN_C()
1411 /* Append? */
1412 if ( nIndex >= pStr->length )
1414 /* newConcat test, if pNewSubStr is 0 */
1415 IMPL_RTL_STRINGNAME( newConcat )( ppThis, pStr, pNewSubStr );
1416 return;
1419 /* negativ index? */
1420 if ( nIndex < 0 )
1422 nCount -= nIndex;
1423 nIndex = 0;
1426 /* not more than the String length could be deleted */
1427 if ( nCount >= pStr->length-nIndex )
1429 nCount = pStr->length-nIndex;
1431 /* Assign of NewSubStr? */
1432 if ( !nIndex && (nCount >= pStr->length) )
1434 if ( !pNewSubStr )
1435 IMPL_RTL_STRINGNAME( new )( ppThis );
1436 else
1437 IMPL_RTL_STRINGNAME( assign )( ppThis, pNewSubStr );
1438 return;
1442 /* Assign of Str? */
1443 if ( !nCount && (!pNewSubStr || !pNewSubStr->length) )
1445 IMPL_RTL_STRINGNAME( assign )( ppThis, pStr );
1446 return;
1449 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1450 IMPL_RTL_STRCODE* pBuffer;
1451 sal_Int32 nNewLen;
1453 /* Calculate length of the new string */
1454 nNewLen = pStr->length-nCount;
1455 if ( pNewSubStr )
1456 nNewLen += pNewSubStr->length;
1458 /* Alloc New Buffer */
1459 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
1460 OSL_ASSERT(*ppThis != NULL);
1461 pBuffer = (*ppThis)->buffer;
1462 if ( nIndex )
1464 rtl_str_ImplCopy( pBuffer, pStr->buffer, nIndex );
1465 pBuffer += nIndex;
1467 if ( pNewSubStr && pNewSubStr->length )
1469 rtl_str_ImplCopy( pBuffer, pNewSubStr->buffer, pNewSubStr->length );
1470 pBuffer += pNewSubStr->length;
1472 rtl_str_ImplCopy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount );
1474 RTL_LOG_STRING_NEW( *ppThis );
1475 /* must be done last, if pStr or pNewSubStr == *ppThis */
1476 if ( pOrg )
1477 IMPL_RTL_STRINGNAME( release )( pOrg );
1480 /* ----------------------------------------------------------------------- */
1482 void SAL_CALL IMPL_RTL_STRINGNAME( newReplace )( IMPL_RTL_STRINGDATA** ppThis,
1483 IMPL_RTL_STRINGDATA* pStr,
1484 IMPL_RTL_STRCODE cOld,
1485 IMPL_RTL_STRCODE cNew )
1486 SAL_THROW_EXTERN_C()
1488 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1489 int bChanged = 0;
1490 sal_Int32 nLen = pStr->length;
1491 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1493 while ( nLen > 0 )
1495 if ( *pCharStr == cOld )
1497 /* Copy String */
1498 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1500 /* replace/copy rest of the string */
1501 if ( pNewCharStr )
1503 *pNewCharStr = cNew;
1504 pNewCharStr++;
1505 pCharStr++;
1506 nLen--;
1508 while ( nLen > 0 )
1510 if ( *pCharStr == cOld )
1511 *pNewCharStr = cNew;
1512 else
1513 *pNewCharStr = *pCharStr;
1515 pNewCharStr++;
1516 pCharStr++;
1517 nLen--;
1521 bChanged = 1;
1522 break;
1525 pCharStr++;
1526 nLen--;
1529 if ( !bChanged )
1531 *ppThis = pStr;
1532 IMPL_RTL_AQUIRE( pStr );
1535 RTL_LOG_STRING_NEW( *ppThis );
1536 /* must be done last, if pStr == *ppThis */
1537 if ( pOrg )
1538 IMPL_RTL_STRINGNAME( release )( pOrg );
1541 /* ----------------------------------------------------------------------- */
1543 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiLowerCase )( IMPL_RTL_STRINGDATA** ppThis,
1544 IMPL_RTL_STRINGDATA* pStr )
1545 SAL_THROW_EXTERN_C()
1547 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1548 int bChanged = 0;
1549 sal_Int32 nLen = pStr->length;
1550 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1552 while ( nLen > 0 )
1554 /* Between A-Z (65-90), than to lowercase (+32) */
1555 if ( (*pCharStr >= 65) && (*pCharStr <= 90) )
1557 /* Copy String */
1558 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1560 /* replace/copy rest of the string */
1561 if ( pNewCharStr )
1563 /* to lowercase (+32) */
1564 *pNewCharStr = *pCharStr+32;
1565 pNewCharStr++;
1566 pCharStr++;
1567 nLen--;
1569 while ( nLen > 0 )
1571 /* Between A-Z (65-90), than to lowercase (+32) */
1572 if ( (*pCharStr >= 65) && (*pCharStr <= 90) )
1573 *pNewCharStr = *pCharStr+32;
1574 else
1575 *pNewCharStr = *pCharStr;
1577 pNewCharStr++;
1578 pCharStr++;
1579 nLen--;
1583 bChanged = 1;
1584 break;
1587 pCharStr++;
1588 nLen--;
1591 if ( !bChanged )
1593 *ppThis = pStr;
1594 IMPL_RTL_AQUIRE( pStr );
1597 RTL_LOG_STRING_NEW( *ppThis );
1598 /* must be done last, if pStr == *ppThis */
1599 if ( pOrg )
1600 IMPL_RTL_STRINGNAME( release )( pOrg );
1603 /* ----------------------------------------------------------------------- */
1605 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiUpperCase )( IMPL_RTL_STRINGDATA** ppThis,
1606 IMPL_RTL_STRINGDATA* pStr )
1607 SAL_THROW_EXTERN_C()
1609 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1610 int bChanged = 0;
1611 sal_Int32 nLen = pStr->length;
1612 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1614 while ( nLen > 0 )
1616 /* Between a-z (97-122), than to uppercase (-32) */
1617 if ( (*pCharStr >= 97) && (*pCharStr <= 122) )
1619 /* Copy String */
1620 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1622 /* replace/copy rest of the string */
1623 if ( pNewCharStr )
1625 /* to uppercase (-32) */
1626 *pNewCharStr = *pCharStr-32;
1627 pNewCharStr++;
1628 pCharStr++;
1629 nLen--;
1631 while ( nLen > 0 )
1633 /* Between a-z (97-122), than to uppercase (-32) */
1634 if ( (*pCharStr >= 97) && (*pCharStr <= 122) )
1635 *pNewCharStr = *pCharStr-32;
1636 else
1637 *pNewCharStr = *pCharStr;
1639 pNewCharStr++;
1640 pCharStr++;
1641 nLen--;
1645 bChanged = 1;
1646 break;
1649 pCharStr++;
1650 nLen--;
1653 if ( !bChanged )
1655 *ppThis = pStr;
1656 IMPL_RTL_AQUIRE( pStr );
1659 RTL_LOG_STRING_NEW( *ppThis );
1660 /* must be done last, if pStr == *ppThis */
1661 if ( pOrg )
1662 IMPL_RTL_STRINGNAME( release )( pOrg );
1665 /* ----------------------------------------------------------------------- */
1667 void SAL_CALL IMPL_RTL_STRINGNAME( newTrim )( IMPL_RTL_STRINGDATA** ppThis,
1668 IMPL_RTL_STRINGDATA* pStr )
1669 SAL_THROW_EXTERN_C()
1671 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1672 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1673 sal_Int32 nPreSpaces = 0;
1674 sal_Int32 nPostSpaces = 0;
1675 sal_Int32 nLen = pStr->length;
1676 sal_Int32 nIndex = nLen-1;
1678 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nPreSpaces)) ) )
1679 nPreSpaces++;
1681 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nIndex)) ) )
1683 nPostSpaces++;
1684 nIndex--;
1687 if ( !nPreSpaces && !nPostSpaces )
1689 *ppThis = pStr;
1690 IMPL_RTL_AQUIRE( pStr );
1692 else
1694 nLen -= nPostSpaces+nPreSpaces;
1695 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1696 OSL_ASSERT(*ppThis != NULL);
1697 if ( *ppThis )
1698 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer+nPreSpaces, nLen );
1701 RTL_LOG_STRING_NEW( *ppThis );
1702 /* must be done last, if pStr == *ppThis */
1703 if ( pOrg )
1704 IMPL_RTL_STRINGNAME( release )( pOrg );
1707 /* ----------------------------------------------------------------------- */
1709 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getToken )( IMPL_RTL_STRINGDATA** ppThis,
1710 IMPL_RTL_STRINGDATA* pStr,
1711 sal_Int32 nToken,
1712 IMPL_RTL_STRCODE cTok,
1713 sal_Int32 nIndex )
1714 SAL_THROW_EXTERN_C()
1716 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1717 const IMPL_RTL_STRCODE* pCharStrStart;
1718 const IMPL_RTL_STRCODE* pOrgCharStr;
1719 sal_Int32 nLen = pStr->length-nIndex;
1720 sal_Int32 nTokCount = 0;
1722 // Set ppThis to an empty string and return -1 if either nToken or nIndex is
1723 // negative:
1724 if (nIndex < 0)
1725 nToken = -1;
1727 pCharStr += nIndex;
1728 pOrgCharStr = pCharStr;
1729 pCharStrStart = pCharStr;
1730 while ( nLen > 0 )
1732 if ( *pCharStr == cTok )
1734 nTokCount++;
1736 if ( nTokCount == nToken )
1737 pCharStrStart = pCharStr+1;
1738 else
1740 if ( nTokCount > nToken )
1741 break;
1745 pCharStr++;
1746 nLen--;
1749 if ( (nToken < 0) || (nTokCount < nToken) || (pCharStr == pCharStrStart) )
1751 IMPL_RTL_STRINGNAME( new )( ppThis );
1752 if( (nToken < 0) || (nTokCount < nToken ) )
1753 return -1;
1754 else if( nLen > 0 )
1755 return nIndex+(pCharStr-pOrgCharStr)+1;
1756 else return -1;
1758 else
1760 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pCharStrStart, pCharStr-pCharStrStart );
1761 if ( nLen )
1762 return nIndex+(pCharStr-pOrgCharStr)+1;
1763 else
1764 return -1;
1768 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */