Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sal / rtl / strtmpl.cxx
blob4e6035d478e27cf182e4a9ec31ebf4cb5006f20e
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_WithLength )( const IMPL_RTL_STRCODE* pStr,
993 sal_Int16 nRadix,
994 sal_Int32 nStrLength )
996 static_assert(std::numeric_limits<T>::is_signed, "is signed");
997 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
998 assert( nStrLength >= 0 );
999 bool bNeg;
1000 sal_Int16 nDigit;
1001 U n = 0;
1002 const IMPL_RTL_STRCODE* pEnd = pStr + nStrLength;
1004 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
1005 nRadix = 10;
1007 /* Skip whitespaces */
1008 while ( pStr != pEnd && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
1009 pStr++;
1011 if ( *pStr == '-' )
1013 bNeg = true;
1014 pStr++;
1016 else
1018 if ( *pStr == '+' )
1019 pStr++;
1020 bNeg = false;
1023 T nDiv;
1024 sal_Int16 nMod;
1025 if ( bNeg )
1027 nDiv = std::numeric_limits<T>::min() / nRadix;
1028 nMod = std::numeric_limits<T>::min() % nRadix;
1029 // Cater for C++03 implementations that round the quotient down
1030 // instead of truncating towards zero as mandated by C++11:
1031 if ( nMod > 0 )
1033 --nDiv;
1034 nMod -= nRadix;
1036 nDiv = -nDiv;
1037 nMod = -nMod;
1039 else
1041 nDiv = std::numeric_limits<T>::max() / nRadix;
1042 nMod = std::numeric_limits<T>::max() % nRadix;
1045 while ( pStr != pEnd )
1047 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
1048 if ( nDigit < 0 )
1049 break;
1050 assert(nDiv > 0);
1051 if( static_cast<U>( nMod < nDigit ? nDiv-1 : nDiv ) < n )
1052 return 0;
1054 n *= nRadix;
1055 n += nDigit;
1057 pStr++;
1060 if ( bNeg )
1061 return n == static_cast<U>(std::numeric_limits<T>::min())
1062 ? std::numeric_limits<T>::min() : -static_cast<T>(n);
1063 else
1064 return static_cast<T>(n);
1068 sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr,
1069 sal_Int16 nRadix )
1070 SAL_THROW_EXTERN_C()
1072 assert(pStr);
1073 return IMPL_RTL_STRNAME( toInt_WithLength )<sal_Int32, sal_uInt32>(pStr, nRadix, IMPL_RTL_STRNAME( getLength )(pStr));
1076 sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr,
1077 sal_Int16 nRadix )
1078 SAL_THROW_EXTERN_C()
1080 assert(pStr);
1081 return IMPL_RTL_STRNAME( toInt_WithLength )<sal_Int64, sal_uInt64>(pStr, nRadix, IMPL_RTL_STRNAME( getLength )(pStr));
1084 sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64_WithLength )( const IMPL_RTL_STRCODE* pStr,
1085 sal_Int16 nRadix,
1086 sal_Int32 nStrLength)
1087 SAL_THROW_EXTERN_C()
1089 assert(pStr);
1090 return IMPL_RTL_STRNAME( toInt_WithLength )<sal_Int64, sal_uInt64>(pStr, nRadix, nStrLength);
1093 /* ----------------------------------------------------------------------- */
1094 namespace {
1095 template <typename T> T IMPL_RTL_STRNAME( toUInt )( const IMPL_RTL_STRCODE* pStr,
1096 sal_Int16 nRadix )
1098 static_assert(!std::numeric_limits<T>::is_signed, "is not signed");
1099 assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
1100 sal_Int16 nDigit;
1101 T n = 0;
1103 if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
1104 nRadix = 10;
1106 /* Skip whitespaces */
1107 while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
1108 ++pStr;
1110 // skip optional explicit sign
1111 if ( *pStr == '+' )
1112 ++pStr;
1114 T nDiv = std::numeric_limits<T>::max() / nRadix;
1115 sal_Int16 nMod = std::numeric_limits<T>::max() % nRadix;
1116 while ( *pStr )
1118 nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
1119 if ( nDigit < 0 )
1120 break;
1121 if( ( nMod < nDigit ? nDiv-1 : nDiv ) < n )
1122 return 0;
1124 n *= nRadix;
1125 n += nDigit;
1127 ++pStr;
1130 return n;
1134 sal_uInt32 SAL_CALL IMPL_RTL_STRNAME( toUInt32 )( const IMPL_RTL_STRCODE* pStr,
1135 sal_Int16 nRadix )
1136 SAL_THROW_EXTERN_C()
1138 assert(pStr);
1139 return IMPL_RTL_STRNAME( toUInt )<sal_uInt32>(pStr, nRadix);
1142 sal_uInt64 SAL_CALL IMPL_RTL_STRNAME( toUInt64 )( const IMPL_RTL_STRCODE* pStr,
1143 sal_Int16 nRadix )
1144 SAL_THROW_EXTERN_C()
1146 assert(pStr);
1147 return IMPL_RTL_STRNAME( toUInt )<sal_uInt64>(pStr, nRadix);
1150 /* ======================================================================= */
1151 /* Internal String-Class help functions */
1152 /* ======================================================================= */
1154 IMPL_RTL_STRINGDATA* IMPL_RTL_STRINGNAME( ImplAlloc )( sal_Int32 nLen )
1156 IMPL_RTL_STRINGDATA * pData
1157 = (sal::static_int_cast< sal_uInt32 >(nLen)
1158 <= ((SAL_MAX_UINT32 - sizeof (IMPL_RTL_STRINGDATA))
1159 / sizeof (IMPL_RTL_STRCODE)))
1160 ? static_cast<IMPL_RTL_STRINGDATA *>(rtl_allocateString(
1161 sizeof (IMPL_RTL_STRINGDATA) + nLen * sizeof (IMPL_RTL_STRCODE)))
1162 : nullptr;
1163 if (pData != nullptr) {
1164 pData->refCount = 1;
1165 pData->length = nLen;
1166 pData->buffer[nLen] = 0;
1168 return pData;
1171 /* ----------------------------------------------------------------------- */
1173 static IMPL_RTL_STRCODE* IMPL_RTL_STRINGNAME( ImplNewCopy )( IMPL_RTL_STRINGDATA** ppThis,
1174 IMPL_RTL_STRINGDATA* pStr,
1175 sal_Int32 nCount )
1177 assert(nCount >= 0);
1178 IMPL_RTL_STRCODE* pDest;
1179 const IMPL_RTL_STRCODE* pSrc;
1180 IMPL_RTL_STRINGDATA* pData = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1181 OSL_ASSERT(pData != nullptr);
1183 pDest = pData->buffer;
1184 pSrc = pStr->buffer;
1186 memcpy( pDest, pSrc, nCount * sizeof(IMPL_RTL_STRCODE));
1188 *ppThis = pData;
1190 RTL_LOG_STRING_NEW( pData );
1191 return pDest + nCount;
1194 /* ======================================================================= */
1195 /* String-Class functions */
1196 /* ======================================================================= */
1198 namespace {
1200 void IMPL_RTL_ACQUIRE(IMPL_RTL_STRINGDATA * pThis)
1202 if (!SAL_STRING_IS_STATIC (pThis))
1203 osl_atomic_increment( &((pThis)->refCount) );
1208 /* ----------------------------------------------------------------------- */
1210 void SAL_CALL IMPL_RTL_STRINGNAME( acquire )( IMPL_RTL_STRINGDATA* pThis )
1211 SAL_THROW_EXTERN_C()
1213 IMPL_RTL_ACQUIRE( pThis );
1216 /* ----------------------------------------------------------------------- */
1218 void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis )
1219 SAL_THROW_EXTERN_C()
1221 if (SAL_UNLIKELY(SAL_STRING_IS_STATIC (pThis)))
1222 return;
1224 /* OString doesn't have an 'intern' */
1225 #if IMPL_RTL_IS_USTRING
1226 if (SAL_STRING_IS_INTERN (pThis))
1228 internRelease (pThis);
1229 return;
1231 #endif
1233 if ( !osl_atomic_decrement( &(pThis->refCount) ) )
1235 RTL_LOG_STRING_DELETE( pThis );
1236 rtl_freeString( pThis );
1240 /* ----------------------------------------------------------------------- */
1242 void SAL_CALL IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA** ppThis )
1243 SAL_THROW_EXTERN_C()
1245 assert(ppThis);
1246 if ( *ppThis)
1247 IMPL_RTL_STRINGNAME( release )( *ppThis );
1249 *ppThis = const_cast<IMPL_RTL_STRINGDATA*>(&IMPL_RTL_EMPTYSTRING);
1252 /* ----------------------------------------------------------------------- */
1254 IMPL_RTL_STRINGDATA* SAL_CALL IMPL_RTL_STRINGNAME( alloc )( sal_Int32 nLen )
1255 SAL_THROW_EXTERN_C()
1257 assert(nLen >= 0);
1258 return IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1261 /* ----------------------------------------------------------------------- */
1263 void SAL_CALL IMPL_RTL_STRINGNAME( new_WithLength )( IMPL_RTL_STRINGDATA** ppThis, sal_Int32 nLen )
1264 SAL_THROW_EXTERN_C()
1266 assert(ppThis);
1267 assert(nLen >= 0);
1268 if ( nLen <= 0 )
1269 IMPL_RTL_STRINGNAME( new )( ppThis );
1270 else
1272 if ( *ppThis)
1273 IMPL_RTL_STRINGNAME( release )( *ppThis );
1275 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1276 OSL_ASSERT(*ppThis != nullptr);
1277 (*ppThis)->length = 0;
1279 IMPL_RTL_STRCODE* pTempStr = (*ppThis)->buffer;
1280 memset(pTempStr, 0, nLen*sizeof(IMPL_RTL_STRCODE));
1284 /* ----------------------------------------------------------------------- */
1286 void SAL_CALL IMPL_RTL_STRINGNAME( newFromString )( IMPL_RTL_STRINGDATA** ppThis,
1287 const IMPL_RTL_STRINGDATA* pStr )
1288 SAL_THROW_EXTERN_C()
1290 assert(ppThis);
1291 assert(pStr);
1292 IMPL_RTL_STRINGDATA* pOrg;
1294 if ( !pStr->length )
1296 IMPL_RTL_STRINGNAME( new )( ppThis );
1297 return;
1300 pOrg = *ppThis;
1301 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
1302 OSL_ASSERT(*ppThis != nullptr);
1303 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer, pStr->length );
1304 RTL_LOG_STRING_NEW( *ppThis );
1306 /* must be done last, if pStr == *ppThis */
1307 if ( pOrg )
1308 IMPL_RTL_STRINGNAME( release )( pOrg );
1311 /* ----------------------------------------------------------------------- */
1313 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr )( IMPL_RTL_STRINGDATA** ppThis,
1314 const IMPL_RTL_STRCODE* pCharStr )
1315 SAL_THROW_EXTERN_C()
1317 assert(ppThis);
1318 IMPL_RTL_STRINGDATA* pOrg;
1319 sal_Int32 nLen;
1321 if ( pCharStr )
1323 nLen = IMPL_RTL_STRNAME( getLength )( pCharStr );
1325 else
1326 nLen = 0;
1328 if ( !nLen )
1330 IMPL_RTL_STRINGNAME( new )( ppThis );
1331 return;
1334 pOrg = *ppThis;
1335 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1336 OSL_ASSERT(*ppThis != nullptr);
1337 rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
1338 RTL_LOG_STRING_NEW( *ppThis );
1340 /* must be done last, if pCharStr == *ppThis */
1341 if ( pOrg )
1342 IMPL_RTL_STRINGNAME( release )( pOrg );
1345 /* ----------------------------------------------------------------------- */
1347 void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA** ppThis,
1348 const IMPL_RTL_STRCODE* pCharStr,
1349 sal_Int32 nLen )
1350 SAL_THROW_EXTERN_C()
1352 assert(ppThis);
1353 assert(nLen >= 0);
1354 IMPL_RTL_STRINGDATA* pOrg;
1356 if ( !pCharStr || (nLen <= 0) )
1358 IMPL_RTL_STRINGNAME( new )( ppThis );
1359 return;
1362 pOrg = *ppThis;
1363 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1364 OSL_ASSERT(*ppThis != nullptr);
1365 rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
1367 RTL_LOG_STRING_NEW( *ppThis );
1369 /* must be done last, if pCharStr == *ppThis */
1370 if ( pOrg )
1371 IMPL_RTL_STRINGNAME( release )( pOrg );
1374 /* ----------------------------------------------------------------------- */
1376 void SAL_CALL IMPL_RTL_STRINGNAME( newFromSubString )( IMPL_RTL_STRINGDATA** ppThis,
1377 const IMPL_RTL_STRINGDATA* pFrom,
1378 sal_Int32 beginIndex,
1379 sal_Int32 count )
1380 SAL_THROW_EXTERN_C()
1382 assert(ppThis);
1383 if ( beginIndex == 0 && count == pFrom->length )
1385 IMPL_RTL_STRINGNAME( assign )( ppThis, const_cast< IMPL_RTL_STRINGDATA * >( pFrom ) );
1386 return;
1388 if ( count < 0 || beginIndex < 0 || beginIndex + count > pFrom->length )
1390 assert(false); // fail fast at least in debug builds
1391 IMPL_RTL_STRINGNAME( newFromLiteral )( ppThis, "!!br0ken!!", 10, 0 );
1392 return;
1395 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pFrom->buffer + beginIndex, count );
1398 /* ----------------------------------------------------------------------- */
1400 // Used when creating from string literals.
1401 void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral )( IMPL_RTL_STRINGDATA** ppThis,
1402 const sal_Char* pCharStr,
1403 sal_Int32 nLen,
1404 sal_Int32 allocExtra )
1405 SAL_THROW_EXTERN_C()
1407 assert(ppThis);
1408 assert(nLen >= 0);
1409 assert(allocExtra >= 0);
1410 if ( nLen + allocExtra == 0 )
1412 IMPL_RTL_STRINGNAME( new )( ppThis );
1413 return;
1416 if ( *ppThis )
1417 IMPL_RTL_STRINGNAME( release )( *ppThis );
1419 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen + allocExtra );
1420 assert( *ppThis != nullptr );
1422 (*ppThis)->length = nLen; // fix after possible allocExtra != 0
1423 (*ppThis)->buffer[nLen] = 0;
1424 IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer;
1425 sal_Int32 nCount;
1426 for( nCount = nLen; nCount > 0; --nCount )
1428 #if IMPL_RTL_IS_USTRING
1429 assert(static_cast<unsigned char>(*pCharStr) < 0x80); // ASCII range
1430 #endif
1431 SAL_WARN_IF( (static_cast<unsigned char>(*pCharStr)) == '\0', "rtl.string",
1432 "rtl_uString_newFromLiteral - Found embedded \\0 character" );
1434 *pBuffer = *pCharStr;
1435 pBuffer++;
1436 pCharStr++;
1439 RTL_LOG_STRING_NEW( *ppThis );
1442 /* ----------------------------------------------------------------------- */
1444 void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis,
1445 IMPL_RTL_STRINGDATA* pStr )
1446 SAL_THROW_EXTERN_C()
1448 assert(ppThis);
1449 /* must be done at first, if pStr == *ppThis */
1450 IMPL_RTL_ACQUIRE( pStr );
1452 if ( *ppThis )
1453 IMPL_RTL_STRINGNAME( release )( *ppThis );
1455 *ppThis = pStr;
1458 /* ----------------------------------------------------------------------- */
1460 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getLength )( const IMPL_RTL_STRINGDATA* pThis )
1461 SAL_THROW_EXTERN_C()
1463 assert(pThis);
1464 return pThis->length;
1467 /* ----------------------------------------------------------------------- */
1469 IMPL_RTL_STRCODE* SAL_CALL IMPL_RTL_STRINGNAME( getStr )( IMPL_RTL_STRINGDATA * pThis )
1470 SAL_THROW_EXTERN_C()
1472 assert(pThis);
1473 return pThis->buffer;
1476 /* ----------------------------------------------------------------------- */
1478 void SAL_CALL IMPL_RTL_STRINGNAME( newConcat )( IMPL_RTL_STRINGDATA** ppThis,
1479 IMPL_RTL_STRINGDATA* pLeft,
1480 IMPL_RTL_STRINGDATA* pRight )
1481 SAL_THROW_EXTERN_C()
1483 assert(ppThis);
1484 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1486 /* Test for 0-Pointer - if not, change newReplaceStrAt! */
1487 if ( !pRight || !pRight->length )
1489 *ppThis = pLeft;
1490 IMPL_RTL_ACQUIRE( pLeft );
1492 else if ( !pLeft || !pLeft->length )
1494 *ppThis = pRight;
1495 IMPL_RTL_ACQUIRE( pRight );
1497 else if (pLeft->length
1498 > std::numeric_limits<sal_Int32>::max() - pRight->length)
1500 *ppThis = nullptr;
1502 else
1504 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( pLeft->length + pRight->length );
1505 OSL_ASSERT(pTempStr != nullptr);
1506 *ppThis = pTempStr;
1507 if (*ppThis != nullptr) {
1508 rtl_str_ImplCopy( pTempStr->buffer, pLeft->buffer, pLeft->length );
1509 rtl_str_ImplCopy( pTempStr->buffer+pLeft->length, pRight->buffer, pRight->length );
1511 RTL_LOG_STRING_NEW( *ppThis );
1515 /* must be done last, if left or right == *ppThis */
1516 if ( pOrg )
1517 IMPL_RTL_STRINGNAME( release )( pOrg );
1520 /* ----------------------------------------------------------------------- */
1522 void SAL_CALL IMPL_RTL_STRINGNAME( ensureCapacity )( IMPL_RTL_STRINGDATA** ppThis,
1523 sal_Int32 size )
1524 SAL_THROW_EXTERN_C()
1526 assert(ppThis);
1527 IMPL_RTL_STRINGDATA* const pOrg = *ppThis;
1528 if ( pOrg->refCount == 1 && pOrg->length >= size )
1529 return;
1530 assert( pOrg->length <= size ); // do not truncate
1531 IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( size );
1532 rtl_str_ImplCopy( pTempStr->buffer, pOrg->buffer, pOrg->length );
1533 // right now the length is still the same as of the original
1534 pTempStr->length = pOrg->length;
1535 pTempStr->buffer[ pOrg->length ] = '\0';
1536 *ppThis = pTempStr;
1537 RTL_LOG_STRING_NEW( *ppThis );
1539 IMPL_RTL_STRINGNAME( release )( pOrg );
1542 /* ----------------------------------------------------------------------- */
1544 void SAL_CALL IMPL_RTL_STRINGNAME( newReplaceStrAt )( IMPL_RTL_STRINGDATA** ppThis,
1545 IMPL_RTL_STRINGDATA* pStr,
1546 sal_Int32 nIndex,
1547 sal_Int32 nCount,
1548 IMPL_RTL_STRINGDATA* pNewSubStr )
1549 SAL_THROW_EXTERN_C()
1551 assert(ppThis);
1552 assert(nIndex >= 0 && nIndex <= pStr->length);
1553 assert(nCount >= 0);
1554 assert(nCount <= pStr->length - nIndex);
1555 /* Append? */
1556 if ( nIndex >= pStr->length )
1558 /* newConcat test, if pNewSubStr is 0 */
1559 IMPL_RTL_STRINGNAME( newConcat )( ppThis, pStr, pNewSubStr );
1560 return;
1563 /* negative index? */
1564 if ( nIndex < 0 )
1566 nCount -= nIndex;
1567 nIndex = 0;
1570 /* not more than the String length could be deleted */
1571 if ( nCount >= pStr->length-nIndex )
1573 nCount = pStr->length-nIndex;
1575 /* Assign of NewSubStr? */
1576 if ( !nIndex && (nCount >= pStr->length) )
1578 if ( !pNewSubStr )
1579 IMPL_RTL_STRINGNAME( new )( ppThis );
1580 else
1581 IMPL_RTL_STRINGNAME( assign )( ppThis, pNewSubStr );
1582 return;
1586 /* Assign of Str? */
1587 if ( !nCount && (!pNewSubStr || !pNewSubStr->length) )
1589 IMPL_RTL_STRINGNAME( assign )( ppThis, pStr );
1590 return;
1593 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1594 IMPL_RTL_STRCODE* pBuffer;
1595 sal_Int32 nNewLen;
1597 /* Calculate length of the new string */
1598 nNewLen = pStr->length-nCount;
1599 if ( pNewSubStr )
1600 nNewLen += pNewSubStr->length;
1602 /* Alloc New Buffer */
1603 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
1604 OSL_ASSERT(*ppThis != nullptr);
1605 pBuffer = (*ppThis)->buffer;
1606 if ( nIndex )
1608 rtl_str_ImplCopy( pBuffer, pStr->buffer, nIndex );
1609 pBuffer += nIndex;
1611 if ( pNewSubStr && pNewSubStr->length )
1613 rtl_str_ImplCopy( pBuffer, pNewSubStr->buffer, pNewSubStr->length );
1614 pBuffer += pNewSubStr->length;
1616 rtl_str_ImplCopy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount );
1618 RTL_LOG_STRING_NEW( *ppThis );
1619 /* must be done last, if pStr or pNewSubStr == *ppThis */
1620 if ( pOrg )
1621 IMPL_RTL_STRINGNAME( release )( pOrg );
1624 /* ----------------------------------------------------------------------- */
1626 void SAL_CALL IMPL_RTL_STRINGNAME( newReplace )( IMPL_RTL_STRINGDATA** ppThis,
1627 IMPL_RTL_STRINGDATA* pStr,
1628 IMPL_RTL_STRCODE cOld,
1629 IMPL_RTL_STRCODE cNew )
1630 SAL_THROW_EXTERN_C()
1632 assert(ppThis);
1633 assert(pStr);
1634 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1635 bool bChanged = false;
1636 sal_Int32 nLen = pStr->length;
1637 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1639 while ( nLen > 0 )
1641 if ( *pCharStr == cOld )
1643 /* Copy String */
1644 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1646 /* replace/copy rest of the string */
1647 if ( pNewCharStr )
1649 *pNewCharStr = cNew;
1650 pNewCharStr++;
1651 pCharStr++;
1652 nLen--;
1654 while ( nLen > 0 )
1656 if ( *pCharStr == cOld )
1657 *pNewCharStr = cNew;
1658 else
1659 *pNewCharStr = *pCharStr;
1661 pNewCharStr++;
1662 pCharStr++;
1663 nLen--;
1667 bChanged = true;
1668 break;
1671 pCharStr++;
1672 nLen--;
1675 if ( !bChanged )
1677 *ppThis = pStr;
1678 IMPL_RTL_ACQUIRE( pStr );
1681 RTL_LOG_STRING_NEW( *ppThis );
1682 /* must be done last, if pStr == *ppThis */
1683 if ( pOrg )
1684 IMPL_RTL_STRINGNAME( release )( pOrg );
1687 /* ----------------------------------------------------------------------- */
1689 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiLowerCase )( IMPL_RTL_STRINGDATA** ppThis,
1690 IMPL_RTL_STRINGDATA* pStr )
1691 SAL_THROW_EXTERN_C()
1693 assert(ppThis);
1694 assert(pStr);
1695 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1696 bool bChanged = false;
1697 sal_Int32 nLen = pStr->length;
1698 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1700 while ( nLen > 0 )
1702 if ( rtl::isAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr)) )
1704 /* Copy String */
1705 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1707 /* replace/copy rest of the string */
1708 if ( pNewCharStr )
1710 *pNewCharStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr));
1711 pNewCharStr++;
1712 pCharStr++;
1713 nLen--;
1715 while ( nLen > 0 )
1717 *pNewCharStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr));
1719 pNewCharStr++;
1720 pCharStr++;
1721 nLen--;
1725 bChanged = true;
1726 break;
1729 pCharStr++;
1730 nLen--;
1733 if ( !bChanged )
1735 *ppThis = pStr;
1736 IMPL_RTL_ACQUIRE( pStr );
1739 RTL_LOG_STRING_NEW( *ppThis );
1740 /* must be done last, if pStr == *ppThis */
1741 if ( pOrg )
1742 IMPL_RTL_STRINGNAME( release )( pOrg );
1745 /* ----------------------------------------------------------------------- */
1747 void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiUpperCase )( IMPL_RTL_STRINGDATA** ppThis,
1748 IMPL_RTL_STRINGDATA* pStr )
1749 SAL_THROW_EXTERN_C()
1751 assert(ppThis);
1752 assert(pStr);
1753 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1754 bool bChanged = false;
1755 sal_Int32 nLen = pStr->length;
1756 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1758 while ( nLen > 0 )
1760 if ( rtl::isAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr)) )
1762 /* Copy String */
1763 IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
1765 /* replace/copy rest of the string */
1766 if ( pNewCharStr )
1768 *pNewCharStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr));
1769 pNewCharStr++;
1770 pCharStr++;
1771 nLen--;
1773 while ( nLen > 0 )
1775 *pNewCharStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr));
1777 pNewCharStr++;
1778 pCharStr++;
1779 nLen--;
1783 bChanged = true;
1784 break;
1787 pCharStr++;
1788 nLen--;
1791 if ( !bChanged )
1793 *ppThis = pStr;
1794 IMPL_RTL_ACQUIRE( pStr );
1797 RTL_LOG_STRING_NEW( *ppThis );
1798 /* must be done last, if pStr == *ppThis */
1799 if ( pOrg )
1800 IMPL_RTL_STRINGNAME( release )( pOrg );
1803 /* ----------------------------------------------------------------------- */
1805 void SAL_CALL IMPL_RTL_STRINGNAME( newTrim )( IMPL_RTL_STRINGDATA** ppThis,
1806 IMPL_RTL_STRINGDATA* pStr )
1807 SAL_THROW_EXTERN_C()
1809 assert(ppThis);
1810 assert(pStr);
1811 IMPL_RTL_STRINGDATA* pOrg = *ppThis;
1812 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1813 sal_Int32 nPreSpaces = 0;
1814 sal_Int32 nPostSpaces = 0;
1815 sal_Int32 nLen = pStr->length;
1816 sal_Int32 nIndex = nLen-1;
1818 while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nPreSpaces)) ) )
1819 nPreSpaces++;
1821 while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nIndex)) ) )
1823 nPostSpaces++;
1824 nIndex--;
1827 if ( !nPreSpaces && !nPostSpaces )
1829 *ppThis = pStr;
1830 IMPL_RTL_ACQUIRE( pStr );
1832 else
1834 nLen -= nPostSpaces+nPreSpaces;
1835 *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
1836 assert(*ppThis);
1837 rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer+nPreSpaces, nLen );
1840 RTL_LOG_STRING_NEW( *ppThis );
1841 /* must be done last, if pStr == *ppThis */
1842 if ( pOrg )
1843 IMPL_RTL_STRINGNAME( release )( pOrg );
1846 /* ----------------------------------------------------------------------- */
1848 sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getToken )( IMPL_RTL_STRINGDATA** ppThis,
1849 IMPL_RTL_STRINGDATA* pStr,
1850 sal_Int32 nToken,
1851 IMPL_RTL_STRCODE cTok,
1852 sal_Int32 nIndex )
1853 SAL_THROW_EXTERN_C()
1855 assert(ppThis);
1856 assert(pStr);
1857 const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
1858 const IMPL_RTL_STRCODE* pCharStrStart;
1859 const IMPL_RTL_STRCODE* pOrgCharStr;
1860 sal_Int32 nLen = pStr->length-nIndex;
1861 sal_Int32 nTokCount = 0;
1863 // Set ppThis to an empty string and return -1 if either nToken or nIndex is
1864 // negative:
1865 if (nIndex < 0)
1866 nToken = -1;
1868 pCharStr += nIndex;
1869 pOrgCharStr = pCharStr;
1870 pCharStrStart = pCharStr;
1871 while ( nLen > 0 )
1873 if ( *pCharStr == cTok )
1875 nTokCount++;
1877 if ( nTokCount == nToken )
1878 pCharStrStart = pCharStr+1;
1879 else
1881 if ( nTokCount > nToken )
1882 break;
1886 pCharStr++;
1887 nLen--;
1890 if ( (nToken < 0) || (nTokCount < nToken) || (pCharStr == pCharStrStart) )
1892 IMPL_RTL_STRINGNAME( new )( ppThis );
1893 if( (nToken < 0) || (nTokCount < nToken ) )
1894 return -1;
1895 else if( nLen > 0 )
1896 return nIndex+(pCharStr-pOrgCharStr)+1;
1897 else return -1;
1899 else
1901 IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pCharStrStart, pCharStr-pCharStrStart );
1902 if ( nLen )
1903 return nIndex+(pCharStr-pOrgCharStr)+1;
1904 else
1905 return -1;
1909 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */