lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / sal / rtl / strtmpl.cxx
blob3cc4d992727429f4c72cd02f9c13b45dc9ac8af3
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 <algorithm>
26 #include <cassert>
27 #include <limits>
29 #include <cstring>
30 #include <wchar.h>
31 #include <sal/log.hxx>
32 #include <rtl/character.hxx>
35 inline void rtl_str_ImplCopy( IMPL_RTL_STRCODE* pDest,
36 const IMPL_RTL_STRCODE* pSrc,
37 sal_Int32 nCount )
39 while ( nCount > 0 )
41 *pDest = *pSrc;
42 pDest++;
43 pSrc++;
44 nCount--;
49 static void rtl_str_ImplCopy( IMPL_RTL_STRCODE* _pDest,
50 const IMPL_RTL_STRCODE* _pSrc,
51 sal_Int32 _nCount )
53 // take advantage of builtin optimisations
54 memcpy( _pDest, _pSrc, _nCount * sizeof(IMPL_RTL_STRCODE));
57 /* ======================================================================= */
58 /* C-String functions which could be used without the String-Class */
59 /* ======================================================================= */
61 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( getLength )( const IMPL_RTL_STRCODE* pStr )
62 SAL_THROW_EXTERN_C()
64 assert(pStr);
65 #if !IMPL_RTL_IS_USTRING
66 // take advantage of builtin optimisations
67 return strlen( pStr);
68 #else
69 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
71 // take advantage of builtin optimisations
72 return wcslen(reinterpret_cast<wchar_t const *>(pStr));
74 else
76 const IMPL_RTL_STRCODE* pTempStr = pStr;
77 while( *pTempStr )
78 pTempStr++;
79 return pTempStr-pStr;
81 #endif
84 /* ----------------------------------------------------------------------- */
86 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare )( const IMPL_RTL_STRCODE* pStr1,
87 const IMPL_RTL_STRCODE* pStr2 )
88 SAL_THROW_EXTERN_C()
90 assert(pStr1);
91 assert(pStr2);
92 #if !IMPL_RTL_IS_USTRING
93 // take advantage of builtin optimisations
94 return strcmp( pStr1, pStr2);
95 #else
96 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
98 // take advantage of builtin optimisations
99 return wcscmp(reinterpret_cast<wchar_t const *>(pStr1), reinterpret_cast<wchar_t const *>(pStr2));
101 else
103 sal_Int32 nRet;
104 while ( ((nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE(*pStr1))-
105 static_cast<sal_Int32>(IMPL_RTL_USTRCODE(*pStr2))) == 0) &&
106 *pStr2 )
108 pStr1++;
109 pStr2++;
112 return nRet;
114 #endif
117 /* ----------------------------------------------------------------------- */
119 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
120 sal_Int32 nStr1Len,
121 const IMPL_RTL_STRCODE* pStr2,
122 sal_Int32 nStr2Len )
123 SAL_THROW_EXTERN_C()
125 assert(nStr1Len >= 0);
126 assert(nStr2Len >= 0);
127 #if !IMPL_RTL_IS_USTRING
128 // take advantage of builtin optimisations
129 sal_Int32 nMin = std::min(nStr1Len, nStr2Len);
130 sal_Int32 nRet = memcmp(pStr1, pStr2, nMin);
131 return nRet == 0 ? nStr1Len - nStr2Len : nRet;
132 #else
133 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
135 // take advantage of builtin optimisations
136 sal_Int32 nMin = std::min(nStr1Len, nStr2Len);
137 sal_Int32 nRet = wmemcmp(reinterpret_cast<wchar_t const *>(pStr1),
138 reinterpret_cast<wchar_t const *>(pStr2), nMin);
139 return nRet == 0 ? nStr1Len - nStr2Len : nRet;
141 else
143 sal_Int32 nRet = nStr1Len - nStr2Len;
144 int nCount = (nRet <= 0) ? nStr1Len : nStr2Len;
146 --pStr1;
147 --pStr2;
148 while( (--nCount >= 0) && (*++pStr1 == *++pStr2) ) ;
150 if( nCount >= 0 )
151 nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr1 ))
152 - static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr2 ));
154 return nRet;
156 #endif
159 /* ----------------------------------------------------------------------- */
161 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
162 sal_Int32 nStr1Len,
163 const IMPL_RTL_STRCODE* pStr2,
164 sal_Int32 nStr2Len,
165 sal_Int32 nShortenedLength )
166 SAL_THROW_EXTERN_C()
168 assert(nStr1Len >= 0);
169 assert(nStr2Len >= 0);
170 assert(nShortenedLength >= 0);
171 #if !IMPL_RTL_IS_USTRING
172 // take advantage of builtin optimisations
173 sal_Int32 nMin = std::min(std::min(nStr1Len, nStr2Len), nShortenedLength);
174 sal_Int32 nRet = memcmp(pStr1, pStr2, nMin);
175 if (nRet == 0 && nShortenedLength > std::min(nStr1Len, nStr2Len))
176 return nStr1Len - nStr2Len;
177 return nRet;
178 #else
179 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
181 // take advantage of builtin optimisations
182 sal_Int32 nMin = std::min(std::min(nStr1Len, nStr2Len), nShortenedLength);
183 sal_Int32 nRet = wmemcmp(reinterpret_cast<wchar_t const *>(pStr1), reinterpret_cast<wchar_t const *>(pStr2), nMin);
184 if (nRet == 0 && nShortenedLength > std::min(nStr1Len, nStr2Len))
185 return nStr1Len - nStr2Len;
186 return nRet;
188 else
190 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
191 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
192 sal_Int32 nRet;
193 while ( (nShortenedLength > 0) &&
194 (pStr1 < pStr1End) && (pStr2 < pStr2End) )
196 nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr1 ))-
197 static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr2 ));
198 if ( nRet )
199 return nRet;
201 nShortenedLength--;
202 pStr1++;
203 pStr2++;
206 if ( nShortenedLength <= 0 )
207 return 0;
208 return nStr1Len - nStr2Len;
210 #endif
213 /* ----------------------------------------------------------------------- */
215 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( reverseCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
216 sal_Int32 nStr1Len,
217 const IMPL_RTL_STRCODE* pStr2,
218 sal_Int32 nStr2Len )
219 SAL_THROW_EXTERN_C()
221 assert(nStr1Len >= 0);
222 assert(nStr2Len >= 0);
223 const IMPL_RTL_STRCODE* pStr1Run = pStr1+nStr1Len;
224 const IMPL_RTL_STRCODE* pStr2Run = pStr2+nStr2Len;
225 sal_Int32 nRet;
226 while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
228 pStr1Run--;
229 pStr2Run--;
230 nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr1Run ))-
231 static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr2Run ));
232 if ( nRet )
233 return nRet;
236 return nStr1Len - nStr2Len;
239 /* ----------------------------------------------------------------------- */
241 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase )( const IMPL_RTL_STRCODE* pStr1,
242 const IMPL_RTL_STRCODE* pStr2 )
243 SAL_THROW_EXTERN_C()
245 assert(pStr1);
246 assert(pStr2);
247 sal_uInt32 c1;
250 c1 = IMPL_RTL_USTRCODE(*pStr1);
251 sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
252 c1, IMPL_RTL_USTRCODE(*pStr2));
253 if ( nRet != 0 )
254 return nRet;
256 pStr1++;
257 pStr2++;
259 while (c1);
261 return 0;
264 /* ----------------------------------------------------------------------- */
266 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
267 sal_Int32 nStr1Len,
268 const IMPL_RTL_STRCODE* pStr2,
269 sal_Int32 nStr2Len )
270 SAL_THROW_EXTERN_C()
272 assert(nStr1Len >= 0);
273 assert(nStr2Len >= 0);
274 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
275 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
276 while ( (pStr1 < pStr1End) && (pStr2 < pStr2End) )
278 sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
279 IMPL_RTL_USTRCODE(*pStr1), IMPL_RTL_USTRCODE(*pStr2));
280 if ( nRet != 0 )
281 return nRet;
283 pStr1++;
284 pStr2++;
287 return nStr1Len - nStr2Len;
290 /* ----------------------------------------------------------------------- */
292 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
293 sal_Int32 nStr1Len,
294 const IMPL_RTL_STRCODE* pStr2,
295 sal_Int32 nStr2Len,
296 sal_Int32 nShortenedLength )
297 SAL_THROW_EXTERN_C()
299 assert(nStr1Len >= 0);
300 assert(nStr2Len >= 0);
301 assert(nShortenedLength >= 0);
302 const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
303 const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
304 while ( (nShortenedLength > 0) &&
305 (pStr1 < pStr1End) && (pStr2 < pStr2End) )
307 sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
308 IMPL_RTL_USTRCODE(*pStr1), IMPL_RTL_USTRCODE(*pStr2));
309 if ( nRet != 0 )
310 return nRet;
312 nShortenedLength--;
313 pStr1++;
314 pStr2++;
317 if ( nShortenedLength <= 0 )
318 return 0;
319 return nStr1Len - nStr2Len;
322 /* ----------------------------------------------------------------------- */
324 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode )( const IMPL_RTL_STRCODE* pStr )
325 SAL_THROW_EXTERN_C()
327 return IMPL_RTL_STRNAME( hashCode_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
330 /* ----------------------------------------------------------------------- */
332 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode_WithLength )( const IMPL_RTL_STRCODE* pStr,
333 sal_Int32 nLen )
334 SAL_THROW_EXTERN_C()
336 assert(nLen >= 0);
337 sal_uInt32 h = static_cast<sal_uInt32>(nLen);
338 while ( nLen > 0 )
340 h = (h*37U) + IMPL_RTL_USTRCODE( *pStr );
341 pStr++;
342 nLen--;
344 return static_cast<sal_Int32>(h);
347 /* ----------------------------------------------------------------------- */
349 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar )( const IMPL_RTL_STRCODE* pStr,
350 IMPL_RTL_STRCODE c )
351 SAL_THROW_EXTERN_C()
353 assert(pStr);
354 #if !IMPL_RTL_IS_USTRING
355 // take advantage of builtin optimisations
356 const IMPL_RTL_STRCODE* p = strchr(pStr, c);
357 return p ? p - pStr : -1;
358 #else
359 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
361 // take advantage of builtin optimisations
362 wchar_t const * p = wcschr(reinterpret_cast<wchar_t const *>(pStr), static_cast<wchar_t>(c));
363 return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
365 else
367 const IMPL_RTL_STRCODE* pTempStr = pStr;
368 while ( *pTempStr )
370 if ( *pTempStr == c )
371 return pTempStr-pStr;
373 pTempStr++;
376 return -1;
378 #endif
381 /* ----------------------------------------------------------------------- */
383 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
384 sal_Int32 nLen,
385 IMPL_RTL_STRCODE c )
386 SAL_THROW_EXTERN_C()
388 // assert(nLen >= 0);
389 #if !IMPL_RTL_IS_USTRING
390 // take advantage of builtin optimisations
391 IMPL_RTL_STRCODE* p = static_cast<IMPL_RTL_STRCODE*>(std::memchr(const_cast<IMPL_RTL_STRCODE *>(pStr), c, nLen));
392 return p ? p - pStr : -1;
393 #else
394 const IMPL_RTL_STRCODE* pTempStr = pStr;
395 while ( nLen > 0 )
397 if ( *pTempStr == c )
398 return pTempStr-pStr;
400 pTempStr++;
401 nLen--;
404 return -1;
405 #endif
408 /* ----------------------------------------------------------------------- */
410 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar )( const IMPL_RTL_STRCODE* pStr,
411 IMPL_RTL_STRCODE c )
412 SAL_THROW_EXTERN_C()
414 assert(pStr);
415 #if !IMPL_RTL_IS_USTRING
416 // take advantage of builtin optimisations
417 const IMPL_RTL_STRCODE* p = strrchr(pStr, c);
418 return p ? p - pStr : -1;
419 #else
420 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
422 // take advantage of builtin optimisations
423 wchar_t const * p = wcsrchr(reinterpret_cast<wchar_t const *>(pStr), static_cast<wchar_t>(c));
424 return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
426 else
428 return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), c );
430 #endif
433 /* ----------------------------------------------------------------------- */
435 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
436 sal_Int32 nLen,
437 IMPL_RTL_STRCODE c )
438 SAL_THROW_EXTERN_C()
440 assert(nLen >= 0);
441 pStr += nLen;
442 while ( nLen > 0 )
444 nLen--;
445 pStr--;
447 if ( *pStr == c )
448 return nLen;
451 return -1;
454 /* ----------------------------------------------------------------------- */
456 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr )( const IMPL_RTL_STRCODE* pStr,
457 const IMPL_RTL_STRCODE* pSubStr )
458 SAL_THROW_EXTERN_C()
460 assert(pStr);
461 assert(pSubStr);
462 #if !IMPL_RTL_IS_USTRING
463 // take advantage of builtin optimisations
464 const IMPL_RTL_STRCODE* p = strstr(pStr, pSubStr);
465 return p ? p - pStr : -1;
466 #else
467 if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
469 // take advantage of builtin optimisations
470 wchar_t const * p = wcsstr(reinterpret_cast<wchar_t const *>(pStr), reinterpret_cast<wchar_t const *>(pSubStr));
471 return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
473 else
475 return IMPL_RTL_STRNAME( indexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
476 pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
478 #endif
481 /* ----------------------------------------------------------------------- */
483 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
484 sal_Int32 nStrLen,
485 const IMPL_RTL_STRCODE* pSubStr,
486 sal_Int32 nSubLen )
487 SAL_THROW_EXTERN_C()
489 assert(nStrLen >= 0);
490 assert(nSubLen >= 0);
491 /* faster search for a single character */
492 if ( nSubLen < 2 )
494 /* an empty SubString is always not findable */
495 if ( nSubLen == 1 )
497 IMPL_RTL_STRCODE c = *pSubStr;
498 const IMPL_RTL_STRCODE* pTempStr = pStr;
499 while ( nStrLen > 0 )
501 if ( *pTempStr == c )
502 return pTempStr-pStr;
504 pTempStr++;
505 nStrLen--;
509 else
511 const IMPL_RTL_STRCODE* pTempStr = pStr;
512 while ( nStrLen > 0 )
514 if ( *pTempStr == *pSubStr )
516 /* Compare SubString */
517 if ( nSubLen <= nStrLen )
519 const IMPL_RTL_STRCODE* pTempStr1 = pTempStr;
520 const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
521 sal_Int32 nTempLen = nSubLen;
522 while ( nTempLen )
524 if ( *pTempStr1 != *pTempStr2 )
525 break;
527 pTempStr1++;
528 pTempStr2++;
529 nTempLen--;
532 if ( !nTempLen )
533 return pTempStr-pStr;
535 else
536 break;
539 nStrLen--;
540 pTempStr++;
544 return -1;
547 /* ----------------------------------------------------------------------- */
549 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr )( const IMPL_RTL_STRCODE* pStr,
550 const IMPL_RTL_STRCODE* pSubStr )
551 SAL_THROW_EXTERN_C()
553 return IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
554 pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
557 /* ----------------------------------------------------------------------- */
559 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
560 sal_Int32 nStrLen,
561 const IMPL_RTL_STRCODE* pSubStr,
562 sal_Int32 nSubLen )
563 SAL_THROW_EXTERN_C()
565 assert(nStrLen >= 0);
566 assert(nSubLen >= 0);
567 /* faster search for a single character */
568 if ( nSubLen < 2 )
570 /* an empty SubString is always not findable */
571 if ( nSubLen == 1 )
573 IMPL_RTL_STRCODE c = *pSubStr;
574 pStr += nStrLen;
575 while ( nStrLen > 0 )
577 nStrLen--;
578 pStr--;
580 if ( *pStr == c )
581 return nStrLen;
585 else
587 pStr += nStrLen;
588 nStrLen -= nSubLen;
589 pStr -= nSubLen;
590 while ( nStrLen >= 0 )
592 const IMPL_RTL_STRCODE* pTempStr1 = pStr;
593 const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
594 sal_Int32 nTempLen = nSubLen;
595 while ( nTempLen )
597 if ( *pTempStr1 != *pTempStr2 )
598 break;
600 pTempStr1++;
601 pTempStr2++;
602 nTempLen--;
605 if ( !nTempLen )
606 return nStrLen;
608 nStrLen--;
609 pStr--;
613 return -1;
616 /* ----------------------------------------------------------------------- */
618 void SAL_CALL IMPL_RTL_STRNAME( replaceChar )( IMPL_RTL_STRCODE* pStr,
619 IMPL_RTL_STRCODE cOld,
620 IMPL_RTL_STRCODE cNew )
621 SAL_THROW_EXTERN_C()
623 assert(pStr);
624 while ( *pStr )
626 if ( *pStr == cOld )
627 *pStr = cNew;
629 pStr++;
633 /* ----------------------------------------------------------------------- */
635 void SAL_CALL IMPL_RTL_STRNAME( replaceChar_WithLength )( IMPL_RTL_STRCODE* pStr,
636 sal_Int32 nLen,
637 IMPL_RTL_STRCODE cOld,
638 IMPL_RTL_STRCODE cNew )
639 SAL_THROW_EXTERN_C()
641 assert(nLen >= 0);
642 while ( nLen > 0 )
644 if ( *pStr == cOld )
645 *pStr = cNew;
647 pStr++;
648 nLen--;
652 /* ----------------------------------------------------------------------- */
654 void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase )( IMPL_RTL_STRCODE* pStr )
655 SAL_THROW_EXTERN_C()
657 assert(pStr);
658 while ( *pStr )
660 *pStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pStr));
662 pStr++;
666 /* ----------------------------------------------------------------------- */
668 void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength )( IMPL_RTL_STRCODE* pStr,
669 sal_Int32 nLen )
670 SAL_THROW_EXTERN_C()
672 assert(nLen >= 0);
673 while ( nLen > 0 )
675 *pStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pStr));
677 pStr++;
678 nLen--;
682 /* ----------------------------------------------------------------------- */
684 void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase )( IMPL_RTL_STRCODE* pStr )
685 SAL_THROW_EXTERN_C()
687 assert(pStr);
688 while ( *pStr )
690 *pStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pStr));
692 pStr++;
696 /* ----------------------------------------------------------------------- */
698 void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength )( IMPL_RTL_STRCODE* pStr,
699 sal_Int32 nLen )
700 SAL_THROW_EXTERN_C()
702 assert(nLen >= 0);
703 while ( nLen > 0 )
705 *pStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pStr));
707 pStr++;
708 nLen--;
712 /* ----------------------------------------------------------------------- */
714 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim )( IMPL_RTL_STRCODE* pStr )
715 SAL_THROW_EXTERN_C()
717 return IMPL_RTL_STRNAME( trim_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
720 /* ----------------------------------------------------------------------- */
722 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim_WithLength )( IMPL_RTL_STRCODE* pStr, sal_Int32 nLen )
723 SAL_THROW_EXTERN_C()
725 assert(nLen >= 0);
726 sal_Int32 nPreSpaces = 0;
727 sal_Int32 nPostSpaces = 0;
728 sal_Int32 nIndex = nLen-1;
730 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nPreSpaces)) ) )
731 nPreSpaces++;
733 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nIndex)) ) )
735 nPostSpaces++;
736 nIndex--;
739 if ( nPostSpaces )
741 nLen -= nPostSpaces;
742 *(pStr+nLen) = 0;
745 if ( nPreSpaces )
747 nLen -= nPreSpaces;
748 memmove(pStr, pStr + nPreSpaces, nLen * sizeof(IMPL_RTL_STRCODE));
749 pStr += nLen;
750 *pStr = 0;
753 return nLen;
756 /* ----------------------------------------------------------------------- */
758 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfBoolean )( IMPL_RTL_STRCODE* pStr, sal_Bool b )
759 SAL_THROW_EXTERN_C()
761 assert(pStr);
762 if ( b )
764 *pStr = 't';
765 pStr++;
766 *pStr = 'r';
767 pStr++;
768 *pStr = 'u';
769 pStr++;
770 *pStr = 'e';
771 pStr++;
772 *pStr = 0;
773 return 4;
775 else
777 *pStr = 'f';
778 pStr++;
779 *pStr = 'a';
780 pStr++;
781 *pStr = 'l';
782 pStr++;
783 *pStr = 's';
784 pStr++;
785 *pStr = 'e';
786 pStr++;
787 *pStr = 0;
788 return 5;
792 /* ----------------------------------------------------------------------- */
794 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfChar )( IMPL_RTL_STRCODE* pStr,
795 IMPL_RTL_STRCODE c )
796 SAL_THROW_EXTERN_C()
798 assert(pStr);
799 *pStr++ = c;
800 *pStr = 0;
801 return 1;
804 /* ----------------------------------------------------------------------- */
806 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt32 )( IMPL_RTL_STRCODE* pStr,
807 sal_Int32 n,
808 sal_Int16 nRadix )
809 SAL_THROW_EXTERN_C()
811 assert(pStr);
812 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
813 sal_Char aBuf[RTL_STR_MAX_VALUEOFINT32];
814 sal_Char* pBuf = aBuf;
815 sal_Int32 nLen = 0;
816 sal_uInt32 nValue;
818 /* Radix must be valid */
819 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
820 nRadix = 10;
822 /* is value negative */
823 if ( n < 0 )
825 *pStr = '-';
826 pStr++;
827 nLen++;
828 nValue = n == SAL_MIN_INT32 ? static_cast<sal_uInt32>(n) : -n;
830 else
831 nValue = n;
833 /* create a recursive buffer with all values, except the last one */
836 sal_Char nDigit = static_cast<sal_Char>(nValue % nRadix);
837 nValue /= nRadix;
838 if ( nDigit > 9 )
839 *pBuf = (nDigit-10) + 'a';
840 else
841 *pBuf = (nDigit + '0' );
842 pBuf++;
844 while ( nValue > 0 );
846 /* copy the values in the right direction into the destination buffer */
849 pBuf--;
850 *pStr = *pBuf;
851 pStr++;
852 nLen++;
854 while ( pBuf != aBuf );
855 *pStr = 0;
857 return nLen;
860 /* ----------------------------------------------------------------------- */
862 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt64 )( IMPL_RTL_STRCODE* pStr,
863 sal_Int64 n,
864 sal_Int16 nRadix )
865 SAL_THROW_EXTERN_C()
867 assert(pStr);
868 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
869 sal_Char aBuf[RTL_STR_MAX_VALUEOFINT64];
870 sal_Char* pBuf = aBuf;
871 sal_Int32 nLen = 0;
872 sal_uInt64 nValue;
874 /* Radix must be valid */
875 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
876 nRadix = 10;
878 /* is value negative */
879 if ( n < 0 )
881 *pStr = '-';
882 pStr++;
883 nLen++;
884 nValue = n == SAL_MIN_INT64 ? static_cast<sal_uInt64>(n) : -n;
886 else
887 nValue = n;
889 /* create a recursive buffer with all values, except the last one */
892 sal_Char nDigit = static_cast<sal_Char>(nValue % nRadix);
893 nValue /= nRadix;
894 if ( nDigit > 9 )
895 *pBuf = (nDigit-10) + 'a';
896 else
897 *pBuf = (nDigit + '0' );
898 pBuf++;
900 while ( nValue > 0 );
902 /* copy the values in the right direction into the destination buffer */
905 pBuf--;
906 *pStr = *pBuf;
907 pStr++;
908 nLen++;
910 while ( pBuf != aBuf );
911 *pStr = 0;
913 return nLen;
916 /* ----------------------------------------------------------------------- */
918 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfUInt64 )( IMPL_RTL_STRCODE* pStr,
919 sal_uInt64 n,
920 sal_Int16 nRadix )
921 SAL_THROW_EXTERN_C()
923 assert(pStr);
924 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
925 sal_Char aBuf[RTL_STR_MAX_VALUEOFUINT64];
926 sal_Char* pBuf = aBuf;
927 sal_Int32 nLen = 0;
928 sal_uInt64 nValue;
930 /* Radix must be valid */
931 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
932 nRadix = 10;
934 nValue = n;
936 /* create a recursive buffer with all values, except the last one */
939 sal_Char nDigit = static_cast<sal_Char>(nValue % nRadix);
940 nValue /= nRadix;
941 if ( nDigit > 9 )
942 *pBuf = (nDigit-10) + 'a';
943 else
944 *pBuf = (nDigit + '0' );
945 pBuf++;
947 while ( nValue > 0 );
949 /* copy the values in the right direction into the destination buffer */
952 pBuf--;
953 *pStr = *pBuf;
954 pStr++;
955 nLen++;
957 while ( pBuf != aBuf );
958 *pStr = 0;
960 return nLen;
963 /* ----------------------------------------------------------------------- */
965 sal_Bool SAL_CALL IMPL_RTL_STRNAME( toBoolean )( const IMPL_RTL_STRCODE* pStr )
966 SAL_THROW_EXTERN_C()
968 assert(pStr);
969 if ( *pStr == '1' )
970 return true;
972 if ( (*pStr == 'T') || (*pStr == 't') )
974 pStr++;
975 if ( (*pStr == 'R') || (*pStr == 'r') )
977 pStr++;
978 if ( (*pStr == 'U') || (*pStr == 'u') )
980 pStr++;
981 if ( (*pStr == 'E') || (*pStr == 'e') )
982 return true;
987 return false;
990 /* ----------------------------------------------------------------------- */
991 namespace {
992 template<typename T, typename U> T IMPL_RTL_STRNAME( toInt )( const IMPL_RTL_STRCODE* pStr,
993 sal_Int16 nRadix )
995 static_assert(std::numeric_limits<T>::is_signed, "is signed");
996 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
997 bool bNeg;
998 sal_Int16 nDigit;
999 U n = 0;
1001 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
1002 nRadix = 10;
1004 /* Skip whitespaces */
1005 while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
1006 pStr++;
1008 if ( *pStr == '-' )
1010 bNeg = true;
1011 pStr++;
1013 else
1015 if ( *pStr == '+' )
1016 pStr++;
1017 bNeg = false;
1020 T nDiv;
1021 sal_Int16 nMod;
1022 if ( bNeg )
1024 nDiv = std::numeric_limits<T>::min() / nRadix;
1025 nMod = std::numeric_limits<T>::min() % nRadix;
1026 // Cater for C++03 implementations that round the quotient down
1027 // instead of truncating towards zero as mandated by C++11:
1028 if ( nMod > 0 )
1030 --nDiv;
1031 nMod -= nRadix;
1033 nDiv = -nDiv;
1034 nMod = -nMod;
1036 else
1038 nDiv = std::numeric_limits<T>::max() / nRadix;
1039 nMod = std::numeric_limits<T>::max() % nRadix;
1042 while ( *pStr )
1044 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
1045 if ( nDigit < 0 )
1046 break;
1047 assert(nDiv > 0);
1048 if( static_cast<U>( nMod < nDigit ? nDiv-1 : nDiv ) < n )
1049 return 0;
1051 n *= nRadix;
1052 n += nDigit;
1054 pStr++;
1057 if ( bNeg )
1058 return n == static_cast<U>(std::numeric_limits<T>::min())
1059 ? std::numeric_limits<T>::min() : -static_cast<T>(n);
1060 else
1061 return static_cast<T>(n);
1065 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr,
1066 sal_Int16 nRadix )
1067 SAL_THROW_EXTERN_C()
1069 assert(pStr);
1070 return IMPL_RTL_STRNAME( toInt )<sal_Int32, sal_uInt32>(pStr, nRadix);
1073 sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr,
1074 sal_Int16 nRadix )
1075 SAL_THROW_EXTERN_C()
1077 assert(pStr);
1078 return IMPL_RTL_STRNAME( toInt )<sal_Int64, sal_uInt64>(pStr, nRadix);
1081 /* ----------------------------------------------------------------------- */
1082 namespace {
1083 template <typename T> T IMPL_RTL_STRNAME( toUInt )( const IMPL_RTL_STRCODE* pStr,
1084 sal_Int16 nRadix )
1086 static_assert(!std::numeric_limits<T>::is_signed, "is not signed");
1087 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
1088 sal_Int16 nDigit;
1089 T n = 0;
1091 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
1092 nRadix = 10;
1094 /* Skip whitespaces */
1095 while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
1096 ++pStr;
1098 // skip optional explicit sign
1099 if ( *pStr == '+' )
1100 ++pStr;
1102 T nDiv = std::numeric_limits<T>::max() / nRadix;
1103 sal_Int16 nMod = std::numeric_limits<T>::max() % nRadix;
1104 while ( *pStr )
1106 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
1107 if ( nDigit < 0 )
1108 break;
1109 if( ( nMod < nDigit ? nDiv-1 : nDiv ) < n )
1110 return 0;
1112 n *= nRadix;
1113 n += nDigit;
1115 ++pStr;
1118 return n;
1122 sal_uInt32 SAL_CALL IMPL_RTL_STRNAME( toUInt32 )( const IMPL_RTL_STRCODE* pStr,
1123 sal_Int16 nRadix )
1124 SAL_THROW_EXTERN_C()
1126 assert(pStr);
1127 return IMPL_RTL_STRNAME( toUInt )<sal_uInt32>(pStr, nRadix);
1130 sal_uInt64 SAL_CALL IMPL_RTL_STRNAME( toUInt64 )( const IMPL_RTL_STRCODE* pStr,
1131 sal_Int16 nRadix )
1132 SAL_THROW_EXTERN_C()
1134 assert(pStr);
1135 return IMPL_RTL_STRNAME( toUInt )<sal_uInt64>(pStr, nRadix);
1138 /* ======================================================================= */
1139 /* Internal String-Class help functions */
1140 /* ======================================================================= */
1142 IMPL_RTL_STRINGDATA* IMPL_RTL_STRINGNAME( ImplAlloc )( sal_Int32 nLen )
1144 IMPL_RTL_STRINGDATA * pData
1145 = (sal::static_int_cast< sal_uInt32 >(nLen)
1146 <= ((SAL_MAX_UINT32 - sizeof (IMPL_RTL_STRINGDATA))
1147 / sizeof (IMPL_RTL_STRCODE)))
1148 ? static_cast<IMPL_RTL_STRINGDATA *>(rtl_allocateString(
1149 sizeof (IMPL_RTL_STRINGDATA) + nLen * sizeof (IMPL_RTL_STRCODE)))
1150 : nullptr;
1151 if (pData != nullptr) {
1152 pData->refCount = 1;
1153 pData->length = nLen;
1154 pData->buffer[nLen] = 0;
1156 return pData;
1159 /* ----------------------------------------------------------------------- */
1161 static IMPL_RTL_STRCODE* IMPL_RTL_STRINGNAME( ImplNewCopy )( IMPL_RTL_STRINGDATA** ppThis,
1162 IMPL_RTL_STRINGDATA* pStr,
1163 sal_Int32 nCount )
1165 assert(nCount >= 0);
1166 IMPL_RTL_STRCODE* pDest;
1167 const IMPL_RTL_STRCODE* pSrc;
1168 IMPL_RTL_STRINGDATA* pData = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1169 OSL_ASSERT(pData != nullptr);
1171 pDest = pData->buffer;
1172 pSrc = pStr->buffer;
1174 memcpy( pDest, pSrc, nCount * sizeof(IMPL_RTL_STRCODE));
1176 *ppThis = pData;
1178 RTL_LOG_STRING_NEW( pData );
1179 return pDest + nCount;
1182 /* ======================================================================= */
1183 /* String-Class functions */
1184 /* ======================================================================= */
1186 namespace {
1188 void IMPL_RTL_ACQUIRE(IMPL_RTL_STRINGDATA * pThis)
1190 if (!SAL_STRING_IS_STATIC (pThis))
1191 osl_atomic_increment( &((pThis)->refCount) );
1196 /* ----------------------------------------------------------------------- */
1198 void SAL_CALL IMPL_RTL_STRINGNAME( acquire )( IMPL_RTL_STRINGDATA* pThis )
1199 SAL_THROW_EXTERN_C()
1201 IMPL_RTL_ACQUIRE( pThis );
1204 /* ----------------------------------------------------------------------- */
1206 void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis )
1207 SAL_THROW_EXTERN_C()
1209 if (SAL_UNLIKELY(SAL_STRING_IS_STATIC (pThis)))
1210 return;
1212 /* OString doesn't have an 'intern' */
1213 #if IMPL_RTL_IS_USTRING
1214 if (SAL_STRING_IS_INTERN (pThis))
1216 internRelease (pThis);
1217 return;
1219 #endif
1221 if ( !osl_atomic_decrement( &(pThis->refCount) ) )
1223 RTL_LOG_STRING_DELETE( pThis );
1224 rtl_freeString( pThis );
1228 /* ----------------------------------------------------------------------- */
1230 void SAL_CALL IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA** ppThis )
1231 SAL_THROW_EXTERN_C()
1233 assert(ppThis);
1234 if ( *ppThis)
1235 IMPL_RTL_STRINGNAME( release )( *ppThis );
1237 *ppThis = const_cast<IMPL_RTL_STRINGDATA*>(&IMPL_RTL_EMPTYSTRING);
1240 /* ----------------------------------------------------------------------- */
1242 IMPL_RTL_STRINGDATA* SAL_CALL IMPL_RTL_STRINGNAME( alloc )( sal_Int32 nLen )
1243 SAL_THROW_EXTERN_C()
1245 assert(nLen >= 0);
1246 return IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1249 /* ----------------------------------------------------------------------- */
1251 void SAL_CALL IMPL_RTL_STRINGNAME( new_WithLength )( IMPL_RTL_STRINGDATA** ppThis, sal_Int32 nLen )
1252 SAL_THROW_EXTERN_C()
1254 assert(ppThis);
1255 assert(nLen >= 0);
1256 if ( nLen <= 0 )
1257 IMPL_RTL_STRINGNAME( new )( ppThis );
1258 else
1260 if ( *ppThis)
1261 IMPL_RTL_STRINGNAME( release )( *ppThis );
1263 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1264 OSL_ASSERT(*ppThis != nullptr);
1265 (*ppThis)->length = 0;
1267 IMPL_RTL_STRCODE* pTempStr = (*ppThis)->buffer;
1268 memset(pTempStr, 0, nLen*sizeof(IMPL_RTL_STRCODE));
1272 /* ----------------------------------------------------------------------- */
1274 void SAL_CALL IMPL_RTL_STRINGNAME( newFromString )( IMPL_RTL_STRINGDATA** ppThis,
1275 const IMPL_RTL_STRINGDATA* pStr )
1276 SAL_THROW_EXTERN_C()
1278 assert(ppThis);
1279 assert(pStr);
1280 IMPL_RTL_STRINGDATA* pOrg;
1282 if ( !pStr->length )
1284 IMPL_RTL_STRINGNAME( new )( ppThis );
1285 return;
1288 pOrg = *ppThis;
1289 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1290 OSL_ASSERT(*ppThis != nullptr);
1291 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer, pStr->length );
1292 RTL_LOG_STRING_NEW( *ppThis );
1294 /* must be done last, if pStr == *ppThis */
1295 if ( pOrg )
1296 IMPL_RTL_STRINGNAME( release )( pOrg );
1299 /* ----------------------------------------------------------------------- */
1301 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr )( IMPL_RTL_STRINGDATA** ppThis,
1302 const IMPL_RTL_STRCODE* pCharStr )
1303 SAL_THROW_EXTERN_C()
1305 assert(ppThis);
1306 IMPL_RTL_STRINGDATA* pOrg;
1307 sal_Int32 nLen;
1309 if ( pCharStr )
1311 nLen = IMPL_RTL_STRNAME( getLength )( pCharStr );
1313 else
1314 nLen = 0;
1316 if ( !nLen )
1318 IMPL_RTL_STRINGNAME( new )( ppThis );
1319 return;
1322 pOrg = *ppThis;
1323 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1324 OSL_ASSERT(*ppThis != nullptr);
1325 rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
1326 RTL_LOG_STRING_NEW( *ppThis );
1328 /* must be done last, if pCharStr == *ppThis */
1329 if ( pOrg )
1330 IMPL_RTL_STRINGNAME( release )( pOrg );
1333 /* ----------------------------------------------------------------------- */
1335 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA** ppThis,
1336 const IMPL_RTL_STRCODE* pCharStr,
1337 sal_Int32 nLen )
1338 SAL_THROW_EXTERN_C()
1340 assert(ppThis);
1341 assert(nLen >= 0);
1342 IMPL_RTL_STRINGDATA* pOrg;
1344 if ( !pCharStr || (nLen <= 0) )
1346 IMPL_RTL_STRINGNAME( new )( ppThis );
1347 return;
1350 pOrg = *ppThis;
1351 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1352 OSL_ASSERT(*ppThis != nullptr);
1353 rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
1355 RTL_LOG_STRING_NEW( *ppThis );
1357 /* must be done last, if pCharStr == *ppThis */
1358 if ( pOrg )
1359 IMPL_RTL_STRINGNAME( release )( pOrg );
1362 /* ----------------------------------------------------------------------- */
1364 void SAL_CALL IMPL_RTL_STRINGNAME( newFromSubString )( IMPL_RTL_STRINGDATA** ppThis,
1365 const IMPL_RTL_STRINGDATA* pFrom,
1366 sal_Int32 beginIndex,
1367 sal_Int32 count )
1368 SAL_THROW_EXTERN_C()
1370 assert(ppThis);
1371 if ( beginIndex == 0 && count == pFrom->length )
1373 IMPL_RTL_STRINGNAME( assign )( ppThis, const_cast< IMPL_RTL_STRINGDATA * >( pFrom ) );
1374 return;
1376 if ( count < 0 || beginIndex < 0 || beginIndex + count > pFrom->length )
1378 assert(false); // fail fast at least in debug builds
1379 IMPL_RTL_STRINGNAME( newFromLiteral )( ppThis, "!!br0ken!!", 10, 0 );
1380 return;
1383 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pFrom->buffer + beginIndex, count );
1386 /* ----------------------------------------------------------------------- */
1388 // Used when creating from string literals.
1389 void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral )( IMPL_RTL_STRINGDATA** ppThis,
1390 const sal_Char* pCharStr,
1391 sal_Int32 nLen,
1392 sal_Int32 allocExtra )
1393 SAL_THROW_EXTERN_C()
1395 assert(ppThis);
1396 assert(nLen >= 0);
1397 assert(allocExtra >= 0);
1398 if ( nLen + allocExtra == 0 )
1400 IMPL_RTL_STRINGNAME( new )( ppThis );
1401 return;
1404 if ( *ppThis )
1405 IMPL_RTL_STRINGNAME( release )( *ppThis );
1407 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen + allocExtra );
1408 assert( *ppThis != nullptr );
1410 (*ppThis)->length = nLen; // fix after possible allocExtra != 0
1411 (*ppThis)->buffer[nLen] = 0;
1412 IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer;
1413 sal_Int32 nCount;
1414 for( nCount = nLen; nCount > 0; --nCount )
1416 #if IMPL_RTL_IS_USTRING
1417 assert(static_cast<unsigned char>(*pCharStr) < 0x80); // ASCII range
1418 #endif
1419 SAL_WARN_IF( (static_cast<unsigned char>(*pCharStr)) == '\0', "rtl.string",
1420 "rtl_uString_newFromLiteral - Found embedded \\0 character" );
1422 *pBuffer = *pCharStr;
1423 pBuffer++;
1424 pCharStr++;
1427 RTL_LOG_STRING_NEW( *ppThis );
1430 /* ----------------------------------------------------------------------- */
1432 void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis,
1433 IMPL_RTL_STRINGDATA* pStr )
1434 SAL_THROW_EXTERN_C()
1436 assert(ppThis);
1437 /* must be done at first, if pStr == *ppThis */
1438 IMPL_RTL_ACQUIRE( pStr );
1440 if ( *ppThis )
1441 IMPL_RTL_STRINGNAME( release )( *ppThis );
1443 *ppThis = pStr;
1446 /* ----------------------------------------------------------------------- */
1448 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getLength )( const IMPL_RTL_STRINGDATA* pThis )
1449 SAL_THROW_EXTERN_C()
1451 assert(pThis);
1452 return pThis->length;
1455 /* ----------------------------------------------------------------------- */
1457 IMPL_RTL_STRCODE* SAL_CALL IMPL_RTL_STRINGNAME( getStr )( IMPL_RTL_STRINGDATA * pThis )
1458 SAL_THROW_EXTERN_C()
1460 assert(pThis);
1461 return pThis->buffer;
1464 /* ----------------------------------------------------------------------- */
1466 void SAL_CALL IMPL_RTL_STRINGNAME( newConcat )( IMPL_RTL_STRINGDATA** ppThis,
1467 IMPL_RTL_STRINGDATA* pLeft,
1468 IMPL_RTL_STRINGDATA* pRight )
1469 SAL_THROW_EXTERN_C()
1471 assert(ppThis);
1472 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1474 /* Test for 0-Pointer - if not, change newReplaceStrAt! */
1475 if ( !pRight || !pRight->length )
1477 *ppThis = pLeft;
1478 IMPL_RTL_ACQUIRE( pLeft );
1480 else if ( !pLeft || !pLeft->length )
1482 *ppThis = pRight;
1483 IMPL_RTL_ACQUIRE( pRight );
1485 else if (pLeft->length
1486 > std::numeric_limits<sal_Int32>::max() - pRight->length)
1488 *ppThis = nullptr;
1490 else
1492 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( pLeft->length + pRight->length );
1493 OSL_ASSERT(pTempStr != nullptr);
1494 *ppThis = pTempStr;
1495 if (*ppThis != nullptr) {
1496 rtl_str_ImplCopy( pTempStr->buffer, pLeft->buffer, pLeft->length );
1497 rtl_str_ImplCopy( pTempStr->buffer+pLeft->length, pRight->buffer, pRight->length );
1499 RTL_LOG_STRING_NEW( *ppThis );
1503 /* must be done last, if left or right == *ppThis */
1504 if ( pOrg )
1505 IMPL_RTL_STRINGNAME( release )( pOrg );
1508 /* ----------------------------------------------------------------------- */
1510 void SAL_CALL IMPL_RTL_STRINGNAME( ensureCapacity )( IMPL_RTL_STRINGDATA** ppThis,
1511 sal_Int32 size )
1512 SAL_THROW_EXTERN_C()
1514 assert(ppThis);
1515 IMPL_RTL_STRINGDATA* const pOrg = *ppThis;
1516 if ( pOrg->refCount == 1 && pOrg->length >= size )
1517 return;
1518 assert( pOrg->length <= size ); // do not truncate
1519 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( size );
1520 rtl_str_ImplCopy( pTempStr->buffer, pOrg->buffer, pOrg->length );
1521 // right now the length is still the same as of the original
1522 pTempStr->length = pOrg->length;
1523 pTempStr->buffer[ pOrg->length ] = '\0';
1524 *ppThis = pTempStr;
1525 RTL_LOG_STRING_NEW( *ppThis );
1527 IMPL_RTL_STRINGNAME( release )( pOrg );
1530 /* ----------------------------------------------------------------------- */
1532 void SAL_CALL IMPL_RTL_STRINGNAME( newReplaceStrAt )( IMPL_RTL_STRINGDATA** ppThis,
1533 IMPL_RTL_STRINGDATA* pStr,
1534 sal_Int32 nIndex,
1535 sal_Int32 nCount,
1536 IMPL_RTL_STRINGDATA* pNewSubStr )
1537 SAL_THROW_EXTERN_C()
1539 assert(ppThis);
1540 assert(nIndex >= 0 && nIndex <= pStr->length);
1541 assert(nCount >= 0);
1542 assert(nCount <= pStr->length - nIndex);
1543 /* Append? */
1544 if ( nIndex >= pStr->length )
1546 /* newConcat test, if pNewSubStr is 0 */
1547 IMPL_RTL_STRINGNAME( newConcat )( ppThis, pStr, pNewSubStr );
1548 return;
1551 /* negative index? */
1552 if ( nIndex < 0 )
1554 nCount -= nIndex;
1555 nIndex = 0;
1558 /* not more than the String length could be deleted */
1559 if ( nCount >= pStr->length-nIndex )
1561 nCount = pStr->length-nIndex;
1563 /* Assign of NewSubStr? */
1564 if ( !nIndex && (nCount >= pStr->length) )
1566 if ( !pNewSubStr )
1567 IMPL_RTL_STRINGNAME( new )( ppThis );
1568 else
1569 IMPL_RTL_STRINGNAME( assign )( ppThis, pNewSubStr );
1570 return;
1574 /* Assign of Str? */
1575 if ( !nCount && (!pNewSubStr || !pNewSubStr->length) )
1577 IMPL_RTL_STRINGNAME( assign )( ppThis, pStr );
1578 return;
1581 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1582 IMPL_RTL_STRCODE* pBuffer;
1583 sal_Int32 nNewLen;
1585 /* Calculate length of the new string */
1586 nNewLen = pStr->length-nCount;
1587 if ( pNewSubStr )
1588 nNewLen += pNewSubStr->length;
1590 /* Alloc New Buffer */
1591 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
1592 OSL_ASSERT(*ppThis != nullptr);
1593 pBuffer = (*ppThis)->buffer;
1594 if ( nIndex )
1596 rtl_str_ImplCopy( pBuffer, pStr->buffer, nIndex );
1597 pBuffer += nIndex;
1599 if ( pNewSubStr && pNewSubStr->length )
1601 rtl_str_ImplCopy( pBuffer, pNewSubStr->buffer, pNewSubStr->length );
1602 pBuffer += pNewSubStr->length;
1604 rtl_str_ImplCopy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount );
1606 RTL_LOG_STRING_NEW( *ppThis );
1607 /* must be done last, if pStr or pNewSubStr == *ppThis */
1608 if ( pOrg )
1609 IMPL_RTL_STRINGNAME( release )( pOrg );
1612 /* ----------------------------------------------------------------------- */
1614 void SAL_CALL IMPL_RTL_STRINGNAME( newReplace )( IMPL_RTL_STRINGDATA** ppThis,
1615 IMPL_RTL_STRINGDATA* pStr,
1616 IMPL_RTL_STRCODE cOld,
1617 IMPL_RTL_STRCODE cNew )
1618 SAL_THROW_EXTERN_C()
1620 assert(ppThis);
1621 assert(pStr);
1622 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1623 bool bChanged = false;
1624 sal_Int32 nLen = pStr->length;
1625 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1627 while ( nLen > 0 )
1629 if ( *pCharStr == cOld )
1631 /* Copy String */
1632 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1634 /* replace/copy rest of the string */
1635 if ( pNewCharStr )
1637 *pNewCharStr = cNew;
1638 pNewCharStr++;
1639 pCharStr++;
1640 nLen--;
1642 while ( nLen > 0 )
1644 if ( *pCharStr == cOld )
1645 *pNewCharStr = cNew;
1646 else
1647 *pNewCharStr = *pCharStr;
1649 pNewCharStr++;
1650 pCharStr++;
1651 nLen--;
1655 bChanged = true;
1656 break;
1659 pCharStr++;
1660 nLen--;
1663 if ( !bChanged )
1665 *ppThis = pStr;
1666 IMPL_RTL_ACQUIRE( pStr );
1669 RTL_LOG_STRING_NEW( *ppThis );
1670 /* must be done last, if pStr == *ppThis */
1671 if ( pOrg )
1672 IMPL_RTL_STRINGNAME( release )( pOrg );
1675 /* ----------------------------------------------------------------------- */
1677 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiLowerCase )( IMPL_RTL_STRINGDATA** ppThis,
1678 IMPL_RTL_STRINGDATA* pStr )
1679 SAL_THROW_EXTERN_C()
1681 assert(ppThis);
1682 assert(pStr);
1683 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1684 bool bChanged = false;
1685 sal_Int32 nLen = pStr->length;
1686 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1688 while ( nLen > 0 )
1690 if ( rtl::isAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr)) )
1692 /* Copy String */
1693 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1695 /* replace/copy rest of the string */
1696 if ( pNewCharStr )
1698 *pNewCharStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr));
1699 pNewCharStr++;
1700 pCharStr++;
1701 nLen--;
1703 while ( nLen > 0 )
1705 *pNewCharStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr));
1707 pNewCharStr++;
1708 pCharStr++;
1709 nLen--;
1713 bChanged = true;
1714 break;
1717 pCharStr++;
1718 nLen--;
1721 if ( !bChanged )
1723 *ppThis = pStr;
1724 IMPL_RTL_ACQUIRE( pStr );
1727 RTL_LOG_STRING_NEW( *ppThis );
1728 /* must be done last, if pStr == *ppThis */
1729 if ( pOrg )
1730 IMPL_RTL_STRINGNAME( release )( pOrg );
1733 /* ----------------------------------------------------------------------- */
1735 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiUpperCase )( IMPL_RTL_STRINGDATA** ppThis,
1736 IMPL_RTL_STRINGDATA* pStr )
1737 SAL_THROW_EXTERN_C()
1739 assert(ppThis);
1740 assert(pStr);
1741 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1742 bool bChanged = false;
1743 sal_Int32 nLen = pStr->length;
1744 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1746 while ( nLen > 0 )
1748 if ( rtl::isAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr)) )
1750 /* Copy String */
1751 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1753 /* replace/copy rest of the string */
1754 if ( pNewCharStr )
1756 *pNewCharStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr));
1757 pNewCharStr++;
1758 pCharStr++;
1759 nLen--;
1761 while ( nLen > 0 )
1763 *pNewCharStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr));
1765 pNewCharStr++;
1766 pCharStr++;
1767 nLen--;
1771 bChanged = true;
1772 break;
1775 pCharStr++;
1776 nLen--;
1779 if ( !bChanged )
1781 *ppThis = pStr;
1782 IMPL_RTL_ACQUIRE( pStr );
1785 RTL_LOG_STRING_NEW( *ppThis );
1786 /* must be done last, if pStr == *ppThis */
1787 if ( pOrg )
1788 IMPL_RTL_STRINGNAME( release )( pOrg );
1791 /* ----------------------------------------------------------------------- */
1793 void SAL_CALL IMPL_RTL_STRINGNAME( newTrim )( IMPL_RTL_STRINGDATA** ppThis,
1794 IMPL_RTL_STRINGDATA* pStr )
1795 SAL_THROW_EXTERN_C()
1797 assert(ppThis);
1798 assert(pStr);
1799 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1800 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1801 sal_Int32 nPreSpaces = 0;
1802 sal_Int32 nPostSpaces = 0;
1803 sal_Int32 nLen = pStr->length;
1804 sal_Int32 nIndex = nLen-1;
1806 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nPreSpaces)) ) )
1807 nPreSpaces++;
1809 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nIndex)) ) )
1811 nPostSpaces++;
1812 nIndex--;
1815 if ( !nPreSpaces && !nPostSpaces )
1817 *ppThis = pStr;
1818 IMPL_RTL_ACQUIRE( pStr );
1820 else
1822 nLen -= nPostSpaces+nPreSpaces;
1823 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1824 assert(*ppThis);
1825 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer+nPreSpaces, nLen );
1828 RTL_LOG_STRING_NEW( *ppThis );
1829 /* must be done last, if pStr == *ppThis */
1830 if ( pOrg )
1831 IMPL_RTL_STRINGNAME( release )( pOrg );
1834 /* ----------------------------------------------------------------------- */
1836 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getToken )( IMPL_RTL_STRINGDATA** ppThis,
1837 IMPL_RTL_STRINGDATA* pStr,
1838 sal_Int32 nToken,
1839 IMPL_RTL_STRCODE cTok,
1840 sal_Int32 nIndex )
1841 SAL_THROW_EXTERN_C()
1843 assert(ppThis);
1844 assert(pStr);
1845 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1846 const IMPL_RTL_STRCODE* pCharStrStart;
1847 const IMPL_RTL_STRCODE* pOrgCharStr;
1848 sal_Int32 nLen = pStr->length-nIndex;
1849 sal_Int32 nTokCount = 0;
1851 // Set ppThis to an empty string and return -1 if either nToken or nIndex is
1852 // negative:
1853 if (nIndex < 0)
1854 nToken = -1;
1856 pCharStr += nIndex;
1857 pOrgCharStr = pCharStr;
1858 pCharStrStart = pCharStr;
1859 while ( nLen > 0 )
1861 if ( *pCharStr == cTok )
1863 nTokCount++;
1865 if ( nTokCount == nToken )
1866 pCharStrStart = pCharStr+1;
1867 else
1869 if ( nTokCount > nToken )
1870 break;
1874 pCharStr++;
1875 nLen--;
1878 if ( (nToken < 0) || (nTokCount < nToken) || (pCharStr == pCharStrStart) )
1880 IMPL_RTL_STRINGNAME( new )( ppThis );
1881 if( (nToken < 0) || (nTokCount < nToken ) )
1882 return -1;
1883 else if( nLen > 0 )
1884 return nIndex+(pCharStr-pOrgCharStr)+1;
1885 else return -1;
1887 else
1889 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pCharStrStart, pCharStr-pCharStrStart );
1890 if ( nLen )
1891 return nIndex+(pCharStr-pOrgCharStr)+1;
1892 else
1893 return -1;
1897 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */